<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CmsBundle\EventListener\Security;

use Doctrine\ORM\EntityManagerInterface;
use Ferienpass\CoreBundle\Entity\User;
use Ferienpass\CoreBundle\Repository\AttendanceRepository;
use Ferienpass\CoreBundle\Ux\Flash;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;

#[AsEventListener(dispatcher: 'security.event_dispatcher.contao_frontend')]
class LoginSuccessListener
{
    public function __construct(
        private readonly AttendanceRepository $attendanceRepository,
        private readonly UrlGeneratorInterface $urlGenerator,
        private readonly EntityManagerInterface $entityManager,
    ) {
    }

    public function __invoke(LoginSuccessEvent $event): void
    {
        $user = $event->getAuthenticatedToken()->getUser();
        if (!$user instanceof User) {
            return;
        }

        // SECURITY_REVIEW FP-028: The frontend login_link signature covers
        // [email, lastLogin], but lastLogin was never written, so issued magic
        // links never auto-invalidated on the next sign-in. Stamp lastLogin on
        // every successful frontend authentication. The signature for the link
        // used in *this* request was computed against the previous lastLogin and
        // is checked before this listener runs, so the current login succeeds
        // while any previously issued link is invalidated for future use.
        $user->setLastLogin(new \DateTimeImmutable());
        $this->entityManager->flush();

        if (!$this->attendanceRepository->hasOutstandingConsentsForUser($user)) {
            return;
        }

        $href = $this->urlGenerator->generate('cms', [
            'to' => 'user_account',
            'alias' => 'einwilligungen',
        ]);

        $event->getRequest()->getSession()->getFlashBag()->add(
            ...Flash::warningModal()
                ->headline('Einwilligungen ausstehend')
                ->text('Für eine oder mehrere Anmeldungen fehlen noch Einwilligungen.')
                ->href($href)
                ->linkText('Einwilligungen jetzt unterzeichnen')
                ->create()
        );
    }
}
