<?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/staff attendance, not participant
            if ($record->subject_type !== 'trainer' && $record->subject_type !== 'staff') {
                return;
            }

            // Find the trainer by subject_id
            $trainer = Trainer::find($record->subject_id);
            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(),
        ]);
    }
}
