<?php

namespace App\Http\Controllers\Web;

use App\Http\Controllers\Controller;
use App\Http\Requests\StorePropertyRequest;
use App\Http\Requests\UpdatePropertyRequest;
use App\Services\PropertyService;
use App\Traits\DeleteModelTrait;
use App\Traits\FlashMessageTrait;
use App\Models\Property;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Illuminate\Support\Facades\Log;

class AdminPropertyController extends Controller
{
    use DeleteModelTrait, FlashMessageTrait;
    
    protected $propertyService;

    public function __construct(PropertyService $propertyService)
    {
        $this->propertyService = $propertyService;
    }

    /**
     * Display a listing of properties
     */
    public function index(Request $request)
    {
        try {
            $perPage = 5;
            $properties = $this->propertyService->getAllProperties($perPage);
            
            // Calculate serial numbers based on pagination
            $properties->getCollection()->transform(function ($property, $index) use ($properties) {
                $property->sn = ($properties->currentPage() - 1) * $properties->perPage() + $index + 1;
                return $property;
            });

            return Inertia::render('Admin/Properties/Property', [
                'properties' => $properties->items(),
                'pagination' => [
                    'current_page' => $properties->currentPage(),
                    'last_page' => $properties->lastPage(),
                    'per_page' => $properties->perPage(),
                    'total' => $properties->total(),
                    'from' => $properties->firstItem(),
                    'to' => $properties->lastItem(),
                    'links' => $properties->linkCollection()->toArray(),
                ],
                'filters' => $request->only(['search', 'status', 'type'])
            ]);
        } catch (\Exception $e) {
            return $this->error('Failed to load properties: ' . $e->getMessage());
        }
    }

    /**
     * Show the form for creating a new property
     */
    public function create()
    {
        try {
            return Inertia::render('Admin/Properties/create/Property');
        } catch (\Exception $e) {
            return $this->error('Failed to load create form: ' . $e->getMessage());
        }
    }

    /**
     * Store a newly created property
     */
    public function store(StorePropertyRequest $request)
    {
        try {
            $propertyData = $request->validated();
            
            // Log the received data for debugging
            Log::info('Property creation data received', [
                'property_type' => $propertyData['property_type'] ?? null,
                'has_hostel_data' => isset($propertyData['hostel']),
                'hostel_data' => $propertyData['hostel'] ?? null,
            ]);
            
            $property = $this->propertyService->createPropertySimple($propertyData);
            
            return $this->successTo('admin.properties.index', 'Property created successfully');
        } catch (\Exception $e) {
            Log::error('Failed to create property', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            return $this->error('Failed to create property: ' . $e->getMessage());
        }
    }

    /**
     * Show the form for editing the specified property
     */
    public function edit($id)
    {
        try {
            $property = $this->propertyService->getPropertyById($id);
            
            if (!$property) {
                return response()->json(['error' => 'Property not found'], 404);
            }

            // Format property data for frontend
            $propertyData = [
                'id' => $property->id,
                'title' => $property->title,
                'description' => $property->description,
                'address' => $property->address,
                'latitude' => $property->latitude,
                'longitude' => $property->longitude,
                'property_type' => $property->property_type,
                'bedrooms' => $property->bedrooms,
                'bathrooms' => $property->bathrooms,
                'size_sqm' => $property->size_sqm,
                'monthly_rent' => $property->monthly_rent,
                'deposit_amount' => $property->deposit_amount,
                'is_furnished' => $property->is_furnished,
                'status' => $property->status,
                'landlord_id' => $property->landlord_id,
                'images' => $property->images->map(function($img) {
                    return is_string($img->image_url) && strpos($img->image_url, '/storage/') === 0
                        ? str_replace('/storage/', '', $img->image_url)
                        : $img->image_url;
                })->toArray(),
                'hostel' => $property->hostel ? [
                    'university_nearby' => $property->hostel->university_nearby ?? '',
                    'distance_to_university' => $property->hostel->distance_to_university ?? 0,
                    'room_sharing' => $property->hostel->room_sharing ?? 1,
                    'gender_restriction' => $property->hostel->gender_restriction ?? 3,
                    'meal_plan_available' => $property->hostel->meal_plan_available ?? false,
                    'study_room_available' => $property->hostel->study_room_available ?? false,
                    'curfew_time' => $property->hostel->curfew_time 
                        ? (is_string($property->hostel->curfew_time) 
                            ? $property->hostel->curfew_time 
                            : (method_exists($property->hostel->curfew_time, 'format') 
                                ? $property->hostel->curfew_time->format('H:i') 
                                : $property->hostel->curfew_time))
                        : '',
                ] : null,
            ];

            return response()->json($propertyData);
        } catch (\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 500);
        }
    }

    /**
     * Update the specified property
     */
    public function update(UpdatePropertyRequest $request, $id)
    {
        try {
            $propertyData = $request->validated();
            
            // Log the received data for debugging
            Log::info('Property update data received', [
                'property_id' => $id,
                'property_type' => $propertyData['property_type'] ?? null,
                'has_hostel_data' => isset($propertyData['hostel']),
                'hostel_data' => $propertyData['hostel'] ?? null,
            ]);
            
            $property = $this->propertyService->updatePropertySimple($id, $propertyData);
            
            return $this->successTo('admin.properties.index', 'Property updated successfully');
        } catch (\Exception $e) {
            Log::error('Failed to update property', [
                'property_id' => $id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            return $this->error('Failed to update property: ' . $e->getMessage());
        }
    }

    /**
     * Get landlords for dropdown (JSON response)
     */
    public function getLandlords()
    {
        try {
            $landlords = \App\Models\User::where('role_type', 1) // 1 = landlord
                ->where('status', 1) // 1 = active
                ->select('id', 'name', 'email')
                ->orderBy('name')
                ->get();

            $formattedLandlords = $landlords->map(function ($user) {
                return [
                    'value' => $user->id,
                    'label' => $user->name . ' (' . $user->email . ')'
                ];
            })->values(); // Use values() to ensure proper JSON array format

            return response()->json([
                'users' => $formattedLandlords,
                'success' => true
            ], 200);
        } catch (\Exception $e) {
            Log::error('Failed to fetch landlords: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString()
            ]);
            return response()->json([
                'error' => 'Failed to fetch landlords: ' . $e->getMessage(),
                'users' => [],
                'success' => false
            ], 500);
        }
    }

    /**
     * Remove the specified property
     */
    public function destroy($id)
    {
        try {
            $property = $this->propertyService->getPropertyById($id);

            if (!$property) {
                return $this->error('Property not found');
            }

            // Use the trait for consistent deletion handling
            return $this->deleteModel($id, new Property());
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * Verify a property from the admin dashboard
     */
    public function verifyProperty(Request $request, $id)
    {
        try {
            $validated = $request->validate([
                'documents_verified' => 'nullable|array',
                'notes' => 'nullable|string|max:1000',
            ]);

            $verification = $this->propertyService->verifyProperty($id, $validated, auth()->user());

            if (!$verification) {
                return $this->error('Property not found');
            }

            return $this->successTo('admin.properties.index', 'Property verified successfully');
        } catch (\Exception $e) {
            return $this->error('Failed to verify property: ' . $e->getMessage());
        }
    }

    /**
     * Update property status from the admin dashboard
     */
    public function updateStatus(Request $request, $id)
    {
        try {
            $validated = $request->validate([
                'status' => 'required|integer|in:1,2,3,4',
            ]);

            $property = $this->propertyService->updatePropertyStatus($id, (int) $validated['status'], auth()->user());

            if (!$property) {
                return $this->error('Property not found');
            }

            return $this->successTo('admin.properties.index', 'Property status updated successfully');
        } catch (\Exception $e) {
            return $this->error('Failed to update property status: ' . $e->getMessage());
        }
    }

    /**
     * Display property verifications
     */
    public function verifications(Request $request)
    {
        try {
            $perPage = $request->input('per_page', 15);
            $filters = $request->only(['verifier_id', 'date_from', 'date_to', 'recent', 'limit']);
            
            $result = $this->propertyService->getAllVerifications($filters, $perPage);
            
            // Format data for display
            $startSN = (($result['pagination']['current_page'] - 1) * $result['pagination']['per_page']) + 1;
            
            $formattedVerifications = array_map(function ($verification, $index) use ($startSN) {
                return [
                    'id' => $verification['id'] ?? $verification->id ?? null,
                    'sn' => $startSN + $index,
                    'property_title' => $verification['property']['title'] ?? $verification->property->title ?? 'N/A',
                    'property_address' => $verification['property']['address'] ?? $verification->property->address ?? 'N/A',
                    'verifier_name' => $verification['verified_by']['name'] ?? $verification->verifier->name ?? 'N/A',
                    'verification_date' => isset($verification['verification_date']) 
                        ? date('Y-m-d', strtotime($verification['verification_date'])) 
                        : (isset($verification->verification_date) ? $verification->verification_date->format('Y-m-d') : 'N/A'),
                    'documents_verified' => $verification['documents_verified'] ?? $verification->documents_verified ?? [],
                    'notes' => $verification['notes'] ?? $verification->notes ?? 'N/A',
                ];
            }, $result['data'], array_keys($result['data']));

            return Inertia::render('Admin/Properties/Verifications', [
                'verifications' => $formattedVerifications,
                'pagination' => $result['pagination'],
                'filters' => $filters,
            ]);
        } catch (\Exception $e) {
            return $this->error('Failed to load verifications: ' . $e->getMessage());
        }
    }

    /**
     * Get verification statistics
     */
    public function verificationStatistics()
    {
        try {
            $stats = $this->propertyService->getVerificationStatistics();
            
            return Inertia::render('Admin/Properties/VerificationStatistics', [
                'statistics' => $stats,
            ]);
        } catch (\Exception $e) {
            return $this->error('Failed to load statistics: ' . $e->getMessage());
        }
    }
}
