<?php

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Controller\Site;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Security\AccountActivationService;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Security\PasswordResetService;
use CpCreation\VitiCore\User\Repository\UserRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class LoginController extends AbstractController
{
    public function __construct(
        private readonly RequestStack $requestStack,
    ) {
    }

    #[Route(path: [
        'fr' => '/connexion',
        'en' => '/en/login',
        'de' => '/de/anmelden',
        'nl' => '/nl/inloggen',
        'it' => '/it/accesso',
        'es' => '/es/iniciar-sesion',
    ], name: 'app_login')]
    public function index(): Response
    {
        if (null !== $this->getUser()) {
            return $this->redirectToRoute('app_account');
        }

        return $this->render('security/login.html.twig', [
        ]);
    }

    #[Route(path: [
        'fr' => '/mot-de-passe-oublie',
        'en' => '/en/forgot-password',
        'de' => '/de/passwort-vergessen',
        'nl' => '/nl/wachtwoord-vergeten',
        'it' => '/it/password-dimenticata',
        'es' => '/es/contrasena-olvidada',
    ], name: 'app_forgot_password')]
    public function forgotPassword(): Response
    {
        return $this->render('security/forgot_password.html.twig');
    }

    #[Route(path: [
        'fr' => '/mot-de-passe-oublie/email-envoye',
        'en' => '/en/forgot-password/email-sent',
        'de' => '/de/passwort-vergessen/e-mail-gesendet',
        'nl' => '/nl/wachtwoord-vergeten/e-mail-verzonden',
        'it' => '/it/password-dimenticata/email-inviata',
        'es' => '/es/contrasena-olvidada/email-enviado',
    ], name: 'app_forgot_password_pending')]
    public function forgotPasswordPending(): Response
    {
        $session = $this->requestStack->getCurrentRequest()?->getSession();

        return $this->render('security/forgot_password_pending.html.twig', [
            'reset_pending_email' => $session?->get('security.reset_pending.email'),
        ]);
    }

    #[Route(path: [
        'fr' => '/connexion/creation-compte',
        'en' => '/en/register/create-account',
        'de' => '/de/anmelden/konto-erstellen',
        'nl' => '/nl/inloggen/account-aanmaken',
        'it' => '/it/accesso/crea-account',
        'es' => '/es/iniciar-sesion/crear-cuenta',
    ], name: 'app_register_confirm')]
    public function registerConfirm(): Response|RedirectResponse
    {
        $session = $this->requestStack->getCurrentRequest()?->getSession();
        $email = $session?->get('security.register.email');

        if (!\is_string($email) || '' === mb_trim($email)) {
            return $this->redirectToRoute('app_login');
        }

        return $this->render('security/register_confirm.html.twig', [
            'pending_email' => $email,
            'pending_marketing_opt_in' => (bool) $session?->get('security.register.marketing_opt_in', false),
        ]);
    }

    #[Route(path: [
        'fr' => '/connexion/activation-en-attente',
        'en' => '/en/login/activation-pending',
        'de' => '/de/anmelden/aktivierung-ausstehend',
        'nl' => '/nl/inloggen/activatie-in-afwachting',
        'it' => '/it/accesso/attivazione-in-attesa',
        'es' => '/es/iniciar-sesion/activacion-pendiente',
    ], name: 'app_register_pending')]
    public function registerPending(): Response
    {
        $session = $this->requestStack->getCurrentRequest()?->getSession();

        return $this->render('security/register_pending.html.twig', [
            'activation_pending_email' => $session?->get('security.activation_pending.email'),
        ]);
    }

    #[Route(path: [
        'fr' => '/connexion/activation/{token}',
        'en' => '/en/login/activate/{token}',
        'de' => '/de/anmelden/aktivieren/{token}',
        'nl' => '/nl/inloggen/activeren/{token}',
        'it' => '/it/accesso/attiva/{token}',
        'es' => '/es/iniciar-sesion/activar/{token}',
    ], name: 'app_verify_account')]
    public function verifyAccount(
        string $token,
        UserRepository $userRepository,
        AccountActivationService $accountActivationService,
    ): RedirectResponse {
        $user = $userRepository->findOneBy(['emailVerificationToken' => $token]);

        if (null === $user) {
            $this->addFlash('error', 'Ce lien d’activation est invalide.');

            return $this->redirectToRoute('app_login');
        }

        if ($user->isVerified()) {
            $this->addFlash('success', 'Votre compte est deja active.');

            return $this->redirectToRoute('app_login');
        }

        if ($accountActivationService->isVerificationExpired($user)) {
            $this->addFlash('error', 'Ce lien d’activation a expire. Reconnectez-vous pour recevoir un nouveau lien.');

            return $this->redirectToRoute('app_login');
        }

        $accountActivationService->verify($user);
        $this->addFlash('success', 'Votre compte est maintenant active. Vous pouvez vous connecter.');

        return $this->redirectToRoute('app_login');
    }

    #[Route(path: [
        'fr' => '/mot-de-passe-oublie/reinitialisation/{token}',
        'en' => '/en/forgot-password/reset/{token}',
        'de' => '/de/passwort-vergessen/zuruecksetzen/{token}',
        'nl' => '/nl/wachtwoord-vergeten/herstellen/{token}',
        'it' => '/it/password-dimenticata/reimposta/{token}',
        'es' => '/es/contrasena-olvidada/restablecer/{token}',
    ], name: 'app_reset_password')]
    public function resetPassword(
        string $token,
        UserRepository $userRepository,
        PasswordResetService $passwordResetService,
    ): Response|RedirectResponse {
        $user = $userRepository->findOneBy(['resetPasswordToken' => $token]);

        if (null === $user) {
            $this->addFlash('error', 'Ce lien de réinitialisation est invalide.');

            return $this->redirectToRoute('app_forgot_password');
        }

        if ($passwordResetService->isExpired($user)) {
            $this->addFlash('error', 'Ce lien de réinitialisation a expiré.');

            return $this->redirectToRoute('app_forgot_password');
        }

        return $this->render('security/reset_password.html.twig', [
            'user' => $user,
            'token' => $token,
        ]);
    }
}
