<?php

namespace App\Modules\HR\PermissionRequests\Listeners;

use App\Models\User;
use App\Modules\HR\PermissionRequests\Events\PermissionRequestApproved;
use App\Modules\HR\PermissionRequests\Events\PermissionRequestRejected;
use App\Modules\HR\PermissionRequests\Events\PermissionRequestSubmitted;
use App\Modules\HR\PermissionRequests\Models\PermissionRequest;
use App\Modules\HR\PermissionRequests\Notifications\PermissionRequestApprovedNotification;
use App\Modules\HR\PermissionRequests\Notifications\PermissionRequestRejectedNotification;
use App\Modules\HR\PermissionRequests\Notifications\PermissionRequestSubmittedNotification;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Notification as NotificationFacade;

class PermissionRequestNotificationListener
{
    public function handleSubmitted(PermissionRequestSubmitted $event): void
    {
        $recipients = $this->reviewers((int) $event->permissionRequest->tenant_id);
        if ($recipients->isNotEmpty()) {
            NotificationFacade::send(
                $recipients,
                new PermissionRequestSubmittedNotification($event->permissionRequest),
            );
        }
    }

    public function handleApproved(PermissionRequestApproved $event): void
    {
        $this->notifyEmployeeAndRequester(
            $event->permissionRequest,
            new PermissionRequestApprovedNotification($event->permissionRequest),
        );
    }

    public function handleRejected(PermissionRequestRejected $event): void
    {
        $this->notifyEmployeeAndRequester(
            $event->permissionRequest,
            new PermissionRequestRejectedNotification($event->permissionRequest),
        );
    }

    private function notifyEmployeeAndRequester(PermissionRequest $request, Notification $notification): void
    {
        $request->loadMissing('employee.user');
        $targets = collect();
        $employeeUser = $request->employee?->user;
        if ($employeeUser instanceof User) {
            $targets->push($employeeUser);
        }
        if ($request->requested_by !== null) {
            $u = User::query()->find((int) $request->requested_by);
            if ($u !== null) {
                $targets->push($u);
            }
        }
        $unique = $targets->unique('id')->values();
        if ($unique->isNotEmpty()) {
            NotificationFacade::send($unique, $notification);
        }
    }

    /**
     * @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('permission_requests.review'));
    }
}
