<?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\ScheduleDailyNotificationDigestMessage;
use Chill\MainBundle\Notification\Email\NotificationMailer;
use Chill\MainBundle\Repository\NotificationRepository;
use Chill\MainBundle\Repository\UserRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;

#[AsMessageHandler]
readonly class ScheduleDailyNotificationDigestHandler
{
    public function __construct(
        private NotificationRepository $notificationRepository,
        private UserRepository $userRepository,
        private NotificationMailer $notificationMailer,
        private LoggerInterface $logger,
    ) {}

    /**
     * @throws TransportExceptionInterface
     */
    public function __invoke(ScheduleDailyNotificationDigestMessage $message): void
    {
        $userId = $message->getUserId();
        $lastExecutionDate = $message->getLastExecutionDateTime();
        $currentDate = $message->getCurrentDateTime();

        $user = $this->userRepository->find($userId);
        if (null === $user) {
            $this->logger->warning('[ScheduleDailyNotificationDigestHandler] User not found', [
                'user_id' => $userId,
            ]);

            throw new \InvalidArgumentException(sprintf('User with ID %s not found', $userId));
        }

        // Get all notifications for this user between last execution and current date
        $notifications = $this->notificationRepository->findNotificationsForUserBetweenDates(
            $userId,
            $lastExecutionDate,
            $currentDate
        );

        // Filter out notifications that should be sent in a daily digest
        $dailyNotifications = array_filter($notifications, fn ($notification) => $user->isNotificationDailyDigest($notification->getType()));

        if ([] === $dailyNotifications) {
            $this->logger->info('[ScheduleDailyNotificationDigestHandler] No daily notifications found for user', [
                'user_id' => $userId,
            ]);

            return;
        }

        $this->notificationMailer->sendDailyDigest($user, $dailyNotifications);

        $this->logger->info('[ScheduleDailyNotificationDigestHandler] Sent daily digest', [
            'user_id' => $userId,
            'notification_count' => count($dailyNotifications),
        ]);
    }
}
