<?php

namespace App\Modules\HR\Overtime\Listeners;

use App\Models\User;
use App\Modules\HR\Overtime\Events\OvertimeRequestApproved;
use App\Modules\HR\Overtime\Events\OvertimeRequestRejected;
use App\Modules\HR\Overtime\Events\OvertimeRequestSubmitted;
use App\Modules\HR\Overtime\Models\OvertimeRequest;
use App\Modules\HR\Overtime\Notifications\OvertimeRequestResolvedNotification;
use App\Modules\HR\Overtime\Notifications\OvertimeRequestSubmittedNotification;
use Illuminate\Support\Facades\Notification as NotificationFacade;

class OvertimeNotificationListener
{
    public function handleSubmitted(OvertimeRequestSubmitted $event): void
    {
        $recipients = $this->reviewers((int) $event->overtimeRequest->tenant_id);
        if ($recipients->isNotEmpty()) {
            NotificationFacade::send(
                $recipients,
                new OvertimeRequestSubmittedNotification($event->overtimeRequest),
            );
        }
    }

    public function handleApproved(OvertimeRequestApproved $event): void
    {
        $this->notifyEmployee($event->overtimeRequest, 'approved');
    }

    public function handleRejected(OvertimeRequestRejected $event): void
    {
        $this->notifyEmployee($event->overtimeRequest, 'rejected');
    }

    private function notifyEmployee(OvertimeRequest $request, string $resolution): void
    {
        $request->loadMissing('employee.user');
        $user = $request->employee?->user;
        if (! $user instanceof User) {
            return;
        }
        $user->notify(new OvertimeRequestResolvedNotification($request, $resolution));
    }

    /**
     * @return \Illuminate\Support\Collection<int, User>
     */
    private function reviewers(int $tenantId)
    {
        return User::query()
            ->where('tenant_id', $tenantId)
            ->where('is_admin', false)
            ->get()
            ->filter(fn (User $u): bool => $u->can('overtime.review'));
    }
}
