<?php

namespace App\Actions\Events;

use App\Enums\RegistrationStatus;
use App\Events\RegistrationStatusChanged;
use App\Models\EventRegistration;
use App\Models\User;
use App\Services\AuditLogger;
use App\Services\RegistrationStatusService;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;

class ApproveRegistrationAction
{
    public function __construct(
        private RegistrationStatusService $registrationStatus,
        private AuditLogger $auditLogger,
    ) {}

    public function execute(EventRegistration $registration, User $admin, ?string $reason = null): EventRegistration
    {
        return DB::transaction(function () use ($registration, $admin, $reason) {
            if ($registration->status !== RegistrationStatus::Pending) {
                throw new InvalidArgumentException(__('events.errors.invalid_status'));
            }

            if (! $this->registrationStatus->hasCapacity($registration->event)) {
                throw new InvalidArgumentException(__('events.registration.capacity_full'));
            }

            $oldStatus = $registration->status;

            $this->registrationStatus->record(
                $registration,
                RegistrationStatus::Confirmed,
                $oldStatus,
                $admin,
                $reason,
            );

            $registration->update([
                'confirmed_at' => now(),
                'reviewed_by' => $admin->id,
                'reviewed_at' => now(),
            ]);

            $this->auditLogger->log('registration.approved', $registration, ['status' => $oldStatus->value], ['status' => RegistrationStatus::Confirmed->value]);

            event(new RegistrationStatusChanged(
                registration: $registration->fresh(['event', 'user']),
                previousStatus: $oldStatus,
            ));

            return $registration->fresh(['event', 'user']);
        });
    }
}
