<?php
declare(strict_types=1);

namespace App\Modules\Sessions\Services;

use App\Core\App;

final class ScheduleConflictResolver
{
    public static function suggestAlternatives(
        int $facilityId,
        ?int $coachId,
        string $dayOfWeek,
        string $startTime,
        string $endTime
    ): array {
        $db = App::getInstance()->db();
        $duration = (strtotime($endTime) - strtotime($startTime)) / 3600;
        $alternatives = [];

        $slots = ['07:00:00', '08:00:00', '09:00:00', '10:00:00', '11:00:00',
                  '12:00:00', '13:00:00', '14:00:00', '15:00:00', '16:00:00',
                  '17:00:00', '18:00:00', '19:00:00', '20:00:00', '21:00:00'];

        foreach ($slots as $slotStart) {
            if ($slotStart === $startTime) {
                continue;
            }
            $slotEnd = date('H:i:s', strtotime($slotStart) + (int)($duration * 3600));

            $facilityConflict = $db->selectOne("
                SELECT id FROM training_groups
                WHERE facility_id = ? AND day_of_week = ? AND status = 'active'
                  AND (start_time < ? AND end_time > ?)
            ", [$facilityId, $dayOfWeek, $slotEnd, $slotStart]);

            if ($facilityConflict) {
                continue;
            }

            if ($coachId !== null) {
                $coachConflict = $db->selectOne("
                    SELECT id FROM training_groups
                    WHERE coach_id = ? AND day_of_week = ? AND status = 'active'
                      AND (start_time < ? AND end_time > ?)
                ", [$coachId, $dayOfWeek, $slotEnd, $slotStart]);

                if ($coachConflict) {
                    continue;
                }
            }

            $alternatives[] = [
                'day_of_week' => $dayOfWeek,
                'start_time'  => $slotStart,
                'end_time'    => $slotEnd,
            ];

            if (count($alternatives) >= 5) {
                break;
            }
        }

        return $alternatives;
    }

    public static function generateSeasonSchedule(
        int $groupId,
        string $seasonStart,
        string $seasonEnd,
        array $excludeDates = []
    ): int {
        $db = App::getInstance()->db();

        $group = $db->selectOne("SELECT * FROM training_groups WHERE id = ?", [$groupId]);
        if (!$group) {
            return 0;
        }

        $dayMap = [
            'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3,
            'thursday' => 4, 'friday' => 5, 'saturday' => 6,
        ];

        $targetDay = $dayMap[$group['day_of_week']] ?? null;
        if ($targetDay === null) {
            return 0;
        }

        $enrolledCount = $db->selectOne(
            "SELECT COUNT(*) AS cnt FROM group_memberships WHERE group_id = ? AND status = 'active'",
            [$groupId]
        )['cnt'] ?? 0;

        $created = 0;
        $current = strtotime($seasonStart);
        $end = strtotime($seasonEnd);

        while ($current <= $end) {
            if ((int) date('w', $current) === $targetDay) {
                $dateStr = date('Y-m-d', $current);

                if (in_array($dateStr, $excludeDates, true)) {
                    $current += 86400;
                    continue;
                }

                $exists = $db->selectOne(
                    "SELECT id FROM training_sessions WHERE group_id = ? AND session_date = ?",
                    [$groupId, $dateStr]
                );

                if (!$exists) {
                    $db->insert('training_sessions', [
                        'group_id'         => $groupId,
                        'academy_id'       => $group['academy_id'] ? (int) $group['academy_id'] : null,
                        'coach_id'         => $group['coach_id'] ? (int) $group['coach_id'] : null,
                        'facility_id'      => $group['facility_id'] ? (int) $group['facility_id'] : null,
                        'session_date'     => $dateStr,
                        'start_time'       => $group['start_time'],
                        'end_time'         => $group['end_time'],
                        'session_type'     => 'regular',
                        'status'           => 'scheduled',
                        'players_expected' => (int) $enrolledCount,
                    ]);
                    $created++;
                }
            }
            $current += 86400;
        }

        return $created;
    }

    public static function applyHolidayOverrides(string $startDate, string $endDate, string $reason = 'إجازة رسمية'): int
    {
        $db = App::getInstance()->db();

        $result = $db->query(
            "UPDATE training_sessions
             SET status = 'cancelled', cancellation_reason = ?
             WHERE session_date BETWEEN ? AND ?
               AND status = 'scheduled'",
            [$reason, $startDate, $endDate]
        );

        return $result->rowCount();
    }
}
