<?php
declare(strict_types=1);

namespace App\Modules\Coaches\Services;

use App\Core\App;
use App\Core\Logger;
use App\Modules\Coaches\Models\Coach;
use App\Modules\Coaches\Models\CoachPerformanceMetric;

final class CoachPerformanceService
{
    /**
     * Calculate monthly metrics for a specific coach.
     */
    public static function calculateMonthlyMetrics(int $coachId, string $yearMonth): array
    {
        return CoachPerformanceMetric::calculateForMonth($coachId, $yearMonth);
    }

    /**
     * Batch calculation for all active coaches (called by cron).
     */
    public static function calculateAllCoachesMetrics(string $yearMonth): int
    {
        $coaches = Coach::allActive();
        $count = 0;

        foreach ($coaches as $coach) {
            try {
                CoachPerformanceMetric::calculateForMonth((int) $coach['id'], $yearMonth);
                $count++;
            } catch (\Throwable $e) {
                Logger::error("Failed to calculate metrics for coach #{$coach['id']}: " . $e->getMessage());
            }
        }

        Logger::info("Calculated performance metrics for {$count} coaches for {$yearMonth}");
        return $count;
    }

    /**
     * Get performance report for a coach over a date range.
     */
    public static function getPerformanceReport(int $coachId, string $fromMonth, string $toMonth): array
    {
        $db = App::getInstance()->db();

        $metrics = $db->select(
            "SELECT * FROM coach_performance_metrics
             WHERE coach_id = ? AND period_month >= ? AND period_month <= ?
             ORDER BY period_month ASC",
            [$coachId, $fromMonth, $toMonth]
        );

        // Build trend data
        $trend = [
            'months'           => [],
            'sessions'         => [],
            'attendance_rate'  => [],
            'ratings'          => [],
            'players'          => [],
            'retention'        => [],
            'revenue'          => [],
            'composite_scores' => [],
        ];

        foreach ($metrics as $m) {
            $trend['months'][]           = $m['period_month'];
            $trend['sessions'][]         = (int) $m['total_sessions_conducted'];
            $trend['attendance_rate'][]   = (float) $m['avg_attendance_rate'];
            $trend['ratings'][]          = $m['avg_rating'] !== null ? (float) $m['avg_rating'] : null;
            $trend['players'][]          = (int) $m['total_players_trained'];
            $trend['retention'][]        = (float) $m['player_retention_rate'];
            $trend['revenue'][]          = (float) $m['revenue_generated'];
            $trend['composite_scores'][] = CoachPerformanceMetric::getCompositeScore($m);
        }

        // Summary stats
        $totalSessions = array_sum($trend['sessions']);
        $avgAttendance = !empty($trend['attendance_rate'])
            ? round(array_sum($trend['attendance_rate']) / count($trend['attendance_rate']), 2) : 0;
        $validRatings = array_filter($trend['ratings'], fn($r) => $r !== null);
        $avgRating = !empty($validRatings) ? round(array_sum($validRatings) / count($validRatings), 2) : null;
        $totalRevenue = array_sum($trend['revenue']);

        return [
            'metrics' => $metrics,
            'trend'   => $trend,
            'summary' => [
                'total_sessions'   => $totalSessions,
                'avg_attendance'   => $avgAttendance,
                'avg_rating'       => $avgRating,
                'total_revenue'    => $totalRevenue,
                'months_covered'   => count($metrics),
            ],
        ];
    }

    /**
     * Get all coaches ranked by composite score for a specific month.
     */
    public static function getRanking(string $yearMonth): array
    {
        $db = App::getInstance()->db();

        $metrics = $db->select(
            "SELECT cpm.*, c.full_name_ar AS coach_name, c.code AS coach_code, c.photo_path
             FROM coach_performance_metrics cpm
             INNER JOIN coaches c ON c.id = cpm.coach_id AND c.is_active = 1
             WHERE cpm.period_month = ?
             ORDER BY cpm.avg_rating DESC",
            [$yearMonth]
        );

        // Calculate composite score and sort
        $ranked = [];
        foreach ($metrics as $m) {
            $m['composite_score'] = CoachPerformanceMetric::getCompositeScore($m);
            $ranked[] = $m;
        }

        usort($ranked, fn($a, $b) => $b['composite_score'] <=> $a['composite_score']);

        return $ranked;
    }

    /**
     * Get performance summary for a single coach (current state).
     */
    public static function getCoachSummary(int $coachId): array
    {
        $latest = CoachPerformanceMetric::getLatest($coachId);
        $last6Months = CoachPerformanceMetric::getForCoach($coachId, 6);

        $compositeScore = $latest ? CoachPerformanceMetric::getCompositeScore($latest) : 0;

        // Determine performance level
        $level = match(true) {
            $compositeScore >= 85 => 'excellent',
            $compositeScore >= 70 => 'good',
            $compositeScore >= 55 => 'average',
            $compositeScore >= 40 => 'below_average',
            default               => 'poor',
        };

        $levelLabels = [
            'excellent'     => 'ممتاز',
            'good'          => 'جيد',
            'average'       => 'متوسط',
            'below_average' => 'أقل من المتوسط',
            'poor'          => 'ضعيف',
        ];

        $levelColors = [
            'excellent'     => '#059669',
            'good'          => '#0D7377',
            'average'       => '#D97706',
            'below_average' => '#EA580C',
            'poor'          => '#DC2626',
        ];

        return [
            'latest_metrics'  => $latest,
            'last_6_months'   => $last6Months,
            'composite_score' => $compositeScore,
            'level'           => $level,
            'level_label'     => $levelLabels[$level] ?? $level,
            'level_color'     => $levelColors[$level] ?? '#6B7280',
        ];
    }
}
