<?php

class FacilityController extends Controller
{
    public function index(Request $request): void
    {
        $db = $this->db();

        $totalActive = (int) $db->fetchColumn("SELECT COUNT(*) FROM facilities WHERE status = 'active' AND is_active = 1");
        $totalMaintenance = (int) $db->fetchColumn("SELECT COUNT(*) FROM facilities WHERE status = 'under_maintenance'");
        $totalClosed = (int) $db->fetchColumn("SELECT COUNT(*) FROM facilities WHERE status = 'closed'");
        $totalAll = (int) $db->fetchColumn("SELECT COUNT(*) FROM facilities WHERE is_active = 1");

        $facilityTypes = $db->fetchAll("SELECT id, name_en, name_ar FROM facility_types WHERE is_active = 1 ORDER BY name_en");

        $this->view('index', [
            'title'            => lang('facilities.title'),
            'breadcrumbs'      => [['label' => lang('facilities.title')]],
            'totalActive'      => $totalActive,
            'totalMaintenance' => $totalMaintenance,
            'totalClosed'      => $totalClosed,
            'totalAll'         => $totalAll,
            'facilityTypes'    => $facilityTypes,
        ]);
    }

    public function show(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $db = $this->db();

        $facility = $db->fetchOne(
            "SELECT f.*, ft.name_en AS type_name_en, ft.name_ar AS type_name_ar
             FROM facilities f
             LEFT JOIN facility_types ft ON f.facility_type_id = ft.id
             WHERE f.id = ?",
            [$id]
        );

        if (!$facility) {
            $this->abort(404, 'Facility not found');
        }

        $amenities = $db->fetchAll("SELECT * FROM facility_amenities WHERE facility_id = ? ORDER BY amenity_name_en", [$id]);
        $timeSlots = $db->fetchAll("SELECT * FROM facility_time_slots WHERE facility_id = ? AND is_active = 1 ORDER BY day_of_week, start_time", [$id]);
        $recentBookings = $db->fetchAll(
            "SELECT fb.*, m.full_name_en AS member_name, m.membership_number
             FROM facility_bookings fb
             LEFT JOIN members m ON fb.member_id = m.id
             WHERE fb.facility_id = ? AND fb.booking_date >= CURDATE()
             ORDER BY fb.booking_date, fb.start_time LIMIT 20",
            [$id]
        );
        $maintenanceRecords = $db->fetchAll(
            "SELECT * FROM facility_maintenance WHERE facility_id = ? ORDER BY start_date DESC LIMIT 10",
            [$id]
        );

        $this->view('show', [
            'title'       => $facility['name_en'],
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => $facility['name_en']],
            ],
            'facility'           => $facility,
            'amenities'          => $amenities,
            'timeSlots'          => $timeSlots,
            'recentBookings'     => $recentBookings,
            'maintenanceRecords' => $maintenanceRecords,
        ]);
    }

    public function create(Request $request): void
    {
        $db = $this->db();
        $facilityTypes = $db->fetchAll("SELECT id, name_en, name_ar FROM facility_types WHERE is_active = 1 ORDER BY name_en");

        $this->view('create', [
            'title'       => lang('facilities.create'),
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => lang('facilities.create')],
            ],
            'facilityTypes' => $facilityTypes,
        ]);
    }

    public function store(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $validator = new Validator($request->all(), [
            'facility_code'    => 'required|string|max:20',
            'facility_type_id' => 'required|integer',
            'name_en'          => 'required|string|max:200',
            'name_ar'          => 'required|string|max:200',
            'location'         => 'nullable|string|max:300',
            'capacity'         => 'nullable|integer',
            'area_sqm'         => 'nullable|decimal',
            'is_indoor'        => 'nullable|boolean',
            'is_bookable'      => 'nullable|boolean',
            'booking_fee_per_hour' => 'nullable|decimal',
            'booking_fee_members'  => 'nullable|decimal',
            'booking_fee_guests'   => 'nullable|decimal',
            'min_booking_minutes'  => 'nullable|integer',
            'max_booking_minutes'  => 'nullable|integer',
            'advance_booking_days' => 'nullable|integer',
            'operating_hours_start'=> 'nullable|string',
            'operating_hours_end'  => 'nullable|string',
            'status'               => 'nullable|in:active,under_maintenance,closed,reserved',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $data['is_indoor']   = isset($data['is_indoor']) ? 1 : 0;
        $data['is_bookable'] = isset($data['is_bookable']) ? 1 : 0;
        $data['is_active']   = 1;
        $data['created_at']  = date('Y-m-d H:i:s');

        $db = $this->db();

        $existingCode = $db->fetchColumn("SELECT COUNT(*) FROM facilities WHERE facility_code = ?", [$data['facility_code']]);
        if ($existingCode > 0) {
            $this->json(['success' => false, 'errors' => ['facility_code' => ['Facility code already exists']]], 422);
            return;
        }

        $id = $db->insert('facilities', $data);
        $this->audit('create', 'facilities', $id, "Created facility: {$data['name_en']}");

        $this->json(['success' => true, 'message' => lang('facilities.created'), 'redirect' => "/facilities/{$id}"]);
    }

    public function edit(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $db = $this->db();

        $facility = $db->fetchOne("SELECT * FROM facilities WHERE id = ?", [$id]);
        if (!$facility) {
            $this->abort(404, 'Facility not found');
        }

        $facilityTypes = $db->fetchAll("SELECT id, name_en, name_ar FROM facility_types WHERE is_active = 1 ORDER BY name_en");

        $this->view('edit', [
            'title'       => lang('facilities.edit') . ': ' . $facility['name_en'],
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => $facility['name_en'], 'url' => "/facilities/{$id}"],
                ['label' => lang('common.edit')],
            ],
            'facility'      => $facility,
            'facilityTypes' => $facilityTypes,
        ]);
    }

    public function update(Request $request): void
    {
        $id = (int) $request->routeParam('id');

        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $db = $this->db();
        $old = $db->fetchOne("SELECT * FROM facilities WHERE id = ?", [$id]);
        if (!$old) {
            $this->json(['success' => false, 'message' => 'Facility not found'], 404);
            return;
        }

        $validator = new Validator($request->all(), [
            'facility_type_id'     => 'required|integer',
            'name_en'              => 'required|string|max:200',
            'name_ar'              => 'required|string|max:200',
            'location'             => 'nullable|string|max:300',
            'capacity'             => 'nullable|integer',
            'area_sqm'             => 'nullable|decimal',
            'is_indoor'            => 'nullable|boolean',
            'is_bookable'          => 'nullable|boolean',
            'booking_fee_per_hour' => 'nullable|decimal',
            'booking_fee_members'  => 'nullable|decimal',
            'booking_fee_guests'   => 'nullable|decimal',
            'min_booking_minutes'  => 'nullable|integer',
            'max_booking_minutes'  => 'nullable|integer',
            'advance_booking_days' => 'nullable|integer',
            'operating_hours_start'=> 'nullable|string',
            'operating_hours_end'  => 'nullable|string',
            'status'               => 'nullable|in:active,under_maintenance,closed,reserved',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $data['is_indoor']   = isset($data['is_indoor']) ? 1 : 0;
        $data['is_bookable'] = isset($data['is_bookable']) ? 1 : 0;
        $data['updated_at']  = date('Y-m-d H:i:s');

        $db->update('facilities', $data, 'id = ?', [$id]);
        $this->audit('update', 'facilities', $id, "Updated facility: {$data['name_en']}", $old, $data);

        $this->json(['success' => true, 'message' => lang('facilities.updated'), 'redirect' => "/facilities/{$id}"]);
    }

    // ─── Facility Types ───

    public function types(Request $request): void
    {
        $this->view('types/index', [
            'title'       => lang('facilities.types'),
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => lang('facilities.types')],
            ],
        ]);
    }

    public function createType(Request $request): void
    {
        $this->view('types/form', [
            'title'       => lang('facilities.create_type'),
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => lang('facilities.types'), 'url' => '/facilities/types'],
                ['label' => lang('facilities.create_type')],
            ],
            'type' => null,
        ]);
    }

    public function storeType(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $validator = new Validator($request->all(), [
            'type_code'  => 'required|string|max:20',
            'name_en'    => 'required|string|max:200',
            'name_ar'    => 'required|string|max:200',
            'icon'       => 'nullable|string|max:100',
            'is_bookable'=> 'nullable|boolean',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $data['is_bookable'] = isset($data['is_bookable']) ? 1 : 0;
        $data['is_active']   = 1;
        $data['created_at']  = date('Y-m-d H:i:s');

        $db = $this->db();
        $exists = $db->fetchColumn("SELECT COUNT(*) FROM facility_types WHERE type_code = ?", [$data['type_code']]);
        if ($exists > 0) {
            $this->json(['success' => false, 'errors' => ['type_code' => ['Type code already exists']]], 422);
            return;
        }

        $id = $db->insert('facility_types', $data);
        $this->audit('create', 'facility_types', $id, "Created facility type: {$data['name_en']}");

        $this->json(['success' => true, 'message' => lang('facilities.type_created'), 'redirect' => '/facilities/types']);
    }

    public function editType(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $db = $this->db();
        $type = $db->fetchOne("SELECT * FROM facility_types WHERE id = ?", [$id]);
        if (!$type) {
            $this->abort(404);
        }

        $this->view('types/form', [
            'title'       => lang('facilities.edit_type') . ': ' . $type['name_en'],
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => lang('facilities.types'), 'url' => '/facilities/types'],
                ['label' => lang('common.edit')],
            ],
            'type' => $type,
        ]);
    }

    public function updateType(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $db = $this->db();
        $old = $db->fetchOne("SELECT * FROM facility_types WHERE id = ?", [$id]);
        if (!$old) {
            $this->json(['success' => false, 'message' => 'Type not found'], 404);
            return;
        }

        $validator = new Validator($request->all(), [
            'name_en'     => 'required|string|max:200',
            'name_ar'     => 'required|string|max:200',
            'icon'        => 'nullable|string|max:100',
            'is_bookable' => 'nullable|boolean',
            'is_active'   => 'nullable|boolean',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $data['is_bookable'] = isset($data['is_bookable']) ? 1 : 0;
        $data['is_active']   = isset($data['is_active']) ? 1 : 0;

        $db->update('facility_types', $data, 'id = ?', [$id]);
        $this->audit('update', 'facility_types', $id, "Updated facility type: {$data['name_en']}", $old, $data);

        $this->json(['success' => true, 'message' => lang('facilities.type_updated'), 'redirect' => '/facilities/types']);
    }

    // ─── Maintenance ───

    public function maintenance(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $db = $this->db();
        $facility = $db->fetchOne("SELECT id, name_en, name_ar, facility_code FROM facilities WHERE id = ?", [$id]);
        if (!$facility) {
            $this->abort(404);
        }

        $this->view('maintenance/index', [
            'title'       => lang('facilities.maintenance') . ': ' . $facility['name_en'],
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => $facility['name_en'], 'url' => "/facilities/{$id}"],
                ['label' => lang('facilities.maintenance')],
            ],
            'facility' => $facility,
        ]);
    }

    public function storeMaintenance(Request $request): void
    {
        $facilityId = (int) $request->routeParam('id');

        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $validator = new Validator($request->all(), [
            'maintenance_type' => 'required|in:scheduled,emergency,inspection,upgrade,repair',
            'title'            => 'required|string|max:300',
            'description'      => 'nullable|string',
            'start_date'       => 'required|date',
            'end_date'         => 'nullable|date',
            'estimated_cost'   => 'nullable|decimal',
            'priority'         => 'required|in:low,medium,high,critical',
            'assigned_to'      => 'nullable|string|max:200',
            'vendor'           => 'nullable|string|max:200',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $data['facility_id'] = $facilityId;
        $data['status']      = 'planned';
        $data['created_at']  = date('Y-m-d H:i:s');
        $data['created_by']  = Auth::id();

        $db = $this->db();
        $id = $db->insert('facility_maintenance', $data);
        $this->audit('create', 'facility_maintenance', $id, "Created maintenance record for facility #{$facilityId}");

        $this->json(['success' => true, 'message' => lang('facilities.maintenance_created')]);
    }

    // ─── Swimming Pools ───

    public function pools(Request $request): void
    {
        $db = $this->db();
        $pools = $db->fetchAll(
            "SELECT sp.*, f.name_en AS facility_name_en, f.name_ar AS facility_name_ar, f.facility_code
             FROM swimming_pools sp
             JOIN facilities f ON sp.facility_id = f.id
             WHERE sp.is_active = 1
             ORDER BY f.name_en"
        );

        $this->view('pools/index', [
            'title'       => lang('facilities.pools'),
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => lang('facilities.pools')],
            ],
            'pools' => $pools,
        ]);
    }

    public function storeReading(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $validator = new Validator($request->all(), [
            'pool_id'           => 'required|integer',
            'reading_date'      => 'required|date',
            'reading_time'      => 'required|string',
            'ph_level'          => 'nullable|decimal',
            'chlorine_level'    => 'nullable|decimal',
            'temperature_celsius'=> 'nullable|decimal',
            'turbidity'         => 'nullable|decimal',
            'action_taken'      => 'nullable|string|max:500',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();

        $isCompliant = 1;
        $reasons = [];
        if ($data['ph_level'] !== null && ($data['ph_level'] < 7.2 || $data['ph_level'] > 7.8)) {
            $isCompliant = 0;
            $reasons[] = 'pH level out of range (7.2-7.8)';
        }
        if ($data['chlorine_level'] !== null && ($data['chlorine_level'] < 1.0 || $data['chlorine_level'] > 3.0)) {
            $isCompliant = 0;
            $reasons[] = 'Chlorine level out of range (1.0-3.0)';
        }
        if ($data['temperature_celsius'] !== null && ($data['temperature_celsius'] < 24 || $data['temperature_celsius'] > 30)) {
            $isCompliant = 0;
            $reasons[] = 'Temperature out of range (24-30°C)';
        }

        $data['is_compliant']         = $isCompliant;
        $data['non_compliance_reason'] = $isCompliant ? null : implode('; ', $reasons);
        $data['recorded_by']          = Auth::id();
        $data['created_at']           = date('Y-m-d H:i:s');

        $db = $this->db();
        $id = $db->insert('swimming_pool_readings', $data);
        $this->audit('create', 'swimming_pool_readings', $id, "Recorded pool reading for pool #{$data['pool_id']}");

        $this->json(['success' => true, 'message' => lang('facilities.reading_recorded')]);
    }

    // ─── Parking ───

    public function parking(Request $request): void
    {
        $db = $this->db();
        $zones = $db->fetchAll("SELECT * FROM parking_zones WHERE is_active = 1 ORDER BY zone_code");
        $membershipTypes = $db->fetchAll("SELECT id, name_en, name_ar FROM membership_types WHERE is_active = 1 ORDER BY sort_order");

        $this->view('parking/index', [
            'title'       => lang('facilities.parking'),
            'breadcrumbs' => [
                ['label' => lang('facilities.title'), 'url' => '/facilities'],
                ['label' => lang('facilities.parking')],
            ],
            'zones'           => $zones,
            'membershipTypes' => $membershipTypes,
        ]);
    }

    public function storePermit(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid security token'], 403);
            return;
        }

        $validator = new Validator($request->all(), [
            'member_id'      => 'required|integer',
            'zone_id'        => 'nullable|integer',
            'vehicle_plate'  => 'required|string|max:30',
            'vehicle_make'   => 'nullable|string|max:100',
            'vehicle_model'  => 'nullable|string|max:100',
            'vehicle_color'  => 'nullable|string|max:50',
            'permit_type'    => 'required|in:annual,seasonal,monthly,daily,vip,disabled',
            'start_date'     => 'required|date',
            'end_date'       => 'nullable|date',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $data['permit_number'] = SequenceGenerator::next('parking_permit_number');
        $data['status']        = 'active';
        $data['created_at']    = date('Y-m-d H:i:s');

        $db = $this->db();
        $id = $db->insert('parking_permits', $data);
        $this->audit('create', 'parking_permits', $id, "Issued parking permit: {$data['permit_number']}");

        $this->json(['success' => true, 'message' => lang('facilities.permit_issued') . ': ' . $data['permit_number']]);
    }
}