<?php
declare(strict_types=1);

namespace App\Modules\FacilityGrids\Controllers;

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

class ZoneScheduleController extends Controller
{
    public function index(Request $request, string $gridId): Response
    {
        $this->authorize('facility_grid.manage');
        $gridId = (int) $gridId;

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

        $schedules = FacilityZoneSchedule::getAllForGrid($gridId);
        $dayNames = FacilityZoneSchedule::getDayNames();

        return $this->view('FacilityGrids.Views.schedules', [
            'grid'      => $grid,
            'schedules' => $schedules,
            'dayNames'  => $dayNames,
        ]);
    }

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

        $grid = FacilityGrid::find($gridId);
        if (!$grid) return $this->json(['success' => false, 'message' => 'شبكة غير موجودة']);

        $rules = [
            'schedule_name'       => 'required|string|max:255',
            'zone_selection_type' => 'required|in:cells,row,column,all',
            'day_of_week'         => 'required|numeric|min:0|max:6',
            'start_time'          => 'required',
            'end_time'            => 'required',
            'effective_from'      => 'required|date',
        ];

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

        $selectionType = $data['zone_selection_type'];
        $selectionJson = $request->post('zone_selection_json') ?? '[]';

        $positions = GridStateService::resolvePositions([
            'zone_selection_type' => $selectionType,
            'zone_selection_json' => $selectionJson,
        ], (int) $grid->rows_count, (int) $grid->cols_count);

        $conflicts = GridStateService::checkConflicts(
            $gridId,
            $positions,
            (int) $data['day_of_week'],
            $data['start_time'],
            $data['end_time'],
            $data['effective_from'],
            $request->post('effective_to')
        );

        if (!empty($conflicts)) {
            return $this->json([
                'success'   => false,
                'message'   => 'يوجد تعارض مع جداول أخرى',
                'conflicts' => $conflicts,
            ]);
        }

        // Validate coach registration
        $db = App::getInstance()->db();
        $coachId = $request->post('coach_id') ? (int) $request->post('coach_id') : null;
        if ($coachId) {
            $coach = $db->selectOne("SELECT id, is_active FROM coaches WHERE id = ?", [$coachId]);
            if (!$coach) {
                return $this->json(['success' => false, 'message' => 'المدرب غير مسجل في النظام']);
            }
            if (!$coach['is_active']) {
                return $this->json(['success' => false, 'message' => 'المدرب غير نشط — يجب تفعيل حسابه أولاً']);
            }
        }

        // Validate academy registration
        $academyId = $request->post('academy_id') ? (int) $request->post('academy_id') : null;
        if ($academyId) {
            $academy = $db->selectOne("SELECT id, is_active FROM academies WHERE id = ?", [$academyId]);
            if (!$academy) {
                return $this->json(['success' => false, 'message' => 'الأكاديمية غير مسجلة في النظام']);
            }
            if (!$academy['is_active']) {
                return $this->json(['success' => false, 'message' => 'الأكاديمية غير نشطة']);
            }
        }

        $maxOccupants = FacilityZoneSchedule::getMaxOccupants($selectionType);
        $planMonth = $request->post('plan_month') ?? date('Y-m');

        $schedule = FacilityZoneSchedule::create([
            'grid_id'             => $gridId,
            'plan_month'          => $planMonth,
            'schedule_name'       => $data['schedule_name'],
            'zone_selection_type' => $selectionType,
            'zone_selection_json' => $selectionJson,
            'day_of_week'         => (int) $data['day_of_week'],
            'start_time'          => $data['start_time'],
            'end_time'            => $data['end_time'],
            'activity_type'       => $request->post('activity_type'),
            'coach_id'            => $request->post('coach_id') ? (int) $request->post('coach_id') : null,
            'coach_name'          => $request->post('coach_name'),
            'academy_id'          => $request->post('academy_id') ? (int) $request->post('academy_id') : null,
            'academy_name'        => $request->post('academy_name'),
            'age_group'           => $request->post('age_group'),
            'gender'              => $request->post('gender') ?? 'male',
            'max_occupants'       => $maxOccupants,
            'color'               => $request->post('color') ?? '#3B82F6',
            'effective_from'      => $data['effective_from'],
            'effective_to'        => $request->post('effective_to'),
            'is_active'           => 1,
            'notes'               => $request->post('notes'),
        ]);

        return $this->json([
            'success'  => true,
            'message'  => 'تم إنشاء الجدول بنجاح',
            'schedule' => ['id' => (int) $schedule->id],
        ]);
    }

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

        $schedule = FacilityZoneSchedule::find($scheduleId);
        if (!$schedule || (int) $schedule->grid_id !== $gridId) {
            return $this->json(['success' => false, 'message' => 'جدول غير موجود']);
        }

        $grid = FacilityGrid::find($gridId);
        $selectionType = $request->post('zone_selection_type') ?? $schedule->zone_selection_type;
        $selectionJson = $request->post('zone_selection_json') ?? $schedule->zone_selection_json;

        $positions = GridStateService::resolvePositions([
            'zone_selection_type' => $selectionType,
            'zone_selection_json' => $selectionJson,
        ], (int) $grid->rows_count, (int) $grid->cols_count);

        $conflicts = GridStateService::checkConflicts(
            $gridId,
            $positions,
            (int) ($request->post('day_of_week') ?? $schedule->day_of_week),
            $request->post('start_time') ?? $schedule->start_time,
            $request->post('end_time') ?? $schedule->end_time,
            $request->post('effective_from') ?? $schedule->effective_from,
            $request->post('effective_to') ?? $schedule->effective_to,
            $scheduleId
        );

        if (!empty($conflicts)) {
            return $this->json([
                'success'   => false,
                'message'   => 'يوجد تعارض مع جداول أخرى',
                'conflicts' => $conflicts,
            ]);
        }

        $schedule->update([
            'schedule_name'       => $request->post('schedule_name') ?? $schedule->schedule_name,
            'zone_selection_type' => $selectionType,
            'zone_selection_json' => $selectionJson,
            'day_of_week'         => (int) ($request->post('day_of_week') ?? $schedule->day_of_week),
            'start_time'          => $request->post('start_time') ?? $schedule->start_time,
            'end_time'            => $request->post('end_time') ?? $schedule->end_time,
            'activity_type'       => $request->post('activity_type') ?? $schedule->activity_type,
            'coach_id'            => $request->post('coach_id') ? (int) $request->post('coach_id') : $schedule->coach_id,
            'coach_name'          => $request->post('coach_name') ?? $schedule->coach_name,
            'academy_id'          => $request->post('academy_id') ? (int) $request->post('academy_id') : $schedule->academy_id,
            'academy_name'        => $request->post('academy_name') ?? $schedule->academy_name,
            'age_group'           => $request->post('age_group') ?? $schedule->age_group,
            'gender'              => $request->post('gender') ?? $schedule->gender,
            'max_occupants'       => $request->post('max_occupants') ? (int) $request->post('max_occupants') : (int) $schedule->max_occupants,
            'color'               => $request->post('color') ?? $schedule->color,
            'effective_from'      => $request->post('effective_from') ?? $schedule->effective_from,
            'effective_to'        => $request->post('effective_to') ?? $schedule->effective_to,
            'notes'               => $request->post('notes') ?? $schedule->notes,
        ]);

        return $this->json(['success' => true, 'message' => 'تم تحديث الجدول']);
    }

    public function destroy(Request $request, string $gridId, string $scheduleId): Response
    {
        $this->authorize('facility_grid.manage');
        $gridId = (int) $gridId;
        $scheduleId = (int) $scheduleId;

        $schedule = FacilityZoneSchedule::find($scheduleId);
        if (!$schedule || (int) $schedule->grid_id !== $gridId) {
            return $this->json(['success' => false, 'message' => 'جدول غير موجود']);
        }

        $schedule->update(['is_active' => 0]);
        return $this->json(['success' => true, 'message' => 'تم حذف الجدول']);
    }

    public function checkConflicts(Request $request, string $gridId): Response
    {
        $gridId = (int) $gridId;
        $grid = FacilityGrid::find($gridId);
        if (!$grid) return $this->json(['success' => false]);

        $positions = GridStateService::resolvePositions([
            'zone_selection_type' => $request->get('type', 'cells'),
            'zone_selection_json' => $request->get('json', '[]'),
        ], (int) $grid->rows_count, (int) $grid->cols_count);

        $conflicts = GridStateService::checkConflicts(
            $gridId,
            $positions,
            (int) ($request->get('day', '0')),
            $request->get('start', '00:00'),
            $request->get('end', '23:59'),
            $request->get('from', date('Y-m-d')),
            $request->get('to'),
            $request->get('exclude') ? (int) $request->get('exclude') : null
        );

        return $this->json(['success' => true, 'conflicts' => $conflicts]);
    }
}
