<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Company;
use AppBundle\Entity\User;
use AppBundle\Enum\UserType;
use AppBundle\Form\Type\Front\User\RegistrationFormType;
use AppBundle\Helper\UserHelper;
use AppBundle\Mail\NewsletterMailer;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

/**
 *
 */
class RegistrationController extends BaseController
{
    
    /**
     * @var EventDispatcherInterface
     */
    private $dispatcher;

    /**
     * @var FormFactoryInterface
     */
    private $formFactory;

    /**
     * @var NewsletterMailer
     */
    private $newsletterMailer;

    /**
     * @var RouterInterface
     */
    private $router;

    /**
     * @var SessionInterface
     */
    private $session;

    /**
     * @var TokenStorageInterface
     */
    private $tokenStorage;

    /**
     * @var UserManagerInterface
     */
    private $userManager;

    /**
     * @var EntityManagerInterface
     */
    private $em;
    

    


    public function __construct(
        EventDispatcherInterface $dispatcher,
        FormFactoryInterface $formFactory,
        NewsletterMailer $newsletterMailer,
        RouterInterface $router,
        SessionInterface $session,
        TokenStorageInterface $tokenStorage,
        UserManagerInterface $userManager
    )
    {
       
        $this->logger = $logger;
         $this->dispatcher = $dispatcher;
        $this->formFactory = $formFactory;
        $this->newsletterMailer = $newsletterMailer;
        $this->router = $router;
        $this->session = $session;
        $this->tokenStorage = $tokenStorage;
        $this->userManager = $userManager;
        
    }

    /**
     * Gestion du formulaire d'inscription (2 étapes) d'un utilisateur :
     * - la première étape dispose d'un type de formulaire unique.
     * - la seconde étape dispose d'un formulaire spécifique au type d'utilisateur (professeur ou ingénieur) créé.
     * Principe de fonctionnement :
     * 1. Affichage du formulaire de l'étape 1
     * 2. Lorsqu'il est soumis (POST) et valide, les données du formulaire sont stockées en session et l'utilisateur est redirigé à l'étape 2
     * 3. Lorsque le formulaire de l'étape 2 est soumis et valide, on enregistre l'utilisateur
     * @param Request $request
     * @param LoggerInterface $logger
     * @return null|RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function registerAction(Request $request)
    {
        return $this->render('Front/Default/registerOff.html.twig', []);
        die;
        
        $user = $this->getUser();

        // If user is logged, redirect to member area
        if (is_object($user) && $user instanceof UserInterface) {
            return new RedirectResponse($this->router->generate('espace_perso'));
        }
        unset($user);

        // Récupération de la variable de session du formulaire d'inscription
        $userSession = $this->session->get('user_registration');

        // Récupération des variables $formStep de l'URL
        $formStep = $request->query->getInt('step', 1);

        if ($formStep > 1) {
            // Redirection à l'étape 1 si aucune données du formulaire d'inscription de l'étape 1 n'existe (n'est en session) :
            // cas où l'accès à l'étape 2 se fait autrement que via la soumission du formulaire de l'étape 1.
            if (null === $userSession) {
                return new RedirectResponse($this->router->generate('fos_user_registration_register', [
                    'step' => 1
                ]));
            }
        } else {
            $formStep = 1;
        }

        // Initialisation de l'utilisateur
        $user = $this->userManager->createUser();
        $user->setEnabled(true);
        
        if ($userSession !== null) {
            $user->setType($userSession['type']);
            $user->setUsername($userSession['username']);
            $user->setFirstname($userSession['firstname']);
            $user->setLastname($userSession['lastname']);
            $user->setEmail($userSession['email']);
            $user->setPlainPassword($userSession['plainPassword']);
        }

        $event = new GetResponseUserEvent($user, $request);
        $this->dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

        if (1 === $formStep) {
            $form = $this->prepareRegistrationForm($user);
            $form->setData($user);

            $form->handleRequest($request);

            if ($form->isSubmitted() && $form->isValid()) {
                $formData = $form->getData();

                // Generate auto Username
                UserHelper::setUserManager($this->userManager);
                $user->setUsername(UserHelper::generateUsername($user));

                // Check if type is valid 
                $userType = $formData->getType();

                if ($userType === UserType::TEACHER) {
                    $user->setType(UserType::TEACHER);
                } else {
                    $user->setType(UserType::ENGINEER);
                }

                $userType = $user->getType(); // Reset var

                // Sauvegarde des données du formulaire de l'étape 1 en session
                // $this->session->set('user_registration', [
                //     'type'          => $formData->getType(),
                //     'username'      => $formData->getUsername(),
                //     'firstname'     => $formData->getFirstname(),
                //     'lastname'      => $formData->getLastname(),
                //     'email'         => $formData->getEmail(),
                //     'plainPassword' => $formData->getPlainPassword(),
                // ]);

                // Legacy - Stay for later in other Controller
                // If the enginner set a custom company, first check if it does not already exists.
                // If not, then create it.
                // if (UserType::ENGINEER === $user->getType() && $companyName = $form->get('establishmentNameOther')->getData()) {
                //     $em = $this->getDoctrine()->getManager();
                //     $company = $em->getRepository(Company::class)->findOneByName($companyName);

                //     if (!$company) {
                //         $company = new Company();
                //         $company->setName($companyName);
                //         $company->setAvailableForUsers(true);

                //         $em->persist($company);
                //         $em->flush();
                //     }

                //     $user->setEstablishment($company);
                // }

                //$this->session->remove('user_registration'); // Suppression des données de session
                
                $event = new FormEvent($form, $request);

                $this->dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

                /**
                 * Next part is called only if fos_user.registration.confirmation.enabled config is disabled
                 */
                
                $this->userManager->updateUser($user);

                // Inscription / Désinscription à la newsletter
                //$this->newsletterMailer->subscribe($user);

                if (null === $response = $event->getResponse()) {
                    // Get $url if params _return exists.
                    $redirectUrl = null;
                    
                    if ($this->session->has('_return')) {
                        $_return = $this->session->get('_return'); 
                    }

                    if (isset($_return)) {
                        // Decode params
                        $_return = base64_decode($_return, true);
            
                        if (filter_var($_return, FILTER_VALIDATE_URL)) {
                            // Security - Check if redirect is local url 
                            if (strpos($_return, $request->getSchemeAndHttpHost()) === 0) {
                                $redirectUrl = $_return;
                            }
                        }
                    }

                    $this->session->remove('_return');
                    
                    if (empty($redirectUrl)) {
                        // Generate redirect with $userType
                        switch ($userType) {
                            case UserType::TEACHER :
                                                        $redirectUrl = $this->generateUrl('espace_perso', [
                                                            'first_login' => 1
                                                        ]);
                                                        break;
                            case UserType::ENGINEER :
                                                        $redirectUrl = $this->generateUrl('espace_perso', [
                                                            'first_login' => 1
                                                        ]);
                                                        break;
                        }
                    }

                    //$this->session->remove('user_registration'); // Suppression des données de session
                    
                    $response = new RedirectResponse($redirectUrl);
                }

                $this->dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

                return $response;
            }
        }

        return $this->render('FOSUserBundle:Registration:register.html.twig', [
            'form' => $form->createView(),
            'step' => $formStep
        ]);
    }
    
    /**
     *
     * @param User $user
     * @return \Symfony\Component\Form\FormInterface
     */
    private function prepareRegistrationForm(User $user): FormInterface
    {
        return $this->formFactory->create(RegistrationFormType::class, $user, [
            'action' => $this->generateUrl('fos_user_registration_register')
        ]);
    }


    /**
     * Tell the user to check their email provider.
     */
    public function checkEmailAction()
    {
        return parent::checkEmailAction();
    }


    /**
     * Receive the confirmation token from user email provider, login the user.
     *
     * @param Request $request
     * @param string  $token
     *
     * @return Response
     */
    public function confirmAction(Request $request, $token)
    {
        /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
        $userManager = $this->get('fos_user.user_manager');

        $user = $userManager->findUserByConfirmationToken($token);

        if (null === $user) {
            throw new NotFoundHttpException(sprintf('The user with confirmation token "%s" does not exist', $token));
        }

        /** @var $dispatcher EventDispatcherInterface */
        $dispatcher = $this->get('event_dispatcher');

        $user->setConfirmationToken(null);
        $user->setEnabled(true);

        $event = new GetResponseUserEvent($user, $request);
        $dispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRM, $event);

        $userManager->updateUser($user);

        if (null === $response = $event->getResponse()) {
            // Get $url if params _return exists.
            $redirectUrl = null;
                    
            if ($this->session->has('_return')){
                $_return = $this->session->get('_return'); 
            }

            if (isset($_return)) {
                // Decode params
                $_return = base64_decode($_return, true);
    
                if (filter_var($_return, FILTER_VALIDATE_URL)) {
                    // Security - Check if redirect is local url 
                    if (strpos($_return, $request->getSchemeAndHttpHost()) === 0) {
                        $redirectUrl = $_return;
                    }
                }
            }

            $this->session->remove('_return');
            
            if (empty($redirectUrl)) {
                // Generate redirect with $userType
                switch ($user->getType()) {
                    case UserType::TEACHER :
                                                $redirectUrl = $this->generateUrl('espace_perso', [
                                                    'first_login' => 1
                                                ]);
                                                break;
                    case UserType::ENGINEER :
                                                $redirectUrl = $this->generateUrl('espace_perso', [
                                                    'first_login' => 1
                                                ]);
                                                break;
                }
            }
            
            //$redirectUrl = $this->generateUrl('fos_user_registration_confirmed');
            $response = new RedirectResponse($redirectUrl);
        }

        $dispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRMED, new FilterUserResponseEvent($user, $request, $response));

        return $response;
    }
}
