<?php

namespace App\Event\Service;

use App\Entity\Account;
use App\Entity\AccountResetPasswordRequest;
use App\Event\Object\EventAdminCreate;
use App\Event\Object\EventAdminDeleted;
use App\Service\Generator\TempPasswordGenerator;
use App\Service\Mailer\Mailer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

#[AsEventListener(event: EventAdminDeleted::class, method: 'onAdminDeleted')]
#[AsEventListener(event: EventAdminCreate::class, method: 'onAdminCreate')]
class AdminEvent
{
    public function __construct(
        private readonly Mailer $mailer,
        private readonly UrlGeneratorInterface $urlGenerator,
        private readonly EntityManagerInterface $entityManager,
    ) {
    }

    public function onAdminCreate(EventAdminCreate $eventAdminCreate): void
    {
        $account = $eventAdminCreate->getAccount();

        // On cherche si une demande existe déjà pour cet utilisateur
        $existingRequest = $this->entityManager->getRepository(AccountResetPasswordRequest::class)
            ->findOneBy(['Account' => $account]);

        $now = new \DateTimeImmutable();
        $sendNewRequest = true;
        $request = null;

        if ($existingRequest instanceof AccountResetPasswordRequest) {
            if ($existingRequest->getExpiresAt() < $now) {
                $this->entityManager->remove($existingRequest);
                $this->entityManager->flush();
            } else {
                $sendNewRequest = false;
                $request = $existingRequest;
            }
        }

        if ($sendNewRequest) {
            $expiredAt = $now->modify('+24 hours'); // On donne 24h pour une création de compte

            $request = new AccountResetPasswordRequest();
            $request->setAccount($account);
            $request->setToken(TempPasswordGenerator::generate(50, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'));
            $request->setRequestedAt($now);
            $request->setExpiresAt($expiredAt);

            $this->entityManager->persist($request);
            $this->entityManager->flush();
        }

        // Génération du lien de confirmation
        $resetLink = $this->urlGenerator->generate(
            'app_forgot_password_confirm',
            ['id' => $account->getId(), 'token' => $request->getToken()],
            UrlGeneratorInterface::ABSOLUTE_URL
        );

        // Envoi du mail de bienvenue / activation
        $this->mailer->send(
            $account->getEmail(),
            $account->getFirstName() . ' ' . $account->getName(),
            "[Intranet Ludikevent] Activation de votre accès administrateur",
            "mails/notification/admin_created.twig",
            [
                'admin'      => $account,
                'creator'    => $eventAdminCreate->getRequestedAccount(),
                'setup_url'  => $resetLink,
                'expires_at' => $request->getExpiresAt(),
            ]
        );
    }

    public function onAdminDeleted(EventAdminDeleted $eventAdminDeleted): void
    {
        $context = [
            'admin' => $eventAdminDeleted->getAccount(),
            'who'   => $eventAdminDeleted->getRequestedAccount(),
            'date'  => new \DateTimeImmutable(),
        ];

        $recipients = [
            'notification@siteconseil.fr' => "Notification Intranet Ludikevent",
            'contact@ludikevent.fr'       => "Notification Intranet Ludikevent"
        ];

        foreach ($recipients as $email => $name) {
            $this->mailer->send(
                $email,
                $name,
                "[Intranet Ludikevent] - Suppression d'un administrateur",
                "mails/notification/admin_deleted.twig",
                $context
            );
        }
    }
}
