<?php
declare(strict_types=1);

namespace App\Modules\Tournaments\Models;

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

class Tournament extends Model
{
    protected static string $table = 'tournaments';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = false;
    protected static bool $autoTrackAuthor = true;

    protected static array $fillable = [
        'name_ar',
        'name_en',
        'discipline_id',
        'tournament_type',
        'format',
        'age_group',
        'gender',
        'max_participants',
        'min_participants',
        'registration_start',
        'registration_end',
        'start_date',
        'end_date',
        'facility_id',
        'entry_fee',
        'prize_description_ar',
        'rules_ar',
        'status',
        'winner_player_id',
        'winner_team_name',
        'organizer_id',
        'banner_image',
        'notes',
    ];

    /**
     * Get tournament types with Arabic labels.
     */
    public static function getTypes(): array
    {
        return [
            'internal'     => 'داخلي',
            'friendly'     => 'ودي',
            'league'       => 'دوري',
            'championship' => 'بطولة',
            'knockout'     => 'خروج المغلوب',
            'round_robin'  => 'دوري كامل',
        ];
    }

    /**
     * Get format types with Arabic labels.
     */
    public static function getFormats(): array
    {
        return [
            'knockout'    => 'خروج المغلوب',
            'round_robin' => 'دوري (الكل ضد الكل)',
            'group_stage' => 'مجموعات',
            'swiss'       => 'النظام السويسري',
            'ladder'      => 'سلّم',
        ];
    }

    /**
     * Get statuses with Arabic labels.
     */
    public static function getStatuses(): array
    {
        return [
            'draft'               => 'مسودة',
            'registration_open'   => 'التسجيل مفتوح',
            'registration_closed' => 'التسجيل مغلق',
            'in_progress'         => 'جاري',
            'completed'           => 'منتهي',
            'cancelled'           => 'ملغي',
        ];
    }

    /**
     * Get badge color for status.
     */
    public static function getStatusColor(string $status): string
    {
        $colors = [
            'draft'               => '#6B7280',
            'registration_open'   => '#0284C7',
            'registration_closed' => '#D97706',
            'in_progress'         => '#7C3AED',
            'completed'           => '#059669',
            'cancelled'           => '#DC2626',
        ];
        return $colors[$status] ?? '#6B7280';
    }

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

        $where = ['1=1'];
        $params = [];

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

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

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

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

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

        $whereClause = implode(' AND ', $where);

        $countSql = "SELECT COUNT(*) AS total FROM tournaments t WHERE {$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;

        $sql = "SELECT t.*, d.name_ar AS discipline_name
                FROM tournaments t
                LEFT JOIN sport_disciplines d ON d.id = t.discipline_id
                WHERE {$whereClause}
                ORDER BY t.start_date DESC, t.id DESC
                LIMIT {$perPage} OFFSET {$offset}";

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

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

    /**
     * Get active (in_progress) tournaments.
     */
    public static function getActive(): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT t.*, d.name_ar AS discipline_name
             FROM tournaments t
             LEFT JOIN sport_disciplines d ON d.id = t.discipline_id
             WHERE t.status = 'in_progress'
             ORDER BY t.start_date ASC",
            []
        );
    }

    /**
     * Get upcoming tournaments (registration open or closed, not started yet).
     */
    public static function getUpcoming(): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT t.*, d.name_ar AS discipline_name
             FROM tournaments t
             LEFT JOIN sport_disciplines d ON d.id = t.discipline_id
             WHERE t.status IN ('registration_open', 'registration_closed')
               AND t.start_date >= CURDATE()
             ORDER BY t.start_date ASC",
            []
        );
    }

    /**
     * Get participant count for a tournament.
     */
    public function getParticipantCount(): int
    {
        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT COUNT(*) AS cnt FROM tournament_participants WHERE tournament_id = ? AND status NOT IN ('withdrawn', 'disqualified')",
            [(int) $this->id]
        );
        return (int) ($row['cnt'] ?? 0);
    }
}
