<?php

namespace App\Domain\Scheduling\Listeners;

use App\Domain\Attendance\Enums\AttendanceStatus;
use App\Domain\Attendance\Models\AttendanceRecord;
use App\Domain\Scheduling\Events\AssignmentCreated;
use App\Domain\Shared\Services\SettingsService;
use App\Domain\Training\Models\TrainingGroup;
use App\Domain\Training\Models\TrainingSession;
use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;

class GenerateTrainerAttendance implements ShouldQueue
{
    public function __construct(
        private SettingsService $settings,
    ) {}

    public function handle(AssignmentCreated $event): void
    {
        if (!(bool) $this->settings->get('trainer_attendance_tracking_enabled', true)) {
            return;
        }

        try {
            $assignment = $event->assignment;

            // Only process active assignments
            if (!$assignment->isActive()) {
                return;
            }

            // Determine the group to generate attendance for
            $groupId = null;

            if ($assignment->assignable_type === TrainingGroup::class) {
                $groupId = $assignment->assignable_id;
            } elseif ($assignment->assignable_type === TrainingSession::class) {
                // Single session assignment — generate for just that session
                $session = TrainingSession::find($assignment->assignable_id);
                if ($session && $session->session_date >= now()->toDateString()) {
                    $this->createIfNotExists($session, $assignment->user_id, $session->academy_id);
                }
                return;
            }

            if (!$groupId) {
                return;
            }

            // Generate 'expected' records for all FUTURE sessions of the group
            $futureSessions = TrainingSession::where('training_group_id', $groupId)
                ->where('session_date', '>=', now()->toDateString())
                ->whereIn('status', ['scheduled', 'in_progress'])
                ->get();

            foreach ($futureSessions as $session) {
                $this->createIfNotExists($session, $assignment->user_id, $session->academy_id);
            }
        } catch (\Throwable $e) {
            Log::error('GenerateTrainerAttendance failed: ' . $e->getMessage(), [
                'assignment_id' => $event->assignment->id,
            ]);
        }
    }

    private function createIfNotExists(TrainingSession $session, int $userId, int $academyId): void
    {
        $exists = AttendanceRecord::where('training_session_id', $session->id)
            ->where('subject_type', User::class)
            ->where('subject_id', $userId)
            ->exists();

        if ($exists) {
            return;
        }

        AttendanceRecord::create([
            'academy_id' => $academyId,
            'training_session_id' => $session->id,
            'subject_type' => User::class,
            'subject_id' => $userId,
            'status' => AttendanceStatus::Expected->value,
            'is_auto_generated' => true,
        ]);
    }

    public function failed(AssignmentCreated $event, \Throwable $exception): void
    {
        Log::critical('GenerateTrainerAttendance PERMANENTLY FAILED', [
            'assignment_id' => $event->assignment->id,
            'error' => $exception->getMessage(),
        ]);
    }
}
