<?php

namespace App\Domain\HR\Listeners;

use App\Domain\Training\Events\SessionCancelled;
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 HandleSessionCancelled implements ShouldQueue
{
    public function __construct(
        private CompensationCalculatorService $calculator,
        private SettingsService $settings,
    ) {}

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

        try {
            $session = $event->session;

            // Find user_ids assigned to this session or its group via polymorphic assignments
            $userIds = \App\Domain\Scheduling\Models\Assignment::where(function ($q) use ($session) {
                $q->where(function ($q2) use ($session) {
                    $q2->where('assignable_type', \App\Domain\Training\Models\TrainingSession::class)
                        ->where('assignable_id', $session->id);
                })->orWhere(function ($q2) use ($session) {
                    $q2->where('assignable_type', \App\Domain\Training\Models\TrainingGroup::class)
                        ->where('assignable_id', $session->training_group_id);
                });
            })
                ->where('status', 'active')
                ->pluck('user_id')
                ->unique();

            // Resolve trainers from user_ids via their employee records
            $trainers = Trainer::whereHas('employee', function ($q) use ($userIds) {
                $q->whereIn('user_id', $userIds);
            })->where('status', 'active')->get();

            foreach ($trainers as $trainer) {
                $this->calculator->calculateCancelledSessionPay(
                    $trainer,
                    $session->id,
                    $event->actor,
                );
            }
        } catch (\Throwable $e) {
            Log::error('HandleSessionCancelled compensation failed: ' . $e->getMessage(), [
                'session_id' => $event->session->id ?? null,
            ]);
        }
    }

    public function failed(SessionCancelled $event, \Throwable $exception): void
    {
        Log::critical('HandleSessionCancelled PERMANENTLY FAILED', [
            'session_id' => $event->session->id ?? null,
            'error' => $exception->getMessage(),
        ]);
    }
}
