<?php
declare(strict_types=1);

namespace App\Modules\FacilityGrids\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Modules\FacilityGrids\Models\FacilityGrid;
use App\Modules\FacilityGrids\Services\GridStateService;

class FacilityGridController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('facility_grid.view');
        $grids = FacilityGrid::allActive();
        return $this->view('FacilityGrids.Views.index', ['grids' => $grids]);
    }

    public function create(Request $request): Response
    {
        $this->authorize('facility_grid.manage');
        $gridTypes = FacilityGrid::getGridTypes();
        $facilities = $this->getFacilities();
        return $this->view('FacilityGrids.Views.create', [
            'gridTypes'  => $gridTypes,
            'facilities' => $facilities,
        ]);
    }

    public function store(Request $request): Response
    {
        $this->authorize('facility_grid.manage');

        $rules = [
            'facility_id' => 'required|numeric',
            'name_ar'     => 'required|string|max:200',
            'grid_type'   => 'required|in:pool,court,generic',
            'rows_count'  => 'required|numeric|min:1|max:50',
            'cols_count'  => 'required|numeric|min:1|max:50',
        ];

        $data = $this->validated($request->all(), $rules);

        $grid = FacilityGrid::create([
            'facility_id'    => (int) $data['facility_id'],
            'name_ar'        => $data['name_ar'],
            'name_en'        => $request->post('name_en'),
            'grid_type'      => $data['grid_type'],
            'rows_count'     => (int) $data['rows_count'],
            'cols_count'     => (int) $data['cols_count'],
            'row_label_ar'   => $request->post('row_label_ar') ?? 'حارة',
            'col_label_ar'   => $request->post('col_label_ar') ?? 'قسم',
            'physical_length'=> $request->post('physical_length') ? (float) $request->post('physical_length') : null,
            'physical_width' => $request->post('physical_width') ? (float) $request->post('physical_width') : null,
            'is_active'      => 1,
        ]);

        $this->generateZones((int) $grid->id, (int) $data['rows_count'], (int) $data['cols_count']);

        return $this->redirect('/facility-grids/' . $grid->id)->withSuccess('تم إنشاء الشبكة بنجاح');
    }

    public function show(Request $request, string $id): Response
    {
        $this->authorize('facility_grid.view');

        $grid = FacilityGrid::find((int) $id);
        if (!$grid) return $this->redirect('/facility-grids')->withError('الشبكة غير موجودة');

        $date = $request->get('date', date('Y-m-d'));
        $time = $request->get('time');
        $planMonth = $request->get('month', substr($date, 0, 7));
        $state = GridStateService::getState((int) $id, $date, $time);

        return $this->view('FacilityGrids.Views.show', [
            'grid'      => $grid,
            'state'     => $state,
            'date'      => $date,
            'planMonth' => $planMonth,
        ]);
    }

    public function edit(Request $request, string $id): Response
    {
        $this->authorize('facility_grid.manage');

        $grid = FacilityGrid::find((int) $id);
        if (!$grid) return $this->redirect('/facility-grids')->withError('الشبكة غير موجودة');

        return $this->view('FacilityGrids.Views.edit', [
            'grid'       => $grid,
            'gridTypes'  => FacilityGrid::getGridTypes(),
            'facilities' => $this->getFacilities(),
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $this->authorize('facility_grid.manage');

        $grid = FacilityGrid::find((int) $id);
        if (!$grid) return $this->redirect('/facility-grids')->withError('الشبكة غير موجودة');

        $rules = [
            'name_ar'    => 'required|string|max:200',
            'grid_type'  => 'required|in:pool,court,generic',
            'rows_count' => 'required|numeric|min:1|max:50',
            'cols_count' => 'required|numeric|min:1|max:50',
        ];

        $data = $this->validated($request->all(), $rules);

        $grid->update([
            'name_ar'        => $data['name_ar'],
            'name_en'        => $request->post('name_en'),
            'grid_type'      => $data['grid_type'],
            'rows_count'     => (int) $data['rows_count'],
            'cols_count'     => (int) $data['cols_count'],
            'row_label_ar'   => $request->post('row_label_ar') ?? 'حارة',
            'col_label_ar'   => $request->post('col_label_ar') ?? 'قسم',
            'physical_length'=> $request->post('physical_length') ? (float) $request->post('physical_length') : null,
            'physical_width' => $request->post('physical_width') ? (float) $request->post('physical_width') : null,
        ]);

        $this->regenerateZones((int) $id, (int) $data['rows_count'], (int) $data['cols_count']);

        return $this->redirect('/facility-grids/' . $id)->withSuccess('تم تحديث الشبكة');
    }

    public function apiState(Request $request, string $id): Response
    {
        $date = $request->get('date', date('Y-m-d'));
        $time = $request->get('time');
        $state = GridStateService::getState((int) $id, $date, $time);
        return $this->json(['success' => true, 'data' => $state]);
    }

    public function toggle(Request $request, string $id): Response
    {
        $this->authorize('facility_grid.manage');
        $grid = FacilityGrid::find((int) $id);
        if (!$grid) return $this->json(['success' => false, 'message' => 'غير موجود']);

        $grid->update(['is_active' => $grid->is_active ? 0 : 1]);
        return $this->redirect('/facility-grids')->withSuccess('تم تحديث الحالة');
    }

    private function generateZones(int $gridId, int $rows, int $cols): void
    {
        $db = \App\Core\App::getInstance()->db();
        for ($r = 0; $r < $rows; $r++) {
            for ($c = 0; $c < $cols; $c++) {
                $db->insert('facility_grid_zones', [
                    'grid_id'       => $gridId,
                    'row_index'     => $r,
                    'col_index'     => $c,
                    'max_occupants' => 8,
                    'is_active'     => 1,
                ]);
            }
        }
    }

    private function regenerateZones(int $gridId, int $rows, int $cols): void
    {
        $db = \App\Core\App::getInstance()->db();
        $existing = $db->select(
            "SELECT row_index, col_index FROM facility_grid_zones WHERE grid_id = ?",
            [$gridId]
        );

        $existingMap = [];
        foreach ($existing as $z) {
            $existingMap[$z['row_index'] . ':' . $z['col_index']] = true;
        }

        for ($r = 0; $r < $rows; $r++) {
            for ($c = 0; $c < $cols; $c++) {
                $key = $r . ':' . $c;
                if (!isset($existingMap[$key])) {
                    $db->insert('facility_grid_zones', [
                        'grid_id'       => $gridId,
                        'row_index'     => $r,
                        'col_index'     => $c,
                        'max_occupants' => 8,
                        'is_active'     => 1,
                    ]);
                }
            }
        }

        $db->query(
            "UPDATE facility_grid_zones SET is_active = 0 WHERE grid_id = ? AND (row_index >= ? OR col_index >= ?)",
            [$gridId, $rows, $cols]
        );
    }

    private function getFacilities(): array
    {
        $db = \App\Core\App::getInstance()->db();
        return $db->select("SELECT id, name_ar FROM facilities WHERE is_active = 1 ORDER BY name_ar");
    }
}
