<?php

namespace App\Controller;

use App\Entity\User;
use App\Service\MailerService;
use App\Service\MeilisearchService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class RegistrationController extends AbstractController
{
    private const BREADCRUMB_HOME = ['name' => 'Accueil', 'url' => '/'];
    private const BREADCRUMB_REGISTER = ['name' => 'Inscription', 'url' => '/inscription'];

    #[Route('/inscription', name: 'app_register', methods: ['GET', 'POST'])]
    public function register(
        Request $request,
        UserPasswordHasherInterface $passwordHasher,
        EntityManagerInterface $em,
        ValidatorInterface $validator,
        MailerService $mailerService,
    ): Response {
        if ($this->getUser()) {
            return $this->redirectToRoute('app_account');
        }

        if ($request->isMethod('POST')) {
            $type = $request->request->getString('type');
            $user = new User();
            $user->setFirstName(trim($request->request->getString('first_name')));
            $user->setLastName(trim($request->request->getString('last_name')));
            $user->setEmail(trim($request->request->getString('email')));

            $plainPassword = $request->request->getString('password');
            $user->setPassword($passwordHasher->hashPassword($user, $plainPassword));

            if ('organizer' === $type) {
                $user->setRoles(['ROLE_ORGANIZER']);
                $user->setCompanyName(trim($request->request->getString('company_name')));
                $user->setSiret(trim($request->request->getString('siret')));
                $user->setAddress(trim($request->request->getString('address')));
                $user->setPostalCode(trim($request->request->getString('postal_code')));
                $user->setCity(trim($request->request->getString('city')));
                $user->setPhone(trim($request->request->getString('phone')));
                $user->setBillingState('poor');
            }

            $token = bin2hex(random_bytes(32));
            $user->setEmailVerificationToken($token);

            $errors = $validator->validate($user);
            if (0 === count($errors)) {
                $em->persist($user);
                $em->flush();

                $verificationUrl = $this->generateUrl('app_verify_email', [
                    'token' => $token,
                ], UrlGeneratorInterface::ABSOLUTE_URL);

                $html = $this->renderView('email/verification.html.twig', [
                    'firstName' => $user->getFirstName(),
                    'verificationUrl' => $verificationUrl,
                ]);

                $mailerService->sendEmail(
                    to: $user->getEmail(),
                    subject: 'Verifiez votre adresse email - E-Ticket',
                    content: $html,
                    withUnsubscribe: false,
                );

                return $this->render('security/register_success.html.twig', [
                    'isOrganizer' => 'organizer' === $type,
                    'breadcrumbs' => [
                        self::BREADCRUMB_HOME,
                        self::BREADCRUMB_REGISTER,
                        ['name' => 'Compte cree', 'url' => self::BREADCRUMB_REGISTER['url']],
                    ],
                ]);
            }

            foreach ($errors as $error) {
                $this->addFlash('error', $error->getMessage());
            }
        }

        return $this->render('security/register.html.twig', [
            'breadcrumbs' => [
                self::BREADCRUMB_HOME,
                self::BREADCRUMB_REGISTER,
            ],
        ]);
    }

    #[Route('/verification-email/{token}', name: 'app_verify_email')]
    public function verifyEmail(string $token, EntityManagerInterface $em, MailerService $mailerService, MeilisearchService $meilisearch): Response
    {
        $user = $em->getRepository(User::class)->findOneBy(['emailVerificationToken' => $token]);

        if (!$user) {
            $this->addFlash('error', 'Lien de verification invalide ou expire.');

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

        $user->setIsVerified(true);
        $user->setEmailVerifiedAt(new \DateTimeImmutable());
        $user->setEmailVerificationToken(null);
        $em->flush();

        if (!\in_array('ROLE_ORGANIZER', $user->getRoles(), true)) {
            $meilisearch->createIndexIfNotExists('buyers');
            $meilisearch->addDocuments('buyers', [[
                'id' => $user->getId(),
                'firstName' => $user->getFirstName(),
                'lastName' => $user->getLastName(),
                'email' => $user->getEmail(),
                'createdAt' => $user->getCreatedAt()->format('d/m/Y'),
            ]]);
        }

        if (\in_array('ROLE_ORGANIZER', $user->getRoles(), true)) {
            $mailerService->sendEmail(
                to: $user->getEmail(),
                subject: 'Votre compte organisateur est en cours d\'examen - E-Ticket',
                content: $this->renderView('email/organizer_pending.html.twig', [
                    'firstName' => $user->getFirstName(),
                ]),
                withUnsubscribe: false,
            );

            $mailerService->sendEmail(
                to: $this->getParameter('admin_email'),
                subject: sprintf('Nouvelle demande organisateur : %s %s', $user->getFirstName(), $user->getLastName()),
                content: $this->renderView('email/organizer_request.html.twig', [
                    'firstName' => $user->getFirstName(),
                    'lastName' => $user->getLastName(),
                    'email' => $user->getEmail(),
                    'companyName' => $user->getCompanyName(),
                    'siret' => $user->getSiret(),
                    'address' => $user->getAddress(),
                    'postalCode' => $user->getPostalCode(),
                    'city' => $user->getCity(),
                    'phone' => $user->getPhone(),
                ]),
                withUnsubscribe: false,
            );
        }

        return $this->render('security/email_verified.html.twig', [
            'isOrganizer' => \in_array('ROLE_ORGANIZER', $user->getRoles(), true),
            'breadcrumbs' => [
                ['name' => 'Accueil', 'url' => '/'],
                ['name' => 'Email verifie', 'url' => '/verification-email/'.$token],
            ],
        ]);
    }
}
