<?php

namespace App\Controller;

use App\Entity\User;
use App\Repository\UserRepository;
use App\Form\RegistrationFormType;
use App\Security\EmailVerifier;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mime\Address;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Mailer\MailerInterface;

class RegistrationController extends AbstractController
{
    public function __construct(private EmailVerifier $emailVerifier)
    {
    }

    #[Route('/register', name: 'app_register')]
    public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager, MailerInterface $mailer): Response
    {
        if (strtolower($_ENV['APP_ALLOW_REGISTER']) != "true") {
            $this->addFlash('info', 'Les créations de comptes sont désactivées sur cette plateforme. Contactez les administrateurs.');
            return $this->redirectToRoute('app_main');
        }

        // SI l'utilisateur est déjà connecté, rediriger vers la page d'accueil
        if ($this->getUser()) {
            $this->addFlash('info', 'Vous êtes déjà connecté. Vous ne pouvez pas vous enregistrer à nouveau.');
            return $this->redirectToRoute('app_main');
        }

        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            
            /** @var string $plainPassword */
            $plainPassword = $form->get('plainPassword')->getData();

            // encode the plain password
            $user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword));

            $entityManager->persist($user);
            $entityManager->flush();

            // generate a signed url and email it to the user
            $this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
                (new TemplatedEmail())
                    ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
                    ->to((string) $user->getEmail())
                    ->subject('Merci de confirmer votre adresse email')
                    ->htmlTemplate('registration/confirmation_email.html.twig')
                    ->textTemplate('registration/confirmation_email.txt.twig')
            );
            $email = (new TemplatedEmail())
                ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
                ->to((string) $user->getEmail())
                ->subject('Votre compte a été créé')
                ->htmlTemplate('admin/user/add.email.html.twig')
                ->textTemplate('admin/user/add.email.txt.twig')
                ->context([
                    'user' => $user,
                    'clearPassword' => $plainPassword,
                ]);
            $mailer->send($email);

            // do anything else you need here, like send an email


            $this->addFlash('success', 'Votre compte a été créé avec succès. Veuillez vérifier votre email pour confirmer votre adresse.');
            return $this->redirectToRoute('app_login');
        }

        return $this->render('registration/register.html.twig', [
            'registrationForm' => $form,
        ]);
    }

    #[Route('/verify/resend/{id}', name: 'app_resend_verification_email', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
    public function resendVerificationEmail(User $user, TranslatorInterface $translator): Response
    {
        $this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
            (new TemplatedEmail())
                ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
                ->to((string) $user->getEmail())
                ->subject('Merci de confirmer votre adresse email')
                ->htmlTemplate('registration/confirmation_email.html.twig')
                ->textTemplate('registration/confirmation_email.txt.twig')
        );

        $this->addFlash('success', 'Un nouvel email de confirmation a été envoyé à votre adresse email.');
        return $this->redirectToRoute('app_login');
    }

    #[Route('/admin/user/{id}/resend', name: 'app_admin_user_resend_verification_email', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
    public function adminUserResendVerificationEmail(User $user, TranslatorInterface $translator): Response
    {
        $this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
            (new TemplatedEmail())
                ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
                ->to((string) $user->getEmail())
                ->subject('Merci de confirmer votre adresse email')
                ->htmlTemplate('registration/confirmation_email.html.twig')
                ->textTemplate('registration/confirmation_email.txt.twig')
        );

        $this->addFlash('success', 'Un nouvel email de confirmation a été envoyé à cet utilisateur.');
        return $this->redirectToRoute('app_admin_user');
    }

    #[Route('/verify/email', name: 'app_verify_email')]
    public function verifyUserEmail(Request $request, UserRepository $userRepository, TranslatorInterface $translator): Response
    {
        $id = $request->query->get('id'); // retrieve the user id from the url

        // Verify the user id exists and is not null
        if (null === $id) {
            return $this->redirectToRoute('app_home');
        }

        $user = $userRepository->find($id);

        // Ensure the user exists in persistence
        if (null === $user) {
            return $this->redirectToRoute('app_home');
        }

        // validate email confirmation link, sets User::isVerified=true and persists
        try {

            $this->emailVerifier->handleEmailConfirmation($request, $user);
        } catch (VerifyEmailExceptionInterface $exception) {
            $this->addFlash('verify_email_error', $translator->trans($exception->getReason(), [], 'VerifyEmailBundle'));

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

        // @TODO Change the redirect on success and handle or remove the flash message in your templates
        $this->addFlash('success', 'Votre adresse de courriel a été confirmée.');

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