<?php

namespace MintyPHP\Module\Notifications\Listeners;

use MintyPHP\App\Module\Contracts\EventListener;
use MintyPHP\Module\Notifications\Service\NotificationMessage;
use MintyPHP\Module\Notifications\Service\NotificationService;
use MintyPHP\Repository\User\UserReadRepositoryInterface;
use MintyPHP\Repository\Tenant\UserTenantRepositoryInterface;
use MintyPHP\Service\Access\PermissionService;

final class SchedulerJobFailedNotificationListener implements EventListener
{
    public function __construct(
        private readonly NotificationService $notificationService,
        private readonly UserReadRepositoryInterface $userReadRepository,
        private readonly UserTenantRepositoryInterface $userTenantRepository
    ) {
    }

    public function handle(string $event, array $payload): void
    {
        $jobKey = trim((string) ($payload['job_key'] ?? ''));
        $jobId = (int) ($payload['job_id'] ?? 0);
        $label = trim((string) ($payload['label'] ?? ''));
        $errorCode = trim((string) ($payload['error_code'] ?? ''));

        if ($jobKey === '' || $jobId <= 0) {
            return;
        }

        $displayLabel = $label !== '' ? $label : $jobKey;

        $adminUserIds = $this->userReadRepository->listPrivilegedUserIdsByPermissionKeys(
            [PermissionService::JOBS_MANAGE]
        );
        if ($adminUserIds === []) {
            return;
        }
        $adminSet = array_flip($adminUserIds);

        $titleParams = [$displayLabel];
        $bodyParams = $errorCode !== '' ? [$errorCode] : [];

        $message = NotificationMessage::localized(
            'scheduler.job_failed',
            'Scheduled job failed: %s',
            $titleParams,
            $errorCode !== '' ? 'Error: %s' : null,
            $bodyParams,
            'admin/scheduled-jobs',
            [
                'job_id' => $jobId,
                'job_key' => $jobKey,
                'error_code' => $errorCode,
                'dedupe_target' => 'job:' . $jobKey,
            ]
        );

        // Create notifications directly per admin user + tenant.
        // This avoids listActiveUserIdsByTenantId which requires a web-context
        // DB session — the scheduler runs in CLI where that lookup may fail.
        foreach ($adminUserIds as $userId) {
            $tenantIds = $this->userTenantRepository->listTenantIdsByUserId($userId);
            if ($tenantIds === []) {
                $this->notificationService->createFromMessage($userId, null, $message);
                continue;
            }
            foreach ($tenantIds as $tenantId) {
                $this->notificationService->createFromMessage($userId, $tenantId, $message);
            }
        }
    }
}
