<?php

declare(strict_types=1);

namespace App\Controller\Admin\Security\Administrateurs;

use App\Entity\Security\Administrateurs\Administrateurs;
use App\Form\Security\Users\AdministrateursType;
use App\Interfaces\NotificationsInterface;
use App\Managers\ManagersInterface;
use App\Repository\Security\Administrateurs\AdministrateursRepository;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security as Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

#[Route('/admin/administrateurs')]
#[Security("is_granted('ROLE_SUPER_ADMIN') or is_granted('ROLE_ADMIN')")]
class AdminAdministrateursController extends AbstractController
{
    public function __construct(
        private ManagersInterface $managers,
        private UserPasswordHasherInterface $encoder,
        private NotificationsInterface $notification,
    ) {}

    #[Route('/', name: "admin.administrateurs.index", methods: ['GET'])]
    #[Security("is_granted('ROLE_SUPER_ADMIN')")]
    /**
     * @param AdministrateursRepository $administrateursRepository
     * @return Response
     */
    public function index(AdministrateursRepository $administrateursRepository): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $administrateur = new Administrateurs();
        $form = $this->createForm(AdministrateursType::class, $administrateur, ['user' => $administrateur]);
        return $this->render('admin/security/users/administrateurs/index.html.twig', [
            'administrateurs' => $administrateursRepository->findBy(['deletedAt' => null], ['id' => 'DESC']),
            'administrateur' => $administrateur,
            'user' => $administrateur,
            'form' => $form->createView(),
            'title' => 'Liste des administrateurs',
            'libelle_ajouter' => 'Nouvel administrateur',
            'current_page' => 'administrateurs',
            'current_global' => 'admin_users'
        ]);
    }

    #[Route('/show/{id<\d+>}', name: "admin.administrateurs.show", methods: ['GET'])]
    #[Security("is_granted('ROLE_SUPER_ADMIN')")]
    /**
     * @param Administrateurs $administrateur
     * @return Response
     */
    public function show(Administrateurs $administrateur): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        return $this->render('admin/security/users/administrateurs/show.html.twig', [
            'administrateur' => $administrateur,
            'title' => 'Détails administrateur',
            'libelle_liste' => 'Liste des administrateurs',
            'libelle_ajouter' => 'Nouvel administrateur',
            'current_page' => 'administrateurs',
            'current_global' => 'admin_users'
        ]);
    }

    #[Route('/new', name: "admin.administrateurs.new", methods: ['GET', 'POST'])]
    #[Security("is_granted('ROLE_SUPER_ADMIN')")]
    /**
     * @param Request $request
     * @return Response
     * @throws Exception
     *
     */
    public function new(Request $request): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $administrateur = new Administrateurs();
        $form = $this->createForm(AdministrateursType::class, $administrateur, ['user' => $administrateur]);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $this->managers->setEntity($administrateur, 'new');
            $this->sendNotif('Administrateur crée', 'Création', $administrateur, 'check', 'green');
            $this->addFlash('success', 'Administrateur crée avec succès.');
            $referer = $request->headers->get('referer');
            //return new RedirectResponse($referer ?? $this->generateUrl('admin.administrateurs.new'));
            return $this->redirectToRoute('admin.administrateurs.index');
        }

        return $this->render('admin/security/users/administrateurs/new.html.twig', [
            'administrateur' => $administrateur,
            'user' => $administrateur,
            'form' => $form->createView(),
            'title' => 'Ajouter un nouvel administrateur',
            'libelle_liste' => 'Liste des administrateurs',
            'current_page' => 'administrateurs_new',
            'current_global' => 'admin_users'
        ]);
    }

    #[Route('/edit/{id<\d+>}', name: "admin.administrateurs.edit", methods: ['GET', 'POST'])]
    #[Security("is_granted('ROLE_SUPER_ADMIN')")]
    /**
     * @param Request $request
     * @param Administrateurs $administrateur
     * @Security("is_granted('ROLE_SUPER_ADMIN')")
     * @return Response
     * @throws Exception
     */
    public function edit(Request $request, Administrateurs $administrateur): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $form = $this->createForm(AdministrateursType::class, $administrateur, ['user' => $administrateur]);
        $form->handleRequest($request);
        if ($form->isSubmitted()) {
            /** @var string[] $datas */
            $datas = $request->request->all('administrateurs');
            $currentPassword = $datas['password_actuel'];
            if ($currentPassword !== '') {
                $match = $this->encoder->isPasswordValid($administrateur, (string)$currentPassword);
                if ($match) {
                    $firstNewPassword = $datas['plainPassword']['first'];
                    $confirmPassword = $datas['plainPassword']['second'];
                    if ($firstNewPassword === $confirmPassword) {
                        $this->encodeUserPassword($administrateur, $confirmPassword);
                        //Connexion automatique
                        $token = new UsernamePasswordToken(
                            $administrateur,
                            'main',
                            $administrateur->getRoles()
                        );
                        $this->get('security.token_storage')->setToken($token);
                        $this->get('session')->set('_security_main', serialize($token));
                    } else {
                        $this->addFlash("danger", "Mot de passe non identique.");
                        return $this->redirectToRoute('admin.administrateurs.edit', [
                            'id' => $administrateur->getId(),
                        ]);
                    }
                } else {
                    $this->addFlash("danger", "Mot de passe actuel invalide.");
                    return $this->redirectToRoute('admin.administrateurs.edit', [
                        'id' => $administrateur->getId(),
                    ]);
                }
            }
            $this->managers->setEntity($administrateur, 'edit');
            $this->sendNotif('Administrateur modifié', 'Modification', $administrateur, 'check', 'green');
            $this->addFlash('success', 'Administrateur modifié avec succès.');
            $referer = $request->headers->get('referer');
            return new RedirectResponse($referer ?? $this->generateUrl('admin.administrateurs.edit', [
                'id' => $administrateur->getId(),
            ]));
        }

        return $this->render('admin/security/users/administrateurs/edit.html.twig', [
            'administrateur' => $administrateur,
            'user' => $administrateur,
            'form' => $form->createView(),
            'title' => 'Editer mon compte',
            'libelle_ajouter' => 'Nouvel administrateur',
            'libelle_liste' => 'Liste des administrateurs',
            'current_page' => 'administrateurs',
            'current_global' => 'admin_users'
        ]);
    }

    #[Route('/compte/{id<\d+>}/edit', name: "admin.administrateurs.compte.edit", methods: ['GET', 'POST'])]
    #[Security("is_granted('ROLE_SUPER_ADMIN') or is_granted('ROLE_ADMIN')")]
    /**
     * @param Request $request
     * @param Administrateurs $administrateur
     * @return Response
     * @throws Exception
     */
    public function editCompte(Request $request, Administrateurs $administrateur): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $form = $this->createForm(
            \App\Form\Security\Comptes\AdministrateursType::class,
            $administrateur,
            ['user' => $administrateur]
        );
        $form->handleRequest($request);
        if ($form->isSubmitted()) {
            $this->managers->setEntity($administrateur, 'edit');
            $this->addFlash('success', 'Modification effectuée avec succès.');
            $referer = $request->headers->get('referer');
            return new RedirectResponse($referer ?? $this->generateUrl('admin.administrateurs.edit', [
                'id' => $administrateur->getId(),
            ]));
        }

        return $this->render('admin/security/users/administrateurs/compte.html.twig', [
            'administrateur' => $administrateur,
            'user' => $administrateur,
            'form' => $form->createView(),
            'title' => 'Editer mon compte',
            'current_page' => 'comptes',
            'current_global' => 'comptes'
        ]);
    }

    #[Route('/{id<\d+>}', name: "admin.administrateurs.delete", methods: ['DELETE'])]
    #[Security("is_granted('ROLE_SUPER_ADMIN')")]
    /**
     * @param Request $request
     * @param Administrateurs $administrateur
     * @return Response
     * @throws Exception
     */
    public function delete(Request $request, Administrateurs $administrateur): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        if ($this->isCsrfTokenValid('delete' . $administrateur->getId(), $request->request->get('_token'))) {
            $this->sendNotif('Administrateur supprimé', 'Suppression', $administrateur, 'trash', 'red');
            $this->managers->setEntity($administrateur, 'delete');
            $this->addFlash('success', 'Administrateur supprimé avec succès.');
        }

        $referer = $request->headers->get('referer');
        return new RedirectResponse($referer ?? $this->generateUrl('admin.administrateurs.index'));
    }

    /**
     * @param Administrateurs $entity
     * @param string $newPassword
     */
    private function encodeUserPassword(Administrateurs $entity, string $newPassword): void
    {
        $entity->setPassword($this->encoder->hashPassword($entity, $newPassword));
    }

    /**
     * @param string $title
     * @param string $action
     * @param object $entity
     * @param string $icon
     * @param string $color
     * @return void
     */
    private function sendNotif(string $title, string $action, object $entity, string $icon, string $color): void
    {
        $this->notification->save($title, $action, $entity, $icon, $color);
    }
}
