<?php

namespace App\Controller\Admin;

use App\Entity\User;
use App\Repository\UserRepository;
use App\Service\KeycloakAdminService;
use App\Service\MailerService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
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\Security\Http\Attribute\IsGranted;
use Twig\Environment;

#[Route('/admin/membres', name: 'app_admin_membres')]
#[IsGranted('ROLE_ROOT')]
class MembresController extends AbstractController
{
    public function __construct(
        private LoggerInterface $logger,
    ) {
    }

    #[Route('', name: '')]
    public function index(KeycloakAdminService $keycloak, UserRepository $userRepository): Response
    {
        $membres = [];

        try {
            // S'assurer que tous les groupes requis existent
            $createdGroups = $keycloak->ensureRequiredGroups();
            foreach ($createdGroups as $g) {
                $this->addFlash('success', 'Groupe "'.$g.'" cree automatiquement dans Keycloak.');
            }

            $keycloakUsers = $keycloak->listUsers();

            foreach ($keycloakUsers as $kcUser) {
                $email = $kcUser['email'] ?? '';
                $localUser = '' !== $email ? $userRepository->findOneBy(['email' => $email]) : null;

                $userGroups = [];
                try {
                    $userGroups = $keycloak->getUserGroups($kcUser['id']);
                } catch (\Throwable $e) {
                    $this->logger->warning('Keycloak: Failed to get groups for user '.$kcUser['id'].': '.$e->getMessage());
                }

                $membres[] = [
                    'keycloakId' => $kcUser['id'],
                    'email' => $email,
                    'firstName' => $kcUser['firstName'] ?? '',
                    'lastName' => $kcUser['lastName'] ?? '',
                    'enabled' => $kcUser['enabled'] ?? false,
                    'emailVerified' => $kcUser['emailVerified'] ?? false,
                    'createdTimestamp' => $kcUser['createdTimestamp'] ?? 0,
                    'existsInDb' => null !== $localUser,
                    'localUser' => $localUser,
                    'groups' => $userGroups,
                ];
            }
        } catch (\Throwable $e) {
            $this->logger->error('Keycloak: Failed to list users: '.$e->getMessage());
            $this->addFlash('error', 'Impossible de recuperer la liste des membres depuis Keycloak.');
        }

        $availableGroups = [];
        try {
            $availableGroups = $keycloak->listGroups();
        } catch (\Throwable $e) {
            $this->logger->warning('Keycloak: Failed to list groups: '.$e->getMessage());
        }

        return $this->render('admin/membres.html.twig', [
            'membres' => $membres,
            'availableGroups' => $availableGroups,
        ]);
    }

    #[Route('/create', name: '_create', methods: ['POST'])]
    public function create(
        Request $request,
        KeycloakAdminService $keycloak,
        UserRepository $userRepository,
        EntityManagerInterface $em,
        UserPasswordHasherInterface $passwordHasher,
        MailerService $mailer,
        Environment $twig,
    ): Response {
        $firstName = trim($request->request->getString('firstName'));
        $lastName = trim($request->request->getString('lastName'));
        $email = trim($request->request->getString('email'));
        $groups = $request->request->all('groups');

        if ('' === $firstName || '' === $lastName || '' === $email) {
            $this->addFlash('error', 'Veuillez remplir tous les champs.');
        } elseif (null !== $userRepository->findOneBy(['email' => $email])) {
            $this->addFlash('error', 'Un compte existe deja avec cet email.');
        } else {
            try {
                $kcResult = $this->createKeycloakUser($keycloak, $email, $firstName, $lastName, $groups);

                if (!$kcResult['created']) {
                    $this->addFlash('error', 'Erreur lors de la creation du compte Keycloak. L\'email existe peut-etre deja.');
                } else {
                    $this->persistLocalUser($em, $passwordHasher, [
                        'email' => $email,
                        'firstName' => $firstName,
                        'lastName' => $lastName,
                        'keycloakId' => $kcResult['keycloakId'],
                        'tempPassword' => $kcResult['tempPassword'],
                        'groups' => $groups,
                    ]);
                    $this->sendCreationEmail($mailer, $twig, $email, $firstName, $lastName, $kcResult['tempPassword'], $groups);

                    $this->addFlash('success', 'Le membre '.$firstName.' '.$lastName.' a ete cree. Un email avec les identifiants lui a ete envoye.');
                }
            } catch (\Throwable $e) {
                $this->logger->error('Keycloak: Failed to create user '.$email.': '.$e->getMessage());
                $this->addFlash('error', 'Erreur lors de la creation : '.$e->getMessage());
            }
        }

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

    /**
     * @param list<string> $groups
     *
     * @return array{created: bool, keycloakId: string|null, tempPassword: string|null}
     */
    private function createKeycloakUser(KeycloakAdminService $keycloak, string $email, string $firstName, string $lastName, array $groups): array
    {
        $kcResult = $keycloak->createUser($email, $firstName, $lastName);

        if ($kcResult['created'] && null !== $kcResult['keycloakId']) {
            foreach ($groups as $group) {
                $keycloak->addUserToGroup($kcResult['keycloakId'], $group);
            }
        }

        return $kcResult;
    }

    /**
     * @param array{email: string, firstName: string, lastName: string, keycloakId: string, tempPassword: string, groups: list<string>} $data
     */
    private function persistLocalUser(
        EntityManagerInterface $em,
        UserPasswordHasherInterface $passwordHasher,
        array $data,
    ): User {
        $user = new User();
        $user->setEmail($data['email']);
        $user->setFirstName($data['firstName']);
        $user->setLastName($data['lastName']);
        $user->setKeycloakId($data['keycloakId']);
        $user->setRoles(\in_array('superadmin', $data['groups'], true) ? ['ROLE_ROOT'] : ['ROLE_EMPLOYE']);
        $user->setPassword($passwordHasher->hashPassword($user, $data['tempPassword']));
        $user->setTempPassword($data['tempPassword']);

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

        return $user;
    }

    /**
     * @param list<string> $groups
     */
    private function sendCreationEmail(
        MailerService $mailer,
        Environment $twig,
        string $email,
        string $firstName,
        string $lastName,
        string $tempPassword,
        array $groups,
    ): void {
        $mailer->sendEmail(
            $email,
            'CRM E-Cosplay - Votre compte a ete cree',
            $twig->render('emails/membre_created.html.twig', [
                'firstName' => $firstName,
                'lastName' => $lastName,
                'email' => $email,
                'tempPassword' => $tempPassword,
                'groups' => $groups,
            ]),
            null,
            null,
            false,
        );
    }

    #[Route('/{id}/resend', name: '_resend', methods: ['POST'])]
    public function resend(
        int $id,
        UserRepository $userRepository,
        MailerService $mailer,
        Environment $twig,
    ): Response {
        $user = $userRepository->find($id);

        if (null === $user || !$user->hasTempPassword()) {
            $this->addFlash('error', 'Impossible de renvoyer le mail. Le mot de passe temporaire n\'est plus disponible.');

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

        $mailer->sendEmail(
            $user->getEmail(),
            'CRM E-Cosplay - Rappel : votre compte a ete cree',
            $twig->render('emails/membre_created.html.twig', [
                'firstName' => $user->getFirstName(),
                'lastName' => $user->getLastName(),
                'email' => $user->getEmail(),
                'tempPassword' => $user->getTempPassword(),
                'groups' => [],
            ]),
            null,
            null,
            false,
        );

        $this->addFlash('success', 'Le mail de creation a ete renvoye a '.$user->getEmail().'.');

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

    #[Route('/{keycloakId}/delete', name: '_delete', methods: ['POST'])]
    public function delete(string $keycloakId, KeycloakAdminService $keycloak, UserRepository $userRepository, EntityManagerInterface $em): Response
    {
        try {
            $keycloak->deleteUser($keycloakId);

            $localUser = $userRepository->findOneBy(['keycloakId' => $keycloakId]);
            if (null !== $localUser) {
                $em->remove($localUser);
                $em->flush();
            }

            $this->addFlash('success', 'Le membre a ete supprime.');
        } catch (\Throwable) {
            $this->addFlash('error', 'Erreur lors de la suppression du membre.');
        }

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