<?php
declare(strict_types=1);

namespace App\Modules\Scheduling\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\App;
use App\Modules\Scheduling\Models\SchedulingRule;
use App\Modules\Scheduling\Services\ConflictDetectionService;
use App\Modules\Scheduling\Services\ScheduleChangeService;

class SchedulingController extends Controller
{
    public function dashboard(Request $request): mixed
    {
        $this->authorize('scheduling.view');
        $db = App::getInstance()->db();

        $pendingRequests = ScheduleChangeService::getPendingRequests();
        $recentConflicts = $db->select(
            "SELECT * FROM scheduling_conflicts WHERE resolution = 'pending' ORDER BY detected_at DESC LIMIT 10"
        );
        $activeRules = SchedulingRule::getActiveRules();
        $stats = [
            'pending_requests' => count($pendingRequests),
            'open_conflicts'   => (int) $db->selectOne("SELECT COUNT(*) AS c FROM scheduling_conflicts WHERE resolution = 'pending'")['c'],
            'active_rules'     => count($activeRules),
            'resolved_today'   => (int) $db->selectOne("SELECT COUNT(*) AS c FROM scheduling_conflicts WHERE resolution = 'resolved' AND resolved_at >= CURDATE()")['c'],
        ];

        return $this->view('Scheduling.Views.dashboard', compact('pendingRequests', 'recentConflicts', 'activeRules', 'stats'));
    }

    public function rules(Request $request): mixed
    {
        $this->authorize('scheduling.manage_rules');
        $rules = SchedulingRule::getActiveRules();
        $ruleTypes = SchedulingRule::getRuleTypes();
        return $this->view('Scheduling.Views.rules', compact('rules', 'ruleTypes'));
    }

    public function createRule(Request $request): mixed
    {
        $this->authorize('scheduling.manage_rules');
        $ruleTypes = SchedulingRule::getRuleTypes();
        return $this->view('Scheduling.Views.rule_create', compact('ruleTypes'));
    }

    public function storeRule(Request $request): mixed
    {
        $this->authorize('scheduling.manage_rules');
        $data = $_POST;

        $this->validate($data, [
            'rule_name_ar' => 'required',
            'rule_type'    => 'required',
        ]);

        $config = [];
        switch ($data['rule_type']) {
            case 'coach_max_hours':
                $config = ['max_hours' => (int) ($data['max_hours'] ?? 8)];
                break;
            case 'facility_buffer':
                $config = ['buffer_minutes' => (int) ($data['buffer_minutes'] ?? 15)];
                break;
            case 'max_daily_sessions':
                $config = ['max_sessions' => (int) ($data['max_sessions'] ?? 3)];
                break;
            case 'rest_between_sessions':
                $config = ['rest_minutes' => (int) ($data['rest_minutes'] ?? 30)];
                break;
            case 'coach_day_off':
                $config = ['day_of_week' => (int) ($data['day_of_week'] ?? 5)];
                break;
            case 'facility_maintenance':
                $config = [
                    'day_of_week' => (int) ($data['maintenance_day'] ?? 1),
                    'start_time'  => $data['maintenance_start'] ?? '06:00',
                    'end_time'    => $data['maintenance_end'] ?? '10:00',
                ];
                break;
        }

        SchedulingRule::create([
            'rule_name_ar'  => $data['rule_name_ar'],
            'rule_type'     => $data['rule_type'],
            'applies_to'    => $data['applies_to'] ?? 'all',
            'applies_to_id' => !empty($data['applies_to_id']) ? (int) $data['applies_to_id'] : null,
            'config_json'   => json_encode($config),
            'priority'      => (int) ($data['priority'] ?? 10),
            'is_active'     => 1,
        ]);

        return $this->redirect('/scheduling/rules')->withSuccess('تم إضافة القاعدة بنجاح');
    }

    public function toggleRule(Request $request, int $id): mixed
    {
        $this->authorize('scheduling.manage_rules');
        $db = App::getInstance()->db();
        $rule = $db->selectOne("SELECT * FROM scheduling_rules WHERE id = ?", [$id]);
        if (!$rule) return $this->redirect('/scheduling/rules')->withError('القاعدة غير موجودة');

        $newStatus = $rule['is_active'] ? 0 : 1;
        $db->update('scheduling_rules', ['is_active' => $newStatus, 'updated_at' => date('Y-m-d H:i:s')], '`id` = ?', [$id]);

        return $this->redirect('/scheduling/rules')->withSuccess($newStatus ? 'تم تفعيل القاعدة' : 'تم تعطيل القاعدة');
    }

    public function deleteRule(Request $request, int $id): mixed
    {
        $this->authorize('scheduling.manage_rules');
        $db = App::getInstance()->db();
        $db->delete('scheduling_rules', '`id` = ?', [$id]);
        return $this->redirect('/scheduling/rules')->withSuccess('تم حذف القاعدة');
    }

    public function conflicts(Request $request): mixed
    {
        $this->authorize('scheduling.view');
        $db = App::getInstance()->db();
        $filter = $_GET['status'] ?? 'pending';

        $sql = "SELECT * FROM scheduling_conflicts";
        $params = [];
        if ($filter !== 'all') {
            $sql .= " WHERE resolution = ?";
            $params[] = $filter;
        }
        $sql .= " ORDER BY detected_at DESC LIMIT 50";

        $conflicts = $db->select($sql, $params);
        return $this->view('Scheduling.Views.conflicts', compact('conflicts', 'filter'));
    }

    public function resolveConflict(Request $request, int $id): mixed
    {
        $this->authorize('scheduling.resolve');
        $db = App::getInstance()->db();
        $resolution = $_POST['resolution'] ?? 'resolved';
        $notes = $_POST['notes'] ?? '';

        $db->update('scheduling_conflicts', [
            'resolution'    => $resolution,
            'resolved_by'   => (int) ($_SESSION['employee_id'] ?? 0),
            'resolved_at'   => date('Y-m-d H:i:s'),
            'resolution_notes' => $notes,
            'updated_at'    => date('Y-m-d H:i:s'),
        ], '`id` = ?', [$id]);

        return $this->redirect('/scheduling/conflicts')->withSuccess('تم معالجة التعارض');
    }

    public function changeRequests(Request $request): mixed
    {
        $this->authorize('scheduling.manage_requests');
        $db = App::getInstance()->db();
        $status = $_GET['status'] ?? 'pending';

        $sql = "SELECT scr.*,
                    CASE scr.requester_type
                        WHEN 'coach' THEN (SELECT full_name_ar FROM coaches WHERE id = scr.requester_id)
                        WHEN 'player' THEN (SELECT full_name_ar FROM players WHERE id = scr.requester_id)
                        ELSE 'مسؤول'
                    END AS requester_name
                FROM schedule_change_requests scr";
        $params = [];
        if ($status !== 'all') {
            $sql .= " WHERE scr.status = ?";
            $params[] = $status;
        }
        $sql .= " ORDER BY scr.created_at DESC LIMIT 50";

        $requests = $db->select($sql, $params);
        return $this->view('Scheduling.Views.change_requests', compact('requests', 'status'));
    }

    public function approveRequest(Request $request, int $id): mixed
    {
        $this->authorize('scheduling.manage_requests');
        $reviewedBy = (int) ($_SESSION['employee_id'] ?? 0);
        $result = ScheduleChangeService::approveRequest($id, $reviewedBy);
        if (!$result) {
            return $this->redirect('/scheduling/requests')->withError('لم يتم العثور على الطلب أو تم معالجته بالفعل');
        }
        return $this->redirect('/scheduling/requests')->withSuccess('تم قبول الطلب وتطبيق التغييرات');
    }

    public function rejectRequest(Request $request, int $id): mixed
    {
        $this->authorize('scheduling.manage_requests');
        $reviewedBy = (int) ($_SESSION['employee_id'] ?? 0);
        $notes = $_POST['notes'] ?? '';
        ScheduleChangeService::rejectRequest($id, $reviewedBy, $notes);
        return $this->redirect('/scheduling/requests')->withSuccess('تم رفض الطلب');
    }

    public function checkConflicts(Request $request): mixed
    {
        $this->authorize('scheduling.view');
        $data = $_POST;

        $proposed = [
            'coach_id'    => !empty($data['coach_id']) ? (int) $data['coach_id'] : null,
            'facility_id' => !empty($data['facility_id']) ? (int) $data['facility_id'] : null,
            'date'        => $data['date'] ?? '',
            'start_time'  => $data['start_time'] ?? '',
            'end_time'    => $data['end_time'] ?? '',
            'player_ids'  => !empty($data['player_ids']) ? array_map('intval', (array) $data['player_ids']) : [],
            'exclude_session_id' => !empty($data['exclude_session_id']) ? (int) $data['exclude_session_id'] : 0,
        ];

        $conflicts = ConflictDetectionService::detectConflicts($proposed);
        $suggestions = [];
        if (!empty($conflicts)) {
            $suggestions = ConflictDetectionService::suggestAlternatives($proposed);
        }

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