<?php

namespace App\Modules\HR\Leave\Services;

use App\Models\User;
use App\Modules\HR\Leave\Events\LeaveRequestCancelled;
use App\Modules\HR\Leave\Models\LeaveRequest;
use App\Modules\HR\Leave\Repositories\LeaveRequestRepository;
use App\Modules\HR\Leave\Support\LeaveRequestStatus;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Facades\DB;

class LeaveCancellationService
{
    public function __construct(
        private readonly LeaveRequestRepository $requests,
        private readonly Dispatcher $events,
    ) {}

    public function cancel(LeaveRequest $request, User $actor): LeaveRequest
    {
        return DB::transaction(function () use ($request, $actor): LeaveRequest {
            $locked = $this->requests->lockForTenant((int) $request->tenant_id, (int) $request->id);
            if ($locked === null) {
                abort(404);
            }
            if (! in_array($locked->status, [
                LeaveRequestStatus::PENDING,
                LeaveRequestStatus::MANAGER_APPROVED,
            ], true)) {
                return $locked;
            }
            $updated = $this->requests->update($locked, [
                'status' => LeaveRequestStatus::CANCELLED,
            ]);
            DB::afterCommit(function () use ($updated, $actor): void {
                $this->events->dispatch(new LeaveRequestCancelled($updated, $actor->id));
            });

            return $updated;
        });
    }
}
