<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Notification\Email\NotificationEmailHandlers;

use Chill\MainBundle\Notification\Email\NotificationEmailMessages\SendImmediateNotificationEmailMessage;
use Chill\MainBundle\Notification\Email\NotificationMailer;
use Chill\MainBundle\Repository\NotificationRepository;
use Chill\MainBundle\Repository\UserGroupRepository;
use Chill\MainBundle\Repository\UserRepositoryInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
readonly class SendImmediateNotificationEmailHandler
{
    public function __construct(
        private NotificationRepository $notificationRepository,
        private UserRepositoryInterface $userRepository,
        private UserGroupRepository $userGroupRepository,
        private NotificationMailer $notificationMailer,
        private LoggerInterface $logger,
    ) {}

    /**
     * @throws TransportExceptionInterface
     * @throws \Exception
     */
    public function __invoke(SendImmediateNotificationEmailMessage $message): void
    {
        $notification = $this->notificationRepository->find($message->getNotificationId());
        if (null !== $message->getUserId()) {
            $addressee = $this->userRepository->find($message->getUserId());
        } elseif (null !== $message->getUserGroupId()) {
            $addressee = $this->userGroupRepository->find($message->getUserGroupId());
        } else {
            throw new \InvalidArgumentException('Addressee not found: nor an user nor a user group');
        }

        if (null === $notification) {
            $this->logger->error('[SendImmediateNotificationEmailHandler] Notification not found', [
                'notification_id' => $message->getNotificationId(),
            ]);

            throw new \InvalidArgumentException(sprintf('Notification with ID %s not found', $message->getNotificationId()));
        }

        if (null === $addressee) {
            $this->logger->error('[SendImmediateNotificationEmailHandler] Addressee not found', [
                'user_id' => $message->getUserId(),
                'user_group_id' => $message->getUserGroupId(),
            ]);

            throw new \InvalidArgumentException(sprintf('User with ID %s or user group with id %s not found', $message->getUserId(), $message->getUserGroupId()));
        }

        try {
            $this->notificationMailer->sendEmailToAddressee($notification, $addressee);
        } catch (\Exception $e) {
            $this->logger->error('[SendImmediateNotificationEmailHandler] Failed to send email', [
                'notification_id' => $message->getNotificationId(),
                'user_id' => $message->getUserId(),
                'user_group_id' => $message->getUserGroupId(),
                'stacktrace' => $e->getTraceAsString(),
            ]);
            throw $e;
        }
    }
}
