<?php

namespace App\Console\Commands;

use App\Domain\Attendance\Enums\AttendanceStatus;
use App\Domain\Attendance\Models\AttendanceRecord;
use App\Domain\Participant\Models\Participant;
use App\Domain\Shared\Services\SettingsService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class EnforceAttendanceThresholds extends Command
{
    protected $signature = 'attendance:enforce-thresholds';
    protected $description = 'Check attendance thresholds and auto-suspend if exceeded';

    private const DEFAULT_MAX_CONSECUTIVE_ABSENCES = 5;
    private const DEFAULT_MIN_ATTENDANCE_PERCENT = 75;

    public function handle(SettingsService $settings): int
    {
        if (!(bool) $settings->get('auto_suspend_on_threshold', false)) {
            $this->info('Auto-suspend is disabled (auto_suspend_on_threshold = false). Skipping.');
            return self::SUCCESS;
        }

        $this->checkConsecutiveAbsences();
        $this->checkAttendancePercentage();

        return self::SUCCESS;
    }

    private function checkConsecutiveAbsences(): void
    {
        $maxAbsences = self::DEFAULT_MAX_CONSECUTIVE_ABSENCES;

        $participants = Participant::where('status', 'active')->get();

        foreach ($participants as $participant) {
            $recentRecords = AttendanceRecord::where('subject_type', Participant::class)
                ->where('subject_id', $participant->id)
                ->whereHas('session', fn ($q) => $q->orderByDesc('session_date'))
                ->orderByDesc('created_at')
                ->limit($maxAbsences)
                ->pluck('status');

            if ($recentRecords->count() < $maxAbsences) {
                continue;
            }

            $allAbsent = $recentRecords->every(fn ($s) =>
                in_array($s instanceof AttendanceStatus ? $s->value : $s, ['absent', 'no_show'])
            );

            if ($allAbsent) {
                $participant->update([
                    'status' => 'suspended',
                    'status_reason' => __('تعليق تلقائي: :count غيابات متتالية', ['count' => $maxAbsences]),
                    'status_changed_at' => now(),
                ]);

                Log::warning("Participant #{$participant->id} auto-suspended: {$maxAbsences} consecutive absences");
                $this->warn(__('تم تعليق المشترك #:id (:name)', [
                    'id' => $participant->id,
                    'name' => $participant->person?->name_ar ?? '-',
                ]));
            }
        }
    }

    private function checkAttendancePercentage(): void
    {
        $minPercent = self::DEFAULT_MIN_ATTENDANCE_PERCENT;

        $participants = Participant::where('status', 'active')->get();

        foreach ($participants as $participant) {
            $total = AttendanceRecord::where('subject_type', Participant::class)
                ->where('subject_id', $participant->id)
                ->count();

            if ($total < 10) {
                continue; // Not enough data
            }

            $excluded = AttendanceRecord::where('subject_type', Participant::class)
                ->where('subject_id', $participant->id)
                ->whereIn('status', [AttendanceStatus::Cancelled, AttendanceStatus::Exempt])
                ->count();

            $denominator = $total - $excluded;
            if ($denominator <= 0) {
                continue;
            }

            $positive = AttendanceRecord::where('subject_type', Participant::class)
                ->where('subject_id', $participant->id)
                ->whereIn('status', [AttendanceStatus::Present, AttendanceStatus::Late, AttendanceStatus::Partial])
                ->count();

            $rate = round(($positive / $denominator) * 100, 1);

            if ($rate < $minPercent) {
                Log::info("Participant #{$participant->id} attendance below threshold: {$rate}% < {$minPercent}%");
                $this->info(__('نسبة حضور منخفضة: المشترك #:id بنسبة :rate%', [
                    'id' => $participant->id,
                    'rate' => $rate,
                ]));
            }
        }
    }
}
