<?php

namespace App\Http\Controllers;

use App\Models\Property;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PropertyController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        // Get properties with unit and customer counts for the current company
        $companyId = $this->user()->CompanyID;
        $search = $request->input('search');
        
        $properties = Property::select('property.PropID', 'property.PropName', 'property.City', 'property.PropertyType', 'property.PropDesc', 'property.WMeterNo', 'property.EMeterNo')
            ->where('property.CompanyID', $companyId)
            ->when($search, function($query) use ($search) {
                $query->where(function($q) use ($search) {
                    $q->where('property.PropName', 'like', "%{$search}%")
                      ->orWhere('property.City', 'like', "%{$search}%")
                      ->orWhere('property.PropertyType', 'like', "%{$search}%")
                      ->orWhere('property.WMeterNo', 'like', "%{$search}%")
                      ->orWhere('property.EMeterNo', 'like', "%{$search}%");
                });
            })
            ->withCount(['units as units_count' => function($query) use ($companyId) {
                $query->where('prounits.CompanyID', $companyId);
            }])
            ->orderBy('property.PropID', 'desc')
            ->paginate(10)
            ->withQueryString();
            
        return view('properties.index', compact('properties', 'search'));
    }
    
    /**
     * Display all units for a property
     */
    public function units(Property $property)
    {
        $this->authorize('view', $property);
        
        $units = $property->units()
            ->with(['block', 'customers'])
            ->orderBy('BlockNo')
            ->orderBy('FloorNo')
            ->orderBy('DoorNo')
            ->paginate(20);
            
        return view('properties.units.index', compact('property', 'units'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        return view('properties.create');
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'PropName' => 'required|string|max:255',
            'City' => 'required|string|max:255',
            'PropDesc' => 'nullable|string',
            'PropertyType' => 'required|string|max:50',
            'WMeterNo' => 'nullable|string|max:50',
            'EMeterNo' => 'nullable|string|max:50',
            'NoMonthPerYear' => 'sometimes|integer|min:1|max:12',
        ]);

        try {
            DB::beginTransaction();
            
            // Add default values for required fields that aren't in the form
            $propertyData = array_merge($validated, [
                'NoMonthPerYear' => $validated['NoMonthPerYear'] ?? 12, // Use provided value or default to 12
                'BillPeriodicity' => 'Monthly', // Default billing periodicity
                'CompanyID' => $this->user()->CompanyID, // Use the logged-in user's company ID
            ]);
            
            $property = Property::create($propertyData);
            
            DB::commit();
            
            return redirect()->route('properties.index')
                ->with('success', 'Property created successfully.');
                
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withInput()->with('error', 'Error creating property: ' . $e->getMessage());
        }
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        // Get the property with company validation
        $property = Property::where('CompanyID', $companyId)
            ->findOrFail($id);

        // Get paginated units for this property with their customer count and active assignments
        $units = $property->units()
            ->withCount(['customers', 'activeAssignments'])
            ->with(['activeCustomer' => function($query) {
                $query->select('CustomerID', 'CustomerName', 'TelNo');
            }])
            ->paginate(10);

        // Calculate stats for the property using optimized queries
        $stats = [
            'total_units' => $property->units_count ?? $property->units()->count(),
            'occupied_units' => $property->units()->has('activeAssignments')->count(),
            'vacant_units' => $property->units()->whereDoesntHave('activeAssignments')->count(),
            'total_customers' => $property->active_customers_count ?? 0,
            'total_services' => $property->services_count ?? 0
        ];

        // Get services for this property with sorting and company validation
        $sortField = request('sort', 'ServiceName');
        $sortDirection = in_array(strtolower(request('direction', 'asc')), ['asc', 'desc']) ? 
            request('direction', 'asc') : 'asc';
            
        $services = \App\Models\PropService::where('PropID', $property->PropID)
            ->when(in_array($sortField, ['ServiceName', 'Description', 'Price', 'NoMonthPerYear']), 
                function($query) use ($sortField, $sortDirection) {
                    return $query->orderBy($sortField, $sortDirection);
                },
                function($query) {
                    return $query->orderBy('ServiceName', 'asc');
                }
            )
            ->get();

        // Get counts for the tabs
        $occupied_units_count = $property->units()->has('activeAssignments')->count();
        $vacant_units_count = $property->units()->whereDoesntHave('activeAssignments')->count();

        return view('properties.show', [
            'property' => $property->load('units'),
            'units' => $units,
            'stats' => $stats,
            'services' => $services,
            'services_count' => $services->count(),
            'occupied_units_count' => $occupied_units_count,
            'vacant_units_count' => $vacant_units_count
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        $property = Property::where('CompanyID', $companyId)
            ->findOrFail($id);
            
        return view('properties.edit', compact('property'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        // Find the property with company validation
        $property = Property::where('CompanyID', $companyId)
            ->findOrFail($id);

        $validated = $request->validate([
            'PropName' => 'required|string|max:255',
            'City' => 'required|string|max:255',
            'PropDesc' => 'required|string',
            'PropertyType' => 'required|string|max:50',
            'NoMonthPerYear' => 'required|integer|min:1|max:12',
            'WMeterNo' => 'nullable|string|max:50',
            'EMeterNo' => 'nullable|string|max:50',
        ]);

        try {
            DB::beginTransaction();
            
            $property->update($validated);
            
            DB::commit();
            
            return redirect()->route('properties.show', $property->PropID)
                ->with('success', 'Property updated successfully.');
                
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withInput()->with('error', 'Error updating property: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id)
    {
        $companyId = $this->user()->CompanyID;
        
        if (!$companyId) {
            return redirect()->back()->with('error', 'No company associated with this account.');
        }

        try {
            // Find the property with company validation
            $property = Property::where('CompanyID', $companyId)
                ->findOrFail($id);
            
            // Check if property has any units
            if ($property->units()->exists()) {
                return redirect()->back()
                    ->with('error', 'Cannot delete property with existing units. Please delete or reassign the units first.');
            }
            
            // Check if property has any services
            if ($property->services()->exists()) {
                return redirect()->back()
                    ->with('error', 'Cannot delete property with existing services. Please delete the services first.');
            }
            
            DB::beginTransaction();
            
            // Delete related data first
            $property->delete();
            
            DB::commit();
            
            return redirect()->route('properties.index')
                ->with('success', 'Property deleted successfully.');
                
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Error deleting property: ' . $e->getMessage());
        }
    }
}
