<?php

namespace App\Controller\Admin;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Routing\Attribute\Route;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use App\Security\EmailVerifier;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\String\Slugger\AsciiSlugger;

use App\Entity\User;
use App\Entity\Gamemaster;
use App\Form\UserType;
use App\Repository\UserRepository;
use App\Repository\GamemasterRepository;

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

    /*
     * Lister tous les utilisateurs
     */
    #[Route('/admin/user', name: 'app_admin_user', methods: ['GET'])]
    public function index(UserRepository $repository): Response
    {
        // Extraire l'ensemble des utilisateurs
       $users = $repository->findAll(); 

        // Retourner la page
        return $this->render('admin/user/index.html.twig', [
            'users' => $users,
        ]);
    }

    /*
     * Supprimer un utilisateur
     */
    #[Route('/admin/user/{id}/delete', name: 'app_admin_user_delete', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
    public function delete(?User $user, EntityManagerInterface $manager): Response
    {
        if (!$user) {
            $this->addFlash('danger', 'Aucun utilisateur sélectionné.');
            return $this->redirectToRoute('app_admin_user');
        }
        // Si MJ, supprimer le lien avant de supprimer
        if ($user->getLinkToGamemaster()) {
            $user->setLinkToGamemaster(null);
            $manager->persist($user);
        }

        $manager->remove($user);
        $manager->flush();
        $this->addFlash('success', 'Utilisateur supprimé avec succès.');
        return $this->redirectToRoute('app_admin_user');
    }

    /*
     * Créer un MJ à partir d'un utitlisateur
     */
    #[Route('/admin/user/{id}/create_gamemaster', name: 'app_admin_user_create_gm', requirements: ['id' => Requirement::UUID_V7], methods: ['GET'])]
    public function createGamemaster(?User $user, EntityManagerInterface $manager, GamemasterRepository $gmRepo): Response
    {
        if (!$user) {
            $this->addFlash('danger', 'Aucun utilisateur sélectionné.');
            return $this->redirectToRoute('app_admin_user');
        }
        if ($gmRepo->findByEmail($user->getEmail())) {
            $this->addFlash('danger', 'Un profil meneur(euse) de jeu existe déjà avec cet email. Associez le depuis la gestion des meneur(euse)s de jeux.');
            return $this->redirectToRoute('app_admin_user');
        }
        if ($user->getLinkToGamemaster()) {
            $this->addFlash('danger', 'Profil meneur(euse) de jeu déjà existant.');
            return $this->redirectToRoute('app_admin_user');
        }
        $gamemaster = new Gamemaster();
        $gamemaster->setFirstName($user->getFirstName());
        $gamemaster->setLastName($user->getLastName());
        $gamemaster->setPreferedName($user->getFullName());
        $slugger = new AsciiSlugger('fr_FR');
        $slug = $slugger->slug(strtolower($user->getFullName()));
        $gamemaster->setSlug($slug);
        $gamemaster->setEmail($user->getEmail());
        $phone = $user->getPhone();
        if ($phone) { $gamemaster->setPhone($phone); }
        $gamemaster->setLinkToUser($user);
        $manager->persist($gamemaster);
        $manager->flush();
        $this->addFlash('success', 'Meneur.euse de jeu créé.e avec succès.');
        return $this->redirectToRoute('app_admin_user');
    }

    /*
     * Modifier un utilisateur
     */
    #[Route('/admin/user/{id}/edit', name: 'app_admin_user_edit', requirements: ['id' => Requirement::UUID_V7], methods: ['GET', 'POST'])]
    public function edit(?User $user, Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $manager,  MailerInterface $mailer): Response
    {
        $form = $this->createForm(UserType::class, $user);

        // Mise à jour de l'utilisateur à partir du formaulaire
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // Si un nouveau mot de passe a été proposé
            if ($form->get('newPassword')->getData()) {
                // Encoder le mot de passe
                $newPassword = $form->get('newPassword')->getData();
                $user->setPassword($userPasswordHasher->hashPassword($user, $newPassword));
                // Prévenir l'utilisateur de la modification de son mot de passe
                $email = (new TemplatedEmail())
                    ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
                    ->to((string) $user->getEmail())
                    ->subject('Votre mot de passe a été modifié')
                    ->htmlTemplate('admin/user/edit.email.html.twig')
                    ->textTemplate('admin/user/edit.email.txt.twig')
                    ->context([
                        'user' => $user,
                        'clearPassword' => $newPassword,
                    ]);
                $mailer->send($email);
            }
            // Mettre à jour l'utilisateur
            $user->setLastUpdate();
            $manager->persist($user);
            $manager->flush();
            $this->addFlash('success', 'Utilisateur modifié avec succès.');
            return $this->redirectToRoute('app_admin_user');
        }

        // Affichage du formulaire de modification
        return $this->render('admin/user/edit.html.twig', [
            'form' => $form,
            'user' => $user
        ]);
    }

    /*
     * Ajouter un utilisateur
     */
    #[Route('/admin/user/add', name: 'app_admin_user_add', methods: ['GET', 'POST'])]
    public function add(Request $request, UserPasswordHasherInterface $userPasswordHasher,EntityManagerInterface $manager,  MailerInterface $mailer): Response
    {
        $user = new User();
        $form = $this->createForm(UserType::class, $user);

        // Mise à jour de l'utilisateur à partir du formaulaire
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // Générer un mot de passe aléatoire et le mailler
            if ($form->get('newPassword')->getData()) {
                // Encoder le mot de passe
                $newPassword = $form->get('newPassword')->getData();
                $user->setPassword($userPasswordHasher->hashPassword($user, $newPassword));
            } else {
                // Générer un mot de passe aléatoire
                $newPassword = bin2hex(random_bytes(8));
                $user->setPassword($userPasswordHasher->hashPassword($user, $newPassword));
            }
            // Enregisrer ce nouvel utilisateur
            $manager->persist($user);
            $manager->flush();

            // Prévenir l'utilisateur de la création de son compte
            $email = (new TemplatedEmail())
                    ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
                    ->to((string) $user->getEmail())
                    ->subject('Votre mot de passe a été modifié')
                    ->htmlTemplate('admin/user/add.email.html.twig')
                    ->textTemplate('admin/user/add.email.txt.twig')
                    ->context([
                        'user' => $user,
                        'clearPassword' => $newPassword,
                    ]);
            $mailer->send($email);

            // Vérification de l'email, si nécessaire
            if (!$user->isVerified()) {
                $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', 'Utilisateur créé avec succès.');
            return $this->redirectToRoute('app_admin_user');
        }

        // Affichage du formulaire d'ajout
        return $this->render('admin/user/edit.html.twig', [
            'form' => $form,
        ]);
    }
}
