<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;

final class AttendanceRuleService
{
    private const DEFAULT_ABSENCE_THRESHOLD = 3;

    public static function checkAbsenceThreshold(int $playerId, int $groupId): ?array
    {
        $db = App::getInstance()->db();

        $monthStart = date('Y-m-01');
        $today = date('Y-m-d');

        $absences = (int) ($db->selectOne(
            "SELECT COUNT(*) as cnt FROM sa_attendance
             WHERE player_id = ? AND group_id = ? AND status = 'absent'
             AND attendance_date BETWEEN ? AND ?",
            [$playerId, $groupId, $monthStart, $today]
        )['cnt'] ?? 0);

        $thresholdRow = $db->selectOne(
            "SELECT config_value FROM system_config WHERE config_key = 'sa.absence_threshold'",
            []
        );
        $threshold = (int) ($thresholdRow['config_value'] ?? self::DEFAULT_ABSENCE_THRESHOLD);

        if ($absences >= $threshold) {
            return [
                'player_id'  => $playerId,
                'group_id'   => $groupId,
                'absences'   => $absences,
                'threshold'  => $threshold,
                'month'      => date('Y-m'),
            ];
        }

        return null;
    }

    public static function getAttendanceRate(int $playerId, int $groupId, string $from, string $to): float
    {
        $db = App::getInstance()->db();

        $total = (int) ($db->selectOne(
            "SELECT COUNT(*) as cnt FROM sa_attendance
             WHERE player_id = ? AND group_id = ? AND attendance_date BETWEEN ? AND ?",
            [$playerId, $groupId, $from, $to]
        )['cnt'] ?? 0);

        if ($total === 0) {
            return 0.0;
        }

        $present = (int) ($db->selectOne(
            "SELECT COUNT(*) as cnt FROM sa_attendance
             WHERE player_id = ? AND group_id = ? AND status IN ('present', 'late')
             AND attendance_date BETWEEN ? AND ?",
            [$playerId, $groupId, $from, $to]
        )['cnt'] ?? 0);

        return round(($present / $total) * 100, 1);
    }

    public static function processMonthlyAbsenceReport(): array
    {
        $db = App::getInstance()->db();

        $lastMonth = date('Y-m-01', strtotime('-1 month'));
        $lastMonthEnd = date('Y-m-t', strtotime('-1 month'));
        $processed = 0;

        $thresholdRow = $db->selectOne(
            "SELECT config_value FROM system_config WHERE config_key = 'sa.absence_threshold'",
            []
        );
        $threshold = (int) ($thresholdRow['config_value'] ?? self::DEFAULT_ABSENCE_THRESHOLD);

        $absentees = $db->select(
            "SELECT a.player_id, a.group_id, COUNT(*) as absence_count,
                    p.full_name_ar, p.phone, p.guardian_phone, g.name_ar as group_name
             FROM sa_attendance a
             JOIN sa_players p ON p.id = a.player_id
             JOIN sa_groups g ON g.id = a.group_id
             WHERE a.status = 'absent'
               AND a.attendance_date BETWEEN ? AND ?
             GROUP BY a.player_id, a.group_id, p.full_name_ar, p.phone, p.guardian_phone, g.name_ar
             HAVING COUNT(*) >= ?",
            [$lastMonth, $lastMonthEnd, $threshold]
        );

        foreach ($absentees as $row) {
            EventBus::dispatch('sa.player.absence_threshold', [
                'player_id'     => (int) $row['player_id'],
                'group_id'      => (int) $row['group_id'],
                'player_name'   => $row['full_name_ar'],
                'group_name'    => $row['group_name'],
                'phone'         => $row['guardian_phone'] ?: $row['phone'],
                'absence_count' => (int) $row['absence_count'],
                'threshold'     => $threshold,
                'month'         => date('Y-m', strtotime('-1 month')),
            ]);
            $processed++;
        }

        Logger::info("SA Attendance report: {$processed} players exceeded absence threshold");
        return ['processed' => $processed, 'threshold' => $threshold];
    }
}
