<?php
 
 
namespace App\Controller;
 
 
use App\Config\ConfigManager;
 
use App\Entity\AbstractPage;
 
use App\Entity\Config;
 
use App\Entity\User;
 
use App\Exception\User\PasswordAlreadyDefinedException;
 
use App\Exception\User\PasswordResetTokenExpired;
 
use App\Repository\UserRepository;
 
use App\User\UserPasswordManager;
 
use Doctrine\ORM\EntityManagerInterface;
 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
 
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 
use Symfony\Component\HttpFoundation\Request;
 
use Symfony\Component\HttpFoundation\Response;
 
use Symfony\Component\Routing\Annotation\Route;
 
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
 
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
 
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
 
 
class SecurityController extends AbstractController
 
{
 
    /**
 
     * @param AuthenticationUtils $authenticationUtils
 
     *
 
     * @return Response
 
     */
 
    public function login(AuthenticationUtils $authenticationUtils, ConfigManager $configManager): Response
 
    {
 
         if ($this->getUser()) {
 
            $this->redirect($configManager->getConfigLink('home_page_dashboard'));
 
         }
 
 
        $error = $authenticationUtils->getLastAuthenticationError();
 
        $lastUsername = $authenticationUtils->getLastUsername();
 
 
        return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
 
    }
 
 
    /**
 
     * @param User $user
 
     * @param Request $request
 
     * @param EntityManagerInterface $entityManager
 
     * @param EncoderFactoryInterface $encoderFactory
 
     * @param ConfigManager $configManager
 
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
 
     * @throws PasswordAlreadyDefinedException
 
     */
 
    public function validation(User $user, Request $request, EntityManagerInterface $entityManager, EncoderFactoryInterface $encoderFactory, ConfigManager $configManager)
 
    {
 
        if (!empty($user->getPassword())) {
 
            throw new PasswordAlreadyDefinedException($user);
 
        }
 
 
        $submittedToken = $request->request->get('_csrf_token');
 
        $password = $request->request->get('password');
 
        $confirm = $request->request->get('confirm');
 
        if (empty($password)) {
 
            return $this->render('security/set-password.html.twig');
 
        }
 
 
        if (!$this->isCsrfTokenValid('set-password', $submittedToken)) {
 
            return $this->render('security/set-password.html.twig', ['error' => 'Token expiré, merci de remplir à nouveau le formulaire.']);
 
        }
 
 
        if ($confirm !== $password) {
 
            return $this->render('security/set-password.html.twig', ['error' => 'Merci de saisir le même mot de passe.']);
 
        }
 
 
        $encoder = $encoderFactory->getEncoder($user);
 
        $user->setPassword($encoder->encodePassword($password, null));
 
        $user->setEnabled(true);
 
        $entityManager->flush();
 
 
 
        $link = $configManager->getConfigLink('home_page');
 
        return $this->redirect($link);
 
    }
 
 
    /**
 
     * @param Request $request
 
     * @param UserPasswordManager $passwordManager
 
     * @param UserRepository $userRepository
 
     * @return \Symfony\Component\HttpFoundation\JsonResponse
 
     * @throws \Twig\Error\LoaderError
 
     * @throws \Twig\Error\RuntimeError
 
     * @throws \Twig\Error\SyntaxError
 
     */
 
    public function askResetPassword(Request $request, UserPasswordManager $passwordManager, UserRepository $userRepository)
 
    {
 
        $submittedToken = $request->request->get('_csrf_token');
 
        if (!$this->isCsrfTokenValid('reset-password', $submittedToken)) {
 
            return $this->json(['success' => false, 'message' => 'Token invalide. Merci de recharger votre page.']);
 
        }
 
 
        $email = $request->request->get('email');
 
        if (empty($email)) {
 
            return $this->json(['success' => false, 'message' => 'Merci de saisir votre email.']);
 
        }
 
 
        $user = $userRepository->findOneBy(['email' => $email]);
 
        if (!$user instanceof User) {
 
            return $this->json(['success' => false, 'message' => 'Aucun compte connu avec cette adresse mail.']);
 
        }
 
 
        $passwordManager->askResetPassword($user);
 
 
        return $this->json(['success' => true]);
 
    }
 
 
    /**
 
     * @ParamConverter("user", options={"mapping": {"id": "id", "requestPasswordToken": "requestPasswordToken"}})
 
     *
 
     * @param User $user
 
     * @param UserPasswordManager $passwordManager
 
     * @param Request $request
 
     * @param EntityManagerInterface $entityManager
 
     * @param EncoderFactoryInterface $encoderFactory
 
     * @param ConfigManager $configManager
 
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
 
     * @throws PasswordResetTokenExpired
 
     */
 
    public function resetPassword(User $user, UserPasswordManager $passwordManager, Request $request, EntityManagerInterface $entityManager, EncoderFactoryInterface $encoderFactory, ConfigManager $configManager)
 
    {
 
        if (!$passwordManager->canResetPassword($user)) {
 
            throw new PasswordResetTokenExpired($user);
 
        }
 
 
        $submittedToken = $request->request->get('_csrf_token');
 
        $password = $request->request->get('password');
 
        $confirm = $request->request->get('confirm');
 
        if (empty($password)) {
 
            return $this->render('security/set-password.html.twig');
 
        }
 
 
        if (!$this->isCsrfTokenValid('set-password', $submittedToken)) {
 
            return $this->render('security/set-password.html.twig', ['error' => 'Token expiré, merci de remplir à nouveau le formulaire.']);
 
        }
 
 
        if ($confirm !== $password) {
 
            return $this->render('security/set-password.html.twig', ['error' => 'Merci de saisir le même mot de passe.']);
 
        }
 
 
        $encoder = $encoderFactory->getEncoder($user);
 
        $user->setPassword($encoder->encodePassword($password, null));
 
        $user->setEnabled(true);
 
        $entityManager->flush();
 
 
 
        $link = $configManager->getConfigLink('home_page');
 
        return $this->redirect($link);
 
    }
 
 
    /**
 
     * @throws \Exception
 
     */
 
    public function logout()
 
    {
 
    }
 
}