<?php
declare(strict_types=1);

namespace App\Modules\Achievements\Models;

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

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

    protected static array $fillable = [
        'code',
        'name_ar',
        'name_en',
        'description_ar',
        'category',
        'icon',
        'badge_color',
        'discipline_id',
        'criteria_json',
        'points',
        'is_active',
    ];

    public static function getCategories(): array
    {
        return [
            'attendance'   => 'الحضور والانتظام',
            'performance'  => 'الأداء',
            'competition'  => 'المسابقات',
            'milestone'    => 'إنجازات زمنية',
            'social'       => 'اجتماعية',
            'fitness'      => 'اللياقة',
            'special'      => 'خاصة',
        ];
    }

    public static function getBadgeColors(): array
    {
        return [
            'gold'    => '#F59E0B',
            'silver'  => '#9CA3AF',
            'bronze'  => '#B45309',
            'blue'    => '#2563EB',
            'green'   => '#059669',
            'purple'  => '#7C3AED',
            'red'     => '#DC2626',
            'teal'    => '#0D7377',
        ];
    }

    /**
     * Get all active achievement definitions.
     */
    public static function allActive(): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT ad.*, sd.name_ar AS discipline_name
             FROM achievement_definitions ad
             LEFT JOIN sport_disciplines sd ON sd.id = ad.discipline_id
             WHERE ad.is_active = 1
             ORDER BY ad.category ASC, ad.points DESC"
        );
    }

    /**
     * Get achievements by category.
     */
    public static function getByCategory(string $category): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT * FROM achievement_definitions WHERE category = ? AND is_active = 1 ORDER BY points DESC",
            [$category]
        );
    }

    /**
     * Get achievements for a specific discipline (or global ones).
     */
    public static function getForDiscipline(?int $disciplineId): array
    {
        $db = App::getInstance()->db();
        if ($disciplineId === null) {
            return $db->select(
                "SELECT * FROM achievement_definitions WHERE discipline_id IS NULL AND is_active = 1 ORDER BY category, points DESC"
            );
        }
        return $db->select(
            "SELECT * FROM achievement_definitions WHERE (discipline_id = ? OR discipline_id IS NULL) AND is_active = 1 ORDER BY category, points DESC",
            [$disciplineId]
        );
    }

    /**
     * Get criteria decoded from JSON.
     */
    public function getCriteria(): array
    {
        $raw = $this->criteria_json;
        if (empty($raw)) {
            return [];
        }
        $decoded = json_decode($raw, true);
        return is_array($decoded) ? $decoded : [];
    }

    /**
     * Search definitions with 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['category'])) {
            $where[] = 'ad.category = ?';
            $params[] = $filters['category'];
        }

        if (isset($filters['is_active']) && $filters['is_active'] !== '') {
            $where[] = 'ad.is_active = ?';
            $params[] = (int) $filters['is_active'];
        }

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

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

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

        $countSql = "SELECT COUNT(*) as total FROM achievement_definitions ad WHERE {$whereClause}";
        $countRow = $db->selectOne($countSql, $params);
        $total = (int) ($countRow['total'] ?? 0);

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

        $dataSql = "SELECT ad.*, sd.name_ar AS discipline_name
                    FROM achievement_definitions ad
                    LEFT JOIN sport_disciplines sd ON sd.id = ad.discipline_id
                    WHERE {$whereClause}
                    ORDER BY ad.category ASC, ad.points DESC
                    LIMIT {$perPage} OFFSET {$offset}";
        $data = $db->select($dataSql, $params);

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