<?php
declare(strict_types=1);

namespace App\Modules\Coaches\Models;

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

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

    protected static array $fillable = [
        'coach_id',
        'player_id',
        'member_id',
        'session_id',
        'rating',
        'punctuality_score',
        'communication_score',
        'technique_score',
        'motivation_score',
        'feedback_ar',
        'is_anonymous',
        'status',
        'admin_response_ar',
    ];

    public static function getRatingStatuses(): array
    {
        return [
            'published'  => 'منشور',
            'flagged'    => 'مبلغ عنه',
            'hidden'     => 'مخفي',
        ];
    }

    /**
     * Get ratings for a specific coach.
     */
    public static function getForCoach(int $coachId, int $limit = 50): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT cr.*, p.full_name_ar AS player_name, p.registration_serial
             FROM coach_ratings cr
             LEFT JOIN players p ON p.id = cr.player_id
             WHERE cr.coach_id = ? AND cr.status = 'published'
             ORDER BY cr.created_at DESC
             LIMIT ?",
            [$coachId, $limit]
        );
    }

    /**
     * Get average scores for a coach.
     */
    public static function getAverages(int $coachId): array
    {
        $db = App::getInstance()->db();
        $row = $db->selectOne(
            "SELECT
                COUNT(*) AS total_ratings,
                AVG(rating) AS avg_rating,
                AVG(punctuality_score) AS avg_punctuality,
                AVG(communication_score) AS avg_communication,
                AVG(technique_score) AS avg_technique,
                AVG(motivation_score) AS avg_motivation
             FROM coach_ratings
             WHERE coach_id = ? AND status = 'published'",
            [$coachId]
        );

        return [
            'total_ratings'     => (int) ($row['total_ratings'] ?? 0),
            'avg_rating'        => $row['avg_rating'] !== null ? round((float) $row['avg_rating'], 2) : null,
            'avg_punctuality'   => $row['avg_punctuality'] !== null ? round((float) $row['avg_punctuality'], 2) : null,
            'avg_communication' => $row['avg_communication'] !== null ? round((float) $row['avg_communication'], 2) : null,
            'avg_technique'     => $row['avg_technique'] !== null ? round((float) $row['avg_technique'], 2) : null,
            'avg_motivation'    => $row['avg_motivation'] !== null ? round((float) $row['avg_motivation'], 2) : null,
        ];
    }

    /**
     * Search ratings 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['coach_id'])) {
            $where[] = 'cr.coach_id = ?';
            $params[] = (int) $filters['coach_id'];
        }

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

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

        if (!empty($filters['min_rating'])) {
            $where[] = 'cr.rating >= ?';
            $params[] = (int) $filters['min_rating'];
        }

        if (!empty($filters['date_from'])) {
            $where[] = 'cr.created_at >= ?';
            $params[] = $filters['date_from'] . ' 00:00:00';
        }

        if (!empty($filters['date_to'])) {
            $where[] = 'cr.created_at <= ?';
            $params[] = $filters['date_to'] . ' 23:59:59';
        }

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

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

    /**
     * Check if a player has already rated a coach for a specific session.
     */
    public static function hasRated(int $playerId, int $coachId, ?int $sessionId = null): bool
    {
        $db = App::getInstance()->db();

        if ($sessionId !== null) {
            $row = $db->selectOne(
                "SELECT id FROM coach_ratings WHERE player_id = ? AND coach_id = ? AND session_id = ?",
                [$playerId, $coachId, $sessionId]
            );
        } else {
            // Check for rating in the last 24 hours without session
            $row = $db->selectOne(
                "SELECT id FROM coach_ratings WHERE player_id = ? AND coach_id = ? AND session_id IS NULL AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)",
                [$playerId, $coachId]
            );
        }

        return $row !== null;
    }
}
