<?php
declare(strict_types=1);

namespace App\Modules\PlayerAffairs\Models;

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

class PlayerFitnessTest extends Model
{
    protected static string $table = 'player_fitness_tests';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = false;
    protected static bool $softDelete = false;
    protected static bool $autoTrackAuthor = false;

    protected static array $fillable = [
        'player_id',
        'discipline_id',
        'test_date',
        'test_type',
        'tester_name',
        'coach_id',
        'results_json',
        'overall_fitness_score',
        'fitness_level',
        'bmi',
        'weight_kg',
        'height_cm',
        'resting_heart_rate',
        'blood_pressure',
        'recommendations_ar',
        'cleared_for_activity',
        'next_test_date',
    ];

    public static function getTestTypes(): array
    {
        return [
            'initial'    => 'تقييم أولي',
            'periodic'   => 'دوري',
            'return'     => 'عودة من إصابة',
            'pre_season' => 'قبل الموسم',
            'post_season'=> 'بعد الموسم',
            'special'    => 'خاص',
        ];
    }

    public static function getFitnessLevels(): array
    {
        return [
            'excellent' => 'ممتاز',
            'good'      => 'جيد',
            'average'   => 'متوسط',
            'below_avg' => 'أقل من المتوسط',
            'poor'      => 'ضعيف',
        ];
    }

    public static function getFitnessLevelColor(string $level): string
    {
        $colors = [
            'excellent' => '#059669',
            'good'      => '#0D7377',
            'average'   => '#D97706',
            'below_avg' => '#EA580C',
            'poor'      => '#DC2626',
        ];
        return $colors[$level] ?? '#6B7280';
    }

    /**
     * Determine fitness level from a numeric score (0-100).
     */
    public static function determineFitnessLevel(float $score): string
    {
        if ($score >= 90) return 'excellent';
        if ($score >= 75) return 'good';
        if ($score >= 60) return 'average';
        if ($score >= 40) return 'below_avg';
        return 'poor';
    }

    /**
     * Get all fitness tests for a specific player.
     */
    public static function getForPlayer(int $playerId): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT pft.*, p.full_name_ar AS player_name, sd.name_ar AS discipline_name,
                    c.full_name_ar AS coach_name
             FROM player_fitness_tests pft
             LEFT JOIN players p ON p.id = pft.player_id
             LEFT JOIN sport_disciplines sd ON sd.id = pft.discipline_id
             LEFT JOIN coaches c ON c.id = pft.coach_id
             WHERE pft.player_id = ?
             ORDER BY pft.test_date DESC",
            [$playerId]
        );
    }

    /**
     * Get the latest fitness test for a player.
     */
    public static function getLatest(int $playerId): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne(
            "SELECT pft.*, p.full_name_ar AS player_name, sd.name_ar AS discipline_name,
                    c.full_name_ar AS coach_name
             FROM player_fitness_tests pft
             LEFT JOIN players p ON p.id = pft.player_id
             LEFT JOIN sport_disciplines sd ON sd.id = pft.discipline_id
             LEFT JOIN coaches c ON c.id = pft.coach_id
             WHERE pft.player_id = ?
             ORDER BY pft.test_date DESC
             LIMIT 1",
            [$playerId]
        );
    }

    /**
     * Search fitness tests 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['player_id'])) {
            $where[] = 'pft.player_id = ?';
            $params[] = (int) $filters['player_id'];
        }

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

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

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

        if (!empty($filters['date_from'])) {
            $where[] = 'pft.test_date >= ?';
            $params[] = $filters['date_from'];
        }

        if (!empty($filters['date_to'])) {
            $where[] = 'pft.test_date <= ?';
            $params[] = $filters['date_to'];
        }

        if (!empty($filters['q'])) {
            $search = '%' . $filters['q'] . '%';
            $where[] = '(p.full_name_ar LIKE ? OR pft.tester_name LIKE ?)';
            $params[] = $search;
            $params[] = $search;
        }

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

        $countSql = "SELECT COUNT(*) as total FROM player_fitness_tests pft LEFT JOIN players p ON p.id = pft.player_id 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 pft.*, p.full_name_ar AS player_name, sd.name_ar AS discipline_name,
                           c.full_name_ar AS coach_name
                    FROM player_fitness_tests pft
                    LEFT JOIN players p ON p.id = pft.player_id
                    LEFT JOIN sport_disciplines sd ON sd.id = pft.discipline_id
                    LEFT JOIN coaches c ON c.id = pft.coach_id
                    WHERE {$whereClause}
                    ORDER BY pft.test_date 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,
            ],
        ];
    }

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