<?php
declare(strict_types=1);

namespace App\Modules\Scheduling\Services;

use App\Core\App;
use App\Core\EventBus;

class ScheduleChangeService
{
    public static function submitRequest(array $data): int
    {
        $db = App::getInstance()->db();

        $suggestions = [];
        if (!empty($data['current_session_id'])) {
            $session = $db->selectOne("SELECT * FROM training_sessions WHERE id = ?", [(int) $data['current_session_id']]);
            if ($session) {
                $suggestions = ConflictDetectionService::suggestAlternatives([
                    'coach_id'    => $session['coach_id'] ? (int) $session['coach_id'] : null,
                    'facility_id' => $session['facility_id'] ? (int) $session['facility_id'] : null,
                    'date'        => $data['requested_date'] ?? $session['session_date'],
                    'start_time'  => $data['requested_start_time'] ?? $session['start_time'],
                    'end_time'    => $data['requested_end_time'] ?? $session['end_time'],
                ]);
            }
        }

        $db->insert('schedule_change_requests', [
            'requester_type'         => $data['requester_type'],
            'requester_id'           => (int) $data['requester_id'],
            'request_type'           => $data['request_type'],
            'current_session_id'     => $data['current_session_id'] ? (int) $data['current_session_id'] : null,
            'current_group_id'       => $data['current_group_id'] ? (int) $data['current_group_id'] : null,
            'requested_day_of_week'  => $data['requested_day_of_week'] ?? null,
            'requested_start_time'   => $data['requested_start_time'] ?? null,
            'requested_end_time'     => $data['requested_end_time'] ?? null,
            'requested_date'         => $data['requested_date'] ?? null,
            'requested_facility_id'  => $data['requested_facility_id'] ?? null,
            'reason_ar'              => $data['reason_ar'],
            'status'                 => 'pending',
            'auto_suggestions_json'  => !empty($suggestions) ? json_encode($suggestions) : null,
            'created_at'             => date('Y-m-d H:i:s'),
            'updated_at'             => date('Y-m-d H:i:s'),
        ]);

        $requestId = (int) $db->selectOne("SELECT LAST_INSERT_ID() AS id")['id'];

        EventBus::dispatch('schedule.change_requested', [
            'request_id'     => $requestId,
            'requester_type' => $data['requester_type'],
            'requester_id'   => (int) $data['requester_id'],
            'request_type'   => $data['request_type'],
        ]);

        return $requestId;
    }

    public static function approveRequest(int $requestId, int $reviewedBy): bool
    {
        $db = App::getInstance()->db();
        $request = $db->selectOne("SELECT * FROM schedule_change_requests WHERE id = ? AND status = 'pending'", [$requestId]);
        if (!$request) return false;

        $db->update('schedule_change_requests', [
            'status'      => 'approved',
            'reviewed_by' => $reviewedBy,
            'reviewed_at' => date('Y-m-d H:i:s'),
            'updated_at'  => date('Y-m-d H:i:s'),
        ], '`id` = ?', [$requestId]);

        if ($request['request_type'] === 'reschedule' && $request['current_session_id']) {
            $updateData = ['updated_at' => date('Y-m-d H:i:s')];
            if ($request['requested_date']) $updateData['session_date'] = $request['requested_date'];
            if ($request['requested_start_time']) $updateData['start_time'] = $request['requested_start_time'];
            if ($request['requested_end_time']) $updateData['end_time'] = $request['requested_end_time'];
            if ($request['requested_facility_id']) $updateData['facility_id'] = (int) $request['requested_facility_id'];

            $db->update('training_sessions', $updateData, '`id` = ?', [(int) $request['current_session_id']]);

            EventBus::dispatch('session.rescheduled', [
                'session_id' => (int) $request['current_session_id'],
                'request_id' => $requestId,
            ]);
        }

        if ($request['request_type'] === 'cancel' && $request['current_session_id']) {
            $db->update('training_sessions', [
                'status'     => 'cancelled',
                'updated_at' => date('Y-m-d H:i:s'),
            ], '`id` = ?', [(int) $request['current_session_id']]);

            EventBus::dispatch('session.cancelled', [
                'session_id' => (int) $request['current_session_id'],
                'reason'     => $request['reason_ar'],
            ]);
        }

        return true;
    }

    public static function rejectRequest(int $requestId, int $reviewedBy, string $notes = ''): bool
    {
        $db = App::getInstance()->db();
        $db->update('schedule_change_requests', [
            'status'       => 'rejected',
            'reviewed_by'  => $reviewedBy,
            'reviewed_at'  => date('Y-m-d H:i:s'),
            'review_notes' => $notes,
            'updated_at'   => date('Y-m-d H:i:s'),
        ], '`id` = ? AND `status` = ?', [$requestId, 'pending']);

        return true;
    }

    public static function getPendingRequests(): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT scr.*,
                    CASE scr.requester_type
                        WHEN 'coach' THEN (SELECT CONCAT(first_name_ar, ' ', last_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
             WHERE scr.status = 'pending'
             ORDER BY scr.created_at ASC"
        );
    }
}
