<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Services;

use App\Core\App;

final class ConflictDetectionService
{
    public static function check(
        int $facilityUnitId,
        string $date,
        string $startTime,
        string $endTime,
        ?int $coachId = null,
        ?int $excludeBookingId = null
    ): array {
        $conflicts = [];

        $slotCheck = SlotAvailabilityService::check(
            $facilityUnitId, $date, $startTime, $endTime, 1, $excludeBookingId
        );

        if (!$slotCheck['available']) {
            $conflicts[] = [
                'type'     => 'unit',
                'severity' => 'blocking',
                'message'  => $slotCheck['reason'],
            ];
        }

        if ($coachId) {
            $coachConflict = self::checkCoachConflict($coachId, $date, $startTime, $endTime, $excludeBookingId);
            if ($coachConflict) {
                $conflicts[] = $coachConflict;
            }
        }

        return $conflicts;
    }

    public static function checkCoachConflict(
        int $coachId,
        string $date,
        string $startTime,
        string $endTime,
        ?int $excludeBookingId = null
    ): ?array {
        $db = App::getInstance()->db();

        $excludeClause = $excludeBookingId ? " AND b.id != ?" : "";
        $params = [$coachId, $date, $endTime, $startTime];
        if ($excludeBookingId) {
            $params[] = $excludeBookingId;
        }

        $existing = $db->selectOne(
            "SELECT b.id, b.booking_number, fu.name_ar as unit_name
             FROM sa_bookings b
             JOIN sa_facility_units fu ON fu.id = b.facility_unit_id
             WHERE b.coach_id = ? AND b.booking_date = ?
             AND b.status NOT IN ('cancelled','no_show')
             AND b.start_time < ? AND b.end_time > ?{$excludeClause}
             LIMIT 1",
            $params
        );

        if ($existing) {
            return [
                'type'     => 'coach',
                'severity' => 'blocking',
                'message'  => "المدرب لديه حجز آخر ({$existing['booking_number']}) في {$existing['unit_name']} في نفس التوقيت",
            ];
        }

        return null;
    }

    public static function checkPlayerConflict(
        int $playerId,
        string $date,
        string $startTime,
        string $endTime,
        ?int $excludeBookingId = null
    ): ?array {
        $db = App::getInstance()->db();

        $excludeClause = $excludeBookingId ? " AND b.id != ?" : "";
        $params = [$playerId, $date, $endTime, $startTime];
        if ($excludeBookingId) {
            $params[] = $excludeBookingId;
        }

        $existing = $db->selectOne(
            "SELECT b.id, b.booking_number
             FROM sa_bookings b
             JOIN sa_booking_participants bp ON bp.booking_id = b.id
             WHERE bp.player_id = ? AND b.booking_date = ?
             AND b.status NOT IN ('cancelled','no_show')
             AND b.start_time < ? AND b.end_time > ?{$excludeClause}
             LIMIT 1",
            $params
        );

        if ($existing) {
            return [
                'type'     => 'player',
                'severity' => 'warning',
                'message'  => "اللاعب لديه حجز آخر ({$existing['booking_number']}) في نفس التوقيت",
            ];
        }

        return null;
    }
}
