<?php

namespace App\Domain\HR\Listeners;

use App\Domain\Attendance\Events\AttendanceMarked;
use App\Domain\HR\Models\Trainer;
use App\Domain\HR\Services\CompensationCalculatorService;
use App\Domain\Shared\Services\SettingsService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;

class GenerateTrainerCompensation implements ShouldQueue
{
    public function __construct(
        private CompensationCalculatorService $calculator,
        private SettingsService $settings,
    ) {}

    public function handle(AttendanceMarked $event): void
    {
        if (!(bool) $this->settings->get('auto_trainer_compensation_enabled', false)) {
            return;
        }

        try {
            $record = $event->record;

            // Only process trainer attendance (stored as User::class), not participant
            if ($record->subject_type !== \App\Models\User::class) {
                return;
            }

            // Find the trainer by user_id → employee → trainer
            $trainer = Trainer::whereHas('employee', fn ($q) => $q->where('user_id', $record->subject_id))
                ->first();
            if (!$trainer || $trainer->status->value !== 'active') {
                return;
            }

            $actor = $event->actor;
            $status = $record->status->value;

            match ($status) {
                'present' => $this->calculator->calculateForSession(
                    $trainer,
                    $record->training_session_id,
                    $record->id,
                    'present',
                    $actor,
                ),
                'late' => (function () use ($trainer, $record, $actor) {
                    $this->calculator->calculateForSession($trainer, $record->training_session_id, $record->id, 'late', $actor);
                    $this->calculator->calculateLatePenalty($trainer, $record->training_session_id, $record->id, $actor);
                })(),
                'absent', 'no_show' => $this->calculator->calculatePenalty(
                    $trainer,
                    $record->training_session_id,
                    $record->id,
                    $actor,
                ),
                default => null,
            };
        } catch (\Throwable $e) {
            Log::error('GenerateTrainerCompensation failed: ' . $e->getMessage(), [
                'attendance_record_id' => $event->record->id ?? null,
            ]);
        }
    }

    public function failed(AttendanceMarked $event, \Throwable $exception): void
    {
        Log::critical('GenerateTrainerCompensation PERMANENTLY FAILED', [
            'attendance_record_id' => $event->record->id ?? null,
            'error' => $exception->getMessage(),
        ]);
    }
}
