<?php
declare(strict_types=1);

namespace App\Modules\Disciplines\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Modules\Disciplines\Models\GroupWaitlist;

class WaitlistService
{
    /**
     * Add a player to a group's waitlist.
     */
    public static function addToWaitlist(int $groupId, int $playerId, string $notes = ''): array
    {
        $db = App::getInstance()->db();

        // Check if already on waitlist for this group
        $existing = GroupWaitlist::query()
            ->where('group_id', '=', $groupId)
            ->where('player_id', '=', $playerId)
            ->whereIn('status', ['waiting', 'offered'])
            ->first();

        if ($existing) {
            return ['success' => false, 'message' => 'اللاعب موجود بالفعل في قائمة الانتظار لهذه المجموعة'];
        }

        // Determine next priority
        $maxPriority = $db->selectOne(
            "SELECT MAX(priority) as max_p FROM group_waitlist WHERE group_id = ? AND status = 'waiting'",
            [$groupId]
        );
        $nextPriority = ((int) ($maxPriority['max_p'] ?? 0)) + 1;

        $entry = GroupWaitlist::create([
            'group_id'     => $groupId,
            'player_id'    => $playerId,
            'priority'     => $nextPriority,
            'status'       => 'waiting',
            'requested_at' => date('Y-m-d H:i:s'),
            'notes'        => $notes ?: null,
        ]);

        return ['success' => true, 'entry' => $entry, 'message' => 'تمت الإضافة لقائمة الانتظار بنجاح'];
    }

    /**
     * Offer a spot to a waitlisted player.
     */
    public static function offerSpot(int $waitlistId): array
    {
        $entry = GroupWaitlist::find($waitlistId);
        if (!$entry) {
            return ['success' => false, 'message' => 'السجل غير موجود'];
        }

        if ($entry->status !== 'waiting') {
            return ['success' => false, 'message' => 'لا يمكن تقديم العرض — الحالة الحالية: ' . $entry->status];
        }

        $expiresAt = date('Y-m-d H:i:s', strtotime('+48 hours'));

        $entry->update([
            'status'     => 'offered',
            'offered_at' => date('Y-m-d H:i:s'),
            'expires_at' => $expiresAt,
        ]);

        EventBus::dispatch('waitlist.spot_offered', [
            'waitlist_id' => $waitlistId,
            'group_id'    => $entry->group_id,
            'player_id'   => $entry->player_id,
            'expires_at'  => $expiresAt,
        ]);

        return ['success' => true, 'message' => 'تم تقديم العرض للاعب بنجاح'];
    }

    /**
     * Accept an offered spot.
     */
    public static function acceptOffer(int $waitlistId): array
    {
        $entry = GroupWaitlist::find($waitlistId);
        if (!$entry) {
            return ['success' => false, 'message' => 'السجل غير موجود'];
        }

        if ($entry->status !== 'offered') {
            return ['success' => false, 'message' => 'لا يوجد عرض مفتوح لهذا السجل'];
        }

        // Check if expired
        if ($entry->expires_at && strtotime($entry->expires_at) < time()) {
            $entry->update(['status' => 'expired']);
            return ['success' => false, 'message' => 'انتهت صلاحية العرض'];
        }

        $entry->update(['status' => 'accepted']);

        EventBus::dispatch('waitlist.spot_accepted', [
            'waitlist_id' => $waitlistId,
            'group_id'    => $entry->group_id,
            'player_id'   => $entry->player_id,
        ]);

        return ['success' => true, 'message' => 'تم قبول العرض بنجاح'];
    }

    /**
     * Expire an offered spot.
     */
    public static function expireOffer(int $waitlistId): array
    {
        $entry = GroupWaitlist::find($waitlistId);
        if (!$entry) {
            return ['success' => false, 'message' => 'السجل غير موجود'];
        }

        if ($entry->status !== 'offered') {
            return ['success' => false, 'message' => 'لا يوجد عرض مفتوح لهذا السجل'];
        }

        $entry->update(['status' => 'expired']);

        return ['success' => true, 'message' => 'تم إنهاء صلاحية العرض'];
    }

    /**
     * Remove a player from the waitlist.
     */
    public static function removeFromWaitlist(int $waitlistId): array
    {
        $db = App::getInstance()->db();

        $entry = GroupWaitlist::find($waitlistId);
        if (!$entry) {
            return ['success' => false, 'message' => 'السجل غير موجود'];
        }

        $db->delete('group_waitlist', 'id = ?', [$waitlistId]);

        return ['success' => true, 'message' => 'تم إزالة اللاعب من قائمة الانتظار'];
    }

    /**
     * Process all expired offers (cron job).
     */
    public static function processExpiredOffers(): int
    {
        $db = App::getInstance()->db();

        $expired = $db->select(
            "SELECT id FROM group_waitlist WHERE status = 'offered' AND expires_at < NOW()",
            []
        );

        $count = 0;
        foreach ($expired as $row) {
            $db->update('group_waitlist', ['status' => 'expired'], 'id = ?', [(int) $row['id']]);
            $count++;
        }

        return $count;
    }

    /**
     * Get the position of a player in a group's waitlist.
     */
    public static function getGroupPosition(int $groupId, int $playerId): ?int
    {
        $db = App::getInstance()->db();

        $rows = $db->select(
            "SELECT player_id FROM group_waitlist
             WHERE group_id = ? AND status = 'waiting'
             ORDER BY priority ASC, requested_at ASC",
            [$groupId]
        );

        $position = 1;
        foreach ($rows as $row) {
            if ((int) $row['player_id'] === $playerId) {
                return $position;
            }
            $position++;
        }

        return null;
    }
}
