<?php

namespace AppBundle\Controller;

use AppBundle\Entity\CguUtilisateur;
use AppBundle\Entity\Historique;
use AppBundle\Entity\Interlocuteur;
use AppBundle\Entity\Utilisateur;
use AppBundle\Form\Security\SendPasswordReset;
use AppBundle\Form\Security\LoginForm;
use AppBundle\Form\Security\PasswordReset;
use AppBundle\Form\Security\SubscribeForm;
use AppBundle\Form\User\PasswordUpdate;
use Doctrine\Common\Collections\ArrayCollection;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Security;

class SecurityController extends Controller
{
    /**
     * @Route("/connexion", name="security_login")
     * @Template("@App/Security/login.html.twig")
     */
    public function loginAction()
    {
        if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {

            $agence = $this->get('session')->get('agence');
            /** @var Utilisateur $user */
            $user = $this->getUser();
            if(empty($agence)) {
                $this->get('session')->set('agence', $user->getAgences()->first()->getCodeAgence());
            }

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

        $entete = $this->getDoctrine()->getManager()->getRepository('AppBundle:Entete')->findOneBy(['localisation'=>'Connexion']);

        $authenticationUtils = $this->get('security.authentication_utils');

        $error = $authenticationUtils->getLastAuthenticationError();

        $lastUsername = $authenticationUtils->getLastUsername();

        $form = $this->createForm(LoginForm::class, [
            '_username' => $lastUsername
        ]);

        // replace this example code with whatever you need
        return [
            'form' => $form->createView(),
            'error' => $error,
            'entete'=> $entete
        ];
    }

    /**
     * @Route("/abonnement", name="security_subscribe")
     * @Template("@App/Security/subscribe.html.twig")
     * @param Request $request
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function subscribeAction(Request $request, UserPasswordEncoderInterface $encoder)
    {
        if ($this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
            return $this->redirectToRoute('homepage');
        }

        $form = $this->createForm(SubscribeForm::class);
        $form->handleRequest($request);
        $doc = $this->getDoctrine();

        $error = null;
        
        if($form->isValid()) {
            $data = $form->getData();
            $em = $doc->getManager();
            $user = new Utilisateur($data);

            $encoded = $encoder->encodePassword($user, $user->getPlainPassword());
            $user->setMdp($encoded);

            $interloc = $em->getRepository('AppBundle:Interlocuteur')->find($data['siret']);
            $user->addInterlocuteur($interloc);

            foreach($data['thematique'] as $code) {
                $them = $em->find('AppBundle:Thematique', $code);
                $user->addThematique($them);
            }

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

                $cguUser = new CguUtilisateur();
                if(!empty($em->getRepository('AppBundle:Cgu')->findBy([], ['dateUpdated'=>'desc']))) {
                    $cguUser->setCguId($em->getRepository('AppBundle:Cgu')->findBy([], ['dateUpdated'=>'desc'])[0]->getId());
                    $cguUser->setUtilisateurID($user->getId());
                    $cguUser->setDateLecture(new \DateTime());
                    $em->persist($cguUser);
                }

                $em->flush();


                $this->get('aeap.mailer')->sendMail('AEAP : Validation du compte',$user->getEmail(), '@App/Email/validation.html.twig', [
                    'hash' => $user->getHash()
                ]);

                return $this->redirectToRoute("subscribe_success");

            } catch (\Exception $e) {
                throw $e;
//                $this->get('session')->getFlashBag()->add('error', $this->get('translator')->trans('SUBSCRIBE_ERROR'));
//
//                return $this->redirectToRoute('security_login');
            }
        }

        return [
            'form' => $form->createView(),
            'error' => $error
        ];
    }

    /**
     * @param Request $request
     * @Route("/abonnement/succes", name="subscribe_success")
     * @Template("@App/Security/subscribeSuccess.html.twig")
     * @return array
     */
    public function subscribeSuccessAction(Request $request)
    {
        return [];
    }

    /**
     * @Route("/mdp-oublie", name="send_reset_password")
     * @Template("@App/Security/sendResetPassword.html.twig")
     * @param Request $request
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function sendResetPasswordAction(Request $request)
    {
        $form = $this->createForm(SendPasswordReset::class);
        $form->handleRequest($request);
        $em = $this->getDoctrine()->getManager();

        if($form->isValid()) {
            $data = $form->getData()['email'];

            $user = $em->getRepository('AppBundle:Utilisateur')->findOneBy(['email'=>$data]);

            if($user) {
                $user->setHash(md5(time()));
                $em->flush();

                $this->get('aeap.mailer')->sendMail('AEAP : Mot de passe réinitialisé',$data,'@App/Email/resetPassword.html.twig', [
                    'hash' => $user->getHash()
                ]);

                $this->get('session')->getFlashBag()->add('success', $this->get('translator')->trans('SUCCESS_PASSWORD_RESET'));

//                return $this->redirectToRoute('homepage');
            } else {
                $this->get('session')->getFlashBag()->add('error', $this->get('translator')->trans('ERROR_PASSWORD_RESET_MAIL404'));
            }
        }

        return [
            'form' => $form->createView()
        ];
    }

    /**
     * @param Request $request
     * @param UserPasswordEncoderInterface $encoder
     * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
     * @Route("/nouveau-mdp", name="reset_password")
     * @Template("@App/Security/resetPassword.html.twig")
     */
    public function resetPasswordAction(Request $request, UserPasswordEncoderInterface $encoder )
    {
        $hash = $request->get('hash');
        $em = $this->getDoctrine()->getManager();
        $user = $em->getRepository('AppBundle:Utilisateur')->findOneBy(['hash'=>$hash]);
        $errors = [];

        if ($user) {

            $form = $this->createForm(PasswordReset::class);
            $form->handleRequest($request);

            if ($form->isValid()) {
                $data = $form->getData();
                $status = 200;

                $uppercase = preg_match('@[A-Z]@', $data['new']);
                $lowercase = preg_match('@[a-z]@', $data['new']);
                $number    = preg_match('@[0-9]@', $data['new']);

                if(!$uppercase || !$lowercase || !$number || strlen($data['new']) < 8) {
                    $status = 500;
                    $errors[] = $this->get('translator')->trans("ERROR_NEW_PASSWORD_STRENGTH");
                }

                if($data['new'] != $data['confirmation']) {
                    $status = 500;
                    $errors[] = $this->get('translator')->trans("ERROR_PASSWORD_CONFIRMATION_FAIL");
                }

                if($status == 200) {


                    $newPassword = $encoder->encodePassword($user, $data['new']);
                    $user->setMdp($newPassword);
                    $user->setHash(null);

                    $histo = new Historique('Modification', 'Utilisateur', $user->getUsername().' a modifié son mot de passe', $user);

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

                    $this->get('session')->getFlashBag()
                        ->add('success', $this->get('translator')->trans('USER_PASSWORD_SAVED'));

                    $this->get('aeap.mailer')->sendMail('AEAP : Mot de passe modifié', $user->getEmail(), '@App/Email/mdpChange.html.twig', [
                        'date' => new \DateTime()
                    ]);

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

        } else {
            $this->get('session')->getFlashBag()->add('error', $this->get('translator')->trans('ERROR_PASSWORD_RESET_EXPIRED'));
            return $this->redirectToRoute('homepage');
        }

        return [
            'form' => $form->createView(),
            'errors' => $errors
        ];
    }

    /**
     * @Route("/logout", name="security_logout")
     */
    public function logoutAction()
    {
        throw new Exception("This should not be reached");
    }

    /**
     * @Route("/security/subCheck1", name="security_subCheck1", options={"expose"=true})
     * @param Request $request
     * @return JsonResponse
     */
    public function subCheck1Action(Request $request)
    {
        $errors = [];
        $status = 200;

        $siret = $request->get('siret');
        $identifiant = $request->get('identifiant');

        $couple = $this->getDoctrine()->getRepository(Interlocuteur::class)->findOneBy([
            'siret' => $siret,
            'identifiant' => $identifiant
        ]);

        if(empty($couple)) {
            $status = 500;
            $errors['fields'] = ['siret' => null, 'identifiant'=> null];
            $errors['global'] = $this->get('translator')->trans("ERROR_SIRET_IDENTIFIANT");
        }

        if(empty($siret)) {
            $status = 500;
            $errors['fields']['siret'] = $this->get('translator')->trans("ERROR_EMPTY_SIRET");
        }
        if(empty($identifiant)) {
            $status = 500;
            $errors['fields']['identifiant'] = $this->get('translator')->trans("ERROR_EMPTY_IDENTIFIANT");
        }

        return new JsonResponse($errors, $status);
    }

    /**
     * @Route("/security/subCheck2", name="security_subCheck2", options={"expose"=true})
     * @param Request $request
     * @return JsonResponse
     */
    public function subCheck2Action(Request $request)
    {
        $errors = [];
        $status = 200;

        $email = $request->get('email');
        $emailCheck = $request->get('emailCheck');

        $unique = $this->getDoctrine()->getRepository(Utilisateur::class)->findOneBy(['email'=>$email]);

        if(!empty($unique)) {
            $status = 500;
            $errors['fields']['email'] = $this->get('translator')->trans("ERROR_EMAIL_EXISTS");
        }

        if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
            $status = 500;
            $errors['fields']['email'] = $this->get('translator')->trans("ERROR_EMAIL_VALIDATION");
        }

        if($email != $emailCheck) {
            $status = 500;
            $errors['fields']['email'] = null;
            $errors['fields']['emailCheck'] = $this->get('translator')->trans("ERROR_EMAIL_CONFIRMATION_FAIL");
        }

        return new JsonResponse($errors, $status);
    }

    /**
     * @Route("/security/subCheck3", name="security_subCheck3", options={"expose"=true})
     * @param Request $request
     * @return JsonResponse
     */
    public function subCheck3Action(Request $request)
    {
        $errors = [];
        $status = 200;

        $password = $request->get('password');
        $passwordCheck = $request->get('passwordCheck');

        $uppercase = preg_match('@[A-Z]@', $password);
        $lowercase = preg_match('@[a-z]@', $password);
        $number    = preg_match('@[0-9]@', $password);

        if(!$uppercase || !$lowercase || !$number || strlen($password) < 8) {
            $status = 500;
            $errors['fields']['password'] = null;
            $errors['fields']['passwordCheck'] = $this->get('translator')->trans("ERROR_PASSWORD_STRENGTH");
        }

        if($password != $passwordCheck) {
            $status = 500;
            $errors['fields']['password'] = null;
            $errors['fields']['passwordCheck'] = $this->get('translator')->trans("ERROR_PASSWORD_CONFIRMATION_FAIL");
        }

        return new JsonResponse($errors, $status);
    }

    /**
     * @Route("/security/subCheck4", name="security_subCheck4", options={"expose"=true})
     * @param Request $request
     * @return JsonResponse
     */
    public function subCheck4Action(Request $request)
    {
        $errors = [];
        $status = 200;

        $password = $request->get('password');
        $passwordCheck = $request->get('passwordCheck');

        $uppercase = preg_match('@[A-Z]@', $password);
        $lowercase = preg_match('@[a-z]@', $password);
        $number    = preg_match('@[0-9]@', $password);

        if(!$uppercase || !$lowercase || !$number || strlen($password) < 8) {
            $status = 500;
            $errors['fields']['password'] = null;
            $errors['fields']['passwordCheck'] = $this->get('translator')->trans("ERROR_PASSWORD_STRENGTH");
        }

        if($password != $passwordCheck) {
            $status = 500;
            $errors['fields']['password'] = null;
            $errors['fields']['passwordCheck'] = $this->get('translator')->trans("ERROR_PASSWORD_CONFIRMATION_FAIL");
        }

        return new JsonResponse($errors, $status);
    }

    /**
     * @Route("/security/validation/{hash}", name="security_validation")
     */
    public function validationAction($hash, Request $request)
    {
        $doc = $this->getDoctrine();
        $em = $doc->getManager();

        $user = $doc->getRepository('AppBundle:Utilisateur')->findOneBy(['hash'=>$hash]);
        if($user){

            $user->setHasValidated(1);
            $user->setHash(null);

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

            $this->get('session')->getFlashBag()->add('success', $this->get('translator')->trans('SUCCESS_USER_VALIDATION'));

            $request->getSession()->set(
                Security::LAST_USERNAME,
                $user->getEmail()
            );

        } else {
            $this->get('session')->getFlashBag()->add('error', $this->get('translator')->trans('ERROR_USER_VALIDATION'));
        }

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

    /**
     * @Route("/403error", name="non_autorise")
     * @Template("@App/Security/error403.html.twig")
     */
    public function error403Action()
    {
        return array();
    }

    /**
     * @Route("/404error", name="not_found")
     * @Template("@App/Security/error404.html.twig")
     */
    public function error404Action()
    {
        return array();
    }

    /**
     * @Route("/cookies", name="cookies")
     * @Template("@App/Security/cookies.html.twig")
     */
    public function cookiesAction()
    {
        return array();
    }


}