<?php

declare(strict_types=1);

namespace App\Service\Notification;

use App\Entity\Notification;
use App\Repository\EmployeeContractPeriodRepository;
use App\Repository\NotificationRepository;
use App\Repository\UserRepository;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;

use function count;

final readonly class ContractEndNotificationService
{
    private const CATEGORY = 'Contrat';

    public function __construct(
        private EmployeeContractPeriodRepository $periodRepository,
        private NotificationRepository $notificationRepository,
        private UserRepository $userRepository,
        private ContractEndNotificationPlanner $planner,
        private EntityManagerInterface $entityManager,
    ) {}

    public function run(DateTimeImmutable $today): ContractEndNotificationResult
    {
        $latestPeriods = $this->periodRepository->findLatestPeriodsForAllEmployees();
        $notices       = $this->planner->plan($latestPeriods, $today);

        if ([] === $notices) {
            return new ContractEndNotificationResult(0, 0);
        }

        $admins  = $this->userRepository->findAllAdmins();
        $created = 0;

        foreach ($notices as $notice) {
            if (null === $notice->employeeId) {
                continue;
            }

            $target = '/employees/'.$notice->employeeId;

            foreach ($admins as $admin) {
                if ($this->notificationRepository->existsForRecipientCategoryTargetMessage(
                    $admin,
                    self::CATEGORY,
                    $target,
                    $notice->message,
                )) {
                    continue;
                }

                $notification = new Notification();
                $notification->setRecipient($admin)
                    ->setMessage($notice->message)
                    ->setCategory(self::CATEGORY)
                    ->setTarget($target)
                ;

                $this->entityManager->persist($notification);
                ++$created;
            }
        }

        $this->entityManager->flush();

        return new ContractEndNotificationResult($created, count($notices));
    }
}
