<?php
declare(strict_types=1);

namespace App\Modules\Disciplines\Models;

use App\Core\Model;
use App\Core\App;

class GroupWaitlist extends Model
{
    protected static string $table = 'group_waitlist';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = false;

    protected static array $fillable = [
        'group_id',
        'player_id',
        'priority',
        'status',
        'requested_at',
        'offered_at',
        'expires_at',
        'notes',
    ];

    /**
     * Get all waitlist entries for a specific group, ordered by priority.
     */
    public static function getForGroup(int $groupId, ?string $status = null): array
    {
        $query = static::query()
            ->where('group_id', '=', $groupId)
            ->orderBy('priority', 'ASC')
            ->orderBy('requested_at', 'ASC');

        if ($status !== null) {
            $query = $query->where('status', '=', $status);
        }

        return $query->get();
    }

    /**
     * Get all waitlist entries for a specific player.
     */
    public static function getForPlayer(int $playerId): array
    {
        return static::query()
            ->where('player_id', '=', $playerId)
            ->orderBy('requested_at', 'DESC')
            ->get();
    }

    /**
     * Get the next person in line for a specific group.
     */
    public static function getNextInLine(int $groupId): ?array
    {
        $result = static::query()
            ->where('group_id', '=', $groupId)
            ->where('status', '=', 'waiting')
            ->orderBy('priority', 'ASC')
            ->orderBy('requested_at', 'ASC')
            ->first();

        return $result ?: null;
    }

    /**
     * Search waitlist entries with filters and pagination.
     */
    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();

        $where = [];
        $params = [];

        if (!empty($filters['group_id'])) {
            $where[] = 'gw.group_id = ?';
            $params[] = (int) $filters['group_id'];
        }

        if (!empty($filters['status'])) {
            $where[] = 'gw.status = ?';
            $params[] = $filters['status'];
        }

        if (!empty($filters['q'])) {
            $search = '%' . $filters['q'] . '%';
            $where[] = '(m.name_ar LIKE ? OR m.membership_number LIKE ?)';
            $params[] = $search;
            $params[] = $search;
        }

        $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';

        // Count total
        $countSql = "SELECT COUNT(*) as total
                     FROM group_waitlist gw
                     LEFT JOIN members m ON m.id = gw.player_id
                     LEFT JOIN training_groups tg ON tg.id = gw.group_id
                     {$whereClause}";
        $countResult = $db->selectOne($countSql, $params);
        $total = (int) ($countResult['total'] ?? 0);

        $lastPage = max(1, (int) ceil($total / $perPage));
        $page = min($page, $lastPage);
        $offset = ($page - 1) * $perPage;

        // Fetch data
        $sql = "SELECT gw.*,
                       m.name_ar AS player_name, m.membership_number,
                       tg.name_ar AS group_name
                FROM group_waitlist gw
                LEFT JOIN members m ON m.id = gw.player_id
                LEFT JOIN training_groups tg ON tg.id = gw.group_id
                {$whereClause}
                ORDER BY gw.group_id ASC, gw.priority ASC, gw.requested_at ASC
                LIMIT {$perPage} OFFSET {$offset}";

        $data = $db->select($sql, $params);

        return [
            'data' => $data,
            'pagination' => [
                'current_page' => $page,
                'last_page'    => $lastPage,
                'per_page'     => $perPage,
                'total'        => $total,
            ],
        ];
    }
}
