<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Form\FormError;
use Ramsey\Uuid\Uuid;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\Persistence\ManagerRegistry;

use App\Service\MessageService;
use App\Service\MailService;

use App\Entity\User;
use App\Entity\Usergroup;
use App\Entity\Registration;

use App\Form\RegistrationType;
use App\Form\ResetpwdType;

class RegistrationController extends AbstractController
{
    private $nameentity  = 'Registration';
    private $labelentity = 'App\Entity\Registration';
    private $labelroute  = 'app_core_config_registration';
    private $labeldata   = 'registration';
    private $labeldatas  = 'registrations';

    private $wss;
    private $mail;
    
    public function __construct(messageService $wss,mailService $mail)
    {
        $this->wss = $wss;
        $this->mail = $mail;
    }

    public function list()
    {
        $moderegistration   = $this->getParameter('moderegistration');
        $masteridentity     = $this->getParameter('masteridentity');
        if($moderegistration=="none"||$masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');

        return $this->render($this->nameentity.'\list.html.twig',[
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,               
        ]);
    }

    public function ajaxlist(Request $request, ManagerRegistry $em)
    {
        // S'assurer que c'est un appel ajax
        if (!$request->isXmlHttpRequest()) {
            return new JsonResponse(array('message' => 'Interdit'), 400);
        }
        
        $start=$request->query->get('start');
        $length= $request->query->get('length');
        $search= $request->query->get('search');
        $draw= $request->query->get('draw');
        $order= $request->query->get('order');
      
        // Nombre total d'enregistrement
        if($this->isGranted('ROLE_ADMIN'))
            $total = $em->getManager()->createQueryBuilder()->select('COUNT(registration)')->from($this->labelentity,'registration')->getQuery()->getSingleScalarResult();
        else {
                $usermodo=$this->getUser()->getId();
                $total = $em->getManager()->createQueryBuilder()
                            ->select('COUNT(registration)')
                            ->from($this->labelentity,'registration')
                            ->from("App\Entity\UserModo",'usermodo')
                            ->where("usermodo.niveau01 = registration.niveau01")
                            ->andWhere("usermodo.user = :userid")
                            ->setParameter("userid", $usermodo)
                            ->getQuery()->getSingleScalarResult();                
            }

        // Nombre d'enregistrement filtré
        if($search["value"]=="")
            $totalf = $total;
        else {
            if($this->isGranted('ROLE_ADMIN'))
                $totalf= $em->getManager()->createQueryBuilder()
                            ->select('COUNT(registration)')
                            ->from($this->labelentity,'registration')
                            ->where('registration.username LIKE :value')
                            ->orWhere('registration.email LIKE :value')
                            ->setParameter("value", "%".$search["value"]."%")
                            ->getQuery()
                            ->getSingleScalarResult();
            else
                $totalf= $em->getManager()->createQueryBuilder()
                            ->select('COUNT(registration)')
                            ->from($this->labelentity,'registration')
                            ->from("App\Entity\UserModo",'usermodo')
                            ->where('registration.username LIKE :value OR registration.email LIKE :value')
                            ->andWhere("usermodo.niveau01 = registration.niveau01")
                            ->andWhere("usermodo.user = :userid")                            
                            ->setParameter("value", "%".$search["value"]."%")
                            ->setParameter("userid", $usermodo)
                            ->getQuery()
                            ->getSingleScalarResult();   
        }

        // Construction du tableau de retour
        $output = array(
            'draw' => $draw,
            'recordsFiltered' => $totalf,
            'recordsTotal' => $total,
            'data' => array(),
        );

        // Parcours des Enregistrement
        $qb = $em->getManager()->createQueryBuilder();
        if($this->isGranted('ROLE_ADMIN')) {
            $qb->select('registration')->from($this->labelentity,'registration')->from('App\Entity\Niveau01','niveau01');
            $qb->where('registration.niveau01=niveau01.id');
        }
        else{
            $qb->select('registration')->from($this->labelentity,'registration')->from('App\Entity\Niveau01','niveau01')->from("App\Entity\UserModo",'usermodo');
            $qb->where('registration.niveau01=niveau01.id')
               ->andWhere("usermodo.niveau01 = registration.niveau01")
               ->andWhere("usermodo.user = :userid")                            
               ->setParameter("userid", $usermodo);            
        }


        if($search["value"]!="") {
            $qb ->andWhere('registration.username LIKE :value OR registration.email LIKE :value OR niveau01.label LIKE :value')
                ->setParameter("value", "%".$search["value"]."%");
        }
        switch($order[0]["column"]) {
            case 1 : 
            $qb->orderBy('registration.username',$order[0]["dir"]);
            break;

            case 2 : 
            $qb->orderBy('registration.email',$order[0]["dir"]);
            break;

            case 3 : 
            $qb->orderBy('niveau01.label',$order[0]["dir"]);
            break;
            
            case 4 : 
            $qb->orderBy('registration.statut',$order[0]["dir"]);
            break;

            case 5 : 
            $qb->orderBy('registration.keyexpire',$order[0]["dir"]);
            break;            
        }

        $datas=$qb->setFirstResult($start)->setMaxResults($length)->getQuery()->getResult();

        foreach($datas as $data) {
            $action ="";
            // Si inscription non périmée
            if($data->getStatut()->getId()<=2) {
                $action.="<a href='".$this->generateUrl('app_core_config_registration_send', array('id'=>$data->getId()))."' title='Modifier'><i class='fa fa-file fa-fw fa-2x'></i></a>";    
            }
            $action.="<a href='".$this->generateUrl('app_core_config_registration_delete', array('id'=>$data->getId()))."' title='Supprimer'><i class='fa fa-trash fa-fw fa-2x'></i></a>";
            array_push($output["data"],array(
                $action,
                $data->getUsername(),
                $data->getEmail(),
                $data->getNiveau01()->getLabel()."<br>".$data->getNiveau01other(),
                $data->getStatut()->getLabel(),
                (is_null($data->getKeyexpire())?"":$data->getKeyexpire()->format('d/m/Y H:i:s'))
            ));
        }

        // Retour
        return new Response(json_encode($output), 200);
    }



    public function submit(Request $request, ManagerRegistry $em)
    {
        $moderegistration   = $this->getParameter('moderegistration');
        $masteridentity     = $this->getParameter('masteridentity');
        $groupid            = $request->query->get('group');

        if($moderegistration=="none"||$masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');

        $data = new Registration();
        $data->setVisible(true);
        $data->setIfad(($this->getParameter("ldap_type")=="AD"));

        $config=$em->getRepository('App\Entity\Config')->find("datauser");
        $fields=$config->getValue();
        $fields=json_decode($fields,true);

        // Création du formulaire
        $form = $this->createForm(RegistrationType::class,$data,array("mode"=>"submit","fields"=>$fields));

        // Récupération des data du formulaire
        $form->handleRequest($request);

        // si mode de registration byuser
        if($moderegistration=="byuser") {
            $idstatut=2;
        }
        else { 
            // On recherche le domaine du mail dans la liste blanche
            $email=explode("@",$data->getEmail());
            $domaine=end($email);
            $whitelist = $em->getRepository("App\Entity\Whitelist")->findBy(["label"=>$domaine]);
            $idstatut=(!$whitelist?1:2);
        }
        $statut = $em->getRepository("App\Entity\Statut")->find($idstatut);
        $data->setStatut($statut);

        // Sur erreur
        $this->getErrorForm($em,null,$form,$request,$data,"submit",$idstatut);

        // Sur validation
        if ($form->get('submit')->isClicked() && $form->isValid()) {
            
            $data = $form->getData();

            // On enregistre l'invitation à un groupe dans l'inscription
            $data->setGroupid($groupid);

            $appname = $request->getSession()->get('appname');
            $noreply = $this->getParameter('noreply');
            $keyterm = $this->getParameter('keyterm');

            // si non : validation par administrateur
            if($idstatut==1) {
                $niveau01id=$data->getNiveau01()->getId();

                // Email à destination de l'inscript pour le prévenir qu'un administrateur doit valider
                $subject=$appname." : Inscription en cours de validation";
                $body="Votre inscription a bien été enregistrée.<br>Cependant, un administrateur doit encore valider votre inscription avant que celle-ci ne devienne effective.<br><br>Vous recevrez un mail quand votre inscription sera validée";
                $to = $data->getEmail();
                $from =  $noreply;
                $fromName = $appname;
                $this->mail->sendEmail($subject, $body, $to, $from, $fromName); 
                $info=$body;

                // Email à l'ensemble administrateurs pour les prévenir qu'il y a une personne à valider
                $emailadmins= $em->getManager()->createQueryBuilder()
                                 ->select('table.email')
                                 ->from("App\Entity\User",'table')
                                 ->where('table.role = :value')
                                 ->setParameter("value", "ROLE_ADMIN")
                                 ->getQuery()
                                 ->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR);
                $to=array();
                $from = $noreply;
                $fromName = $appname;                
                foreach($emailadmins as $emailadmin) {
                    array_push($to,$emailadmin["email"]);
                }

                // Email à l'ensemble des modérateurs du service pour les prévenir qu'il y a une personne à valider
                $emailmodos= $em->getManager()->createQueryBuilder()
                                 ->select('user.email')
                                 ->from("App\Entity\UserModo",'usermodo')
                                 ->from("App\Entity\User",'user')
                                 ->where("usermodo.niveau01 = :niveau01id")
                                 ->andWhere("user.id = usermodo.user")
                                 ->andWhere('user.role = :value')
                                 ->setParameter("niveau01id", $niveau01id)
                                 ->setParameter("value", "ROLE_MODO")
                                 ->getQuery()
                                 ->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR);
                $from =  $noreply;
                $fromName = $appname;                
                foreach($emailmodos as $emailmodo) {
                    array_push($to,$emailmodo["email"]);
                }
                
                $url = $this->generateUrl('app_core_config_registration', [], UrlGeneratorInterface::ABSOLUTE_URL);
                $motivation = "Login = ".$data->getUsername()."\n";
                $motivation.= "Nom = ".$data->getLastname()."\n";
                $motivation.= "Prénom = ".$data->getFirstname()."\n";
                $motivation.= "Mail = ".$data->getEmail()."\n";
                $motivation.= $this->getParameter("labelniveau01")." = ".$data->getNiveau01()->getLabel()." ".$data->getNiveau01other()."\n\n";
                $motivation.= $data->getMotivation();

                $subject=$appname." : Inscription à valider";
                $body="Un utilisateur dont le mail n’est pas en liste blanche souhaite s’inscrire au ".$appname.".\nMerci d’approuver son inscription pour finaliser celle-ci.<br><br>Veuillez vérifier cette inscription à cette adresse:<br><a href='$url'>$url</a><br><br>".nl2br($motivation);
                $this->mail->sendEmail($subject, $body, $to, $from, $fromName); 
            }

            // si oui : Domaine de confiance : email de validation d'inscription directement à l'utilisateur
            else {

                // Génération d'une clé de validation
                $key = Uuid::uuid4();

                // Génération de la date de fin de validité de la clé
                $keyexpire=new \DateTime();
                $keyexpire->add(new \DateInterval('PT'.$keyterm.'H'));

                // Enregistrement des valeurs
                $data->setKeyvalue($key->toString());
                $data->setKeyexpire($keyexpire);

                // Email à l'utilisateur
                $url = $this->generateUrl('app_core_registration_validation', array("key"=>$key->toString()), UrlGeneratorInterface::ABSOLUTE_URL);
                $subject=$appname." : confirmation de validation";
                $body="<p>Merci de confirmer votre inscription en cliquant sur le lien suivant</p><p><a href='".$url."'>".$url."</a></p><br><p>Attention vous disposez d’un délai de 8 heures pour le faire. Passé ce délai, vous devrez vous réinscrire.</p>";
                $info="Vous allez recevoir un mail de confirmation pour finaliser votre inscription";
                $to = $data->getEmail();
                $from =  $noreply;
                $fromName = $appname;
                $this->mail->sendEmail($subject, $body, $to, $from, $fromName);              
            }

            // Sauvegarde
            $em->getManager()->persist($data);
            $em->getManager()->flush();
                       
            // A voir retour sur un écran d'info indiquant si validation par admion ou s'il doit matter ses email
            $request->getSession()->set('registrationinfo', $info);
            $request->getSession()->set('registrationmode', "info");
            $request->getSession()->set('registrationredirectto', null);

            return $this->redirectToRoute('app_core_registration_info');
        }
        else {
            return $this->render($this->nameentity.'\edit.html.twig', [
                'useheader'         => true,
                'usemenu'           => false,
                'usesidebar'        => false,               
                $this->labeldata    => $data,
                'mode'              => 'submit',
                'form'              => $form->createView()
            ]);
        }

    }
    public function info(Request $request, ManagerRegistry $em)
    {
        $info = $request->getSession()->get('registrationinfo');
        $mode = $request->getSession()->get('registrationmode');
        $redirectto = $request->getSession()->get('registrationredirectto');


        return $this->render($this->nameentity.'\info.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => false,                   
            'info'              => $info,
            'mode'              => $mode,
            'redirectto'         => $redirectto,
        ]);
    }

    public function send($id,Request $request, ManagerRegistry $em)
    {
        $moderegistration   = $this->getParameter('moderegistration');
        $masteridentity     = $this->getParameter('masteridentity');
        if($moderegistration=="none"||$masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');

        // Récupération de l'enregistrement courant 
        $data=$this->getData($em,$id);
        $config=$em->getRepository('App\Entity\Config')->find("datauser");
        $fields=$config->getValue();
        $fields=json_decode($fields,true);
        
        // Vérifier que cet enregistrement est modifiable
                                    
        // Création du formulaire
        $form = $this->createForm(RegistrationType::class,$data,array("mode"=>"send","fields"=>$fields));

        // Récupération des data du formulaire
        $form->handleRequest($request);
    
        // Sur erreur
        $this->getErrorForm($em,$id,$form,$request,$data,"send",null);

        // Sur validation
        if ($form->get('save')->isClicked() && $form->isValid()) {
            $data = $form->getData();

            // Sauvegarde
            $em->getManager()->flush();

            return $this->redirectToRoute('app_core_config_registration');
        }
        
        // Sur validation
        if ($form->get('submit')->isClicked() && $form->isValid()) {
            $data = $form->getData();
            
            $appname = $request->getSession()->get('appname');
            $noreply = $this->getParameter('noreply');
            $keyterm = $this->getParameter('keyterm');
            
            // Génération d'une clé de validation
            $key = Uuid::uuid4();

            // Génération de la date de fin de validité de la clé
            $keyexpire=new \DateTime();
            $keyexpire->add(new \DateInterval('PT'.$keyterm.'H'));

            // Enregistrement des valeurs
            $data->setKeyvalue($key->toString());
            $data->setKeyexpire($keyexpire);

            // Statut en attente validation utilisateur
            $data->setStatut($em->getRepository("App\Entity\Statut")->find(2));

            // Email à l'utilisateur
            $url = $this->generateUrl('app_core_registration_validation', array("key"=>$key->toString()), UrlGeneratorInterface::ABSOLUTE_URL);
            $subject=$appname." : confirmation de validation";
            $body="<p>Merci de confirmer votre inscription en cliquant sur le lien suivant</p><p><a href='".$url."'>".$url."</a></p><br><p>Attention vous disposez d’un délai de 8 heures pour le faire. Passé ce délai, vous devrez vous réinscrire.</p>";
            $info="Vous allez recevoir un mail de confirmation pour finaliser votre inscription";
            $to = $data->getEmail();
            $from =  $noreply;
            $fromName = $appname;
            $this->mail->sendEmail($subject, $body, $to, $from, $fromName);

            // Sauvegarde
            $em->getManager()->flush();

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

        // Affichage du formulaire
        return $this->render($this->nameentity.'\edit.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,              
            $this->labeldata    => $data,
            'mode'              => 'send',
            'form'              => $form->createView()
        ]);       
    }

    public function validation($key,Request $request, ManagerRegistry $em)
    {
        $moderegistration   = $this->getParameter('moderegistration');
        $masteridentity     = $this->getParameter('masteridentity');

        if($moderegistration=="none"||$masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');

        $now=new \DateTime();
        
        $data = $em->getManager()->createQueryBuilder()
                    ->select('table')
                    ->from($this->labelentity,'table')
                    ->where('table.keyvalue= :key')
                    ->andWhere('table.keyexpire >= :date')
                    ->setParameter("key", $key)
                    ->setParameter("date", $now)
                    ->getQuery()
                    ->getResult();

        if(!$data) {
            $info="Clé de validation invalide";
            $mode="danger";

            $request->getSession()->set('registrationinfo', $info);
            $request->getSession()->set('registrationmode', $mode); 
            $request->getSession()->set('registrationredirectto', null); 
        }
        else {
            $url=$this->getUrlLogin();
            $info="<p>Votre compte est à présent activé</p><p>Vous allez être redirigé vers la mire de connexion</p><p><a href='".$url."'>Connexion</a>";
            $mode="success";

            $request->getSession()->set('registrationinfo', $info);
            $request->getSession()->set('registrationmode', $mode);  

            // Initialisation de l'enregistrement
            $user = new User();
            $user->setAvatar("noavatar.png");
            $user->setUsername($data[0]->getUsername());
            $user->setApikey(Uuid::uuid4());
            $user->setEmail($data[0]->getEmail());
            $user->setLastname($data[0]->getLastname());
            $user->setFirstname($data[0]->getFirstname());
            $user->setSalt($data[0]->getSalt());
            $user->setPasswordDirect($data[0]->getPassword());
            $user->setVisible($data[0]->getVisible());
            $user->setMotivation($data[0]->getMotivation());
            $user->setNote($data[0]->getNote());

            $user->setNiveau01($data[0]->getNiveau01());
            $user->setSiren($data[0]->getNiveau01()->getSiren());
            $user->setNiveau01other($data[0]->getNiveau01other());

            $user->setNiveau02($data[0]->getNiveau02());
            if($data[0]->getNiveau02()!==null) $user->setSiret($data[0]->getNiveau02()->getSiret());

            $user->setUsualname($data[0]->getUsualname());
            $user->setTelephonenumber($data[0]->getTelephonenumber());
            $user->setPostaladress($data[0]->getPostaladress());
            $user->setGivensname($data[0]->getGivensname());
            $user->setBirthdate($data[0]->getBirthdate());
            $user->setGender($data[0]->getGender());
            $user->setJob($data[0]->getJob());
            $user->setPosition($data[0]->getPosition());
            $user->setBirthcountry($data[0]->getBirthcountry());
            $user->setBirthplace($data[0]->getBirthplace());

            $user->setRole("ROLE_USER");
            $user->setAuthlevel("simple");
            $user->setBelongingpopulation("agent");

            // Sauvegarde
            $em->getManager()->persist($user);
            $em->getManager()->flush();

            // Si invitation à un groupe : on le rattache directement à ce groupe
            $groupid=$data[0]->getGroupid();

            $userid=$user->getId();
            if($groupid) {
                $group=$em->getRepository("App\Entity\Group")->find($groupid);
                if($group) {
                    $idpage =$group->getPages()->first()->getId();
                    $url = $this->generateUrl('app_core_redirect', ["route"=>"app_core_home","id"=>$idpage], UrlGeneratorInterface::ABSOLUTE_URL);
                    $info="<p>Votre compte est à présent activé</p><p>Vous allez être redirigé vers la mire de connexion puis vers votre groupe de travail</p><p><a href='".$url."'>Connexion</a>";
                    $request->getSession()->set('registrationinfo', $info);                    
                    $request->getSession()->set('registrationredirectto', $url);

                    $key = Uuid::uuid4();
                    $usergroup=new UserGroup();
                    $user=$em->getRepository("App\Entity\User")->find($userid);
                    $usergroup->setUser($user);
                    $usergroup->setGroup($group);
                    $usergroup->setKeyvalue($key);
                    $usergroup->setRolegroup(0);
                    $em->getManager()->persist($usergroup);
                    $em->getManager()->flush();
            
                    // Notification message
                    $message="Inscription de l'utilisateur<br>".$user->getLastname()." ".$user->getFirstname()."<br>Inscription via invitation";
                    $this->wss->addMessage($user->getApikey(),$groupid,$message);
                }
            }

            $em->getManager()->remove($data[0]);
            $em->getManager()->flush();
        }
        
        return $this->redirectToRoute('app_core_registration_info');
    }


    public function delete($id,Request $request, ManagerRegistry $em)
    {
        $moderegistration   = $this->getParameter('moderegistration');
        $masteridentity     = $this->getParameter('masteridentity');
        if($moderegistration=="none"||$masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');

        // Récupération de l'enregistrement courant
        $data=$this->getData($em,$id);
        $config=$em->getRepository('App\Entity\Config')->find("datauser");
        $fields=$config->getValue();
        $fields=json_decode($fields,true);

        // Vérifier que cet enregistrement est supprimable

        // Création du formulaire
        $form = $this->createForm(RegistrationType::class,$data,array("mode"=>"delete","fields"=>$fields));

        // Récupération des data du formulaire
        $form->handleRequest($request);

        // Sur erreur
        $this->getErrorForm($em,$id,$form,$request,$data,"delete",null);

        // Sur validation
        if ($form->get('submit')->isClicked() && $form->isValid()) {
            $em->getManager()->remove($data);
            $em->getManager()->flush();

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

        // Affichage du formulaire
        return $this->render($this->nameentity.'\edit.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,               
            $this->labeldata    => $data,
            'mode'              => 'delete',
            'form'              => $form->createView()
        ]);
    }

    public function resetpwd01(Request $request, ManagerRegistry $em)
    {
        $moderegistration   = $this->getParameter('moderegistration');
        $masteridentity     = $this->getParameter('masteridentity');
        if($masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');

        // Création du formulaire
        $form = $this->createForm(ResetpwdType::class,null,array("mode"=>"resetpwd01"));

        // Récupération des data du formulaire
        $form->handleRequest($request);
        $data = $form->getData();

        // Sur erreur
        if ($form->get('submit')->isClicked()) {
            // On s'assure que le mail existe dans la base des utilisateurs
            $user=$this->getUserBy($em,"email",$data["email"]);
            if(!$user) {
                $form->addError(new FormError('Mail inconnu'));
    
                $errors = $form->getErrors();
                foreach( $errors as $error ) {
                    $request->getSession()->getFlashBag()->add("error", $error->getMessage());
                }                
            }
        }

        // Sur validation
        if ($form->get('submit')->isClicked() && $form->isValid()) {
            $appname = $request->getSession()->get('appname');
            $noreply = $this->getParameter('noreply');
            $keyterm = $this->getParameter('keyterm');

            // Génération d'une clé de validation
            $key = Uuid::uuid4();

            // Génération de la date de fin de validité de la clé
            $keyexpire=new \DateTime();
            $keyexpire->add(new \DateInterval('PT'.$keyterm.'H'));

            // Enregistrement des valeurs
            $user[0]->setKeyvalue($key->toString());
            $user[0]->setKeyexpire($keyexpire);

            // Sauvegarde
            $em->getManager()->flush();

            // Email au user
            $url = $this->generateUrl('app_core_resetpwd02', array("key"=>$key->toString()), UrlGeneratorInterface::ABSOLUTE_URL);
            $subject=$appname." : réinitialisation mot de passe";
            $body="<p>Merci de réinitialiser votre mot de passe en cliquant sur le lien suivant</p><p><a href='".$url."'>".$url."</a></p><br><p>Attention vous disposez d’un délai de 8 heures pour le faire.</p><p>Vous pourrez par la suite vous connecter avec votre login : ".$user[0]->getUsername()."</p>";
            $to = $user[0]->getEmail();
            $from =  $noreply;
            $fromName = $appname;
            $this->mail->sendEmail($subject, $body, $to, $from, $fromName);
            
            // Info
            $info="Vous allez recevoir un mail avec lien qui vous permettra de réinitialiser votre mot de passe";
            $mode="info";
            $request->getSession()->set('registrationinfo', $info);
            $request->getSession()->set('registrationmode', $mode);  
            $request->getSession()->set('registrationredirectto', null); 
            return $this->redirectToRoute('app_core_registration_info');
        }

        // Affichage du formulaire
        return $this->render($this->nameentity.'\resetpwd01.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => false,               
            'form'              => $form->createView()
        ]);
    }

    public function resetpwd02($key,Request $request, ManagerRegistry $em)
    {
        $masteridentity     = $this->getParameter('masteridentity');
        if($masteridentity!="SQL")
            throw $this->createNotFoundException('Permission denied');
                    
        $now=new \DateTime();
        
        $user = $em->getManager()->createQueryBuilder()
                    ->select('table')
                    ->from("App\Entity\User",'table')
                    ->where('table.keyvalue= :key')
                    ->andWhere('table.keyexpire >= :date')
                    ->setParameter("key", $key)
                    ->setParameter("date", $now)
                    ->getQuery()
                    ->getResult();

        if(!$user) {
            $info="Clé de validation invalide";
            $mode="danger";
            $request->getSession()->set('registrationinfo', $info);
            $request->getSession()->set('registrationmode', $mode);  
            $request->getSession()->set('registrationredirectto', null);  
            return $this->redirectToRoute('app_core_registration_info');
        }
        else {
            // Création du formulaire
            $form = $this->createForm(ResetpwdType::class,null,array("mode"=>"resetpwd02"));

            // Récupération des data du formulaire
            $form->handleRequest($request);
            $data = $form->getData();

            if($form->get('submit')) {
                $password=$data["password"];
                $message="";
                if(!empty($password)) {
                    if (strlen($password) < $this->getParameter("minpassword")) {
                        $message = "Votre mot de passe doit contenir au minimum ".$this->getParameter("minpassword")." caractères, constitué de chiffres, de lettres et caractères spéciaux";
                    }
                    elseif(!preg_match("#[0-9]+#",$password)) {
                        $message = "Votre mot de passe doit contenir au minimum ".$this->getParameter("minpassword")." caractères, constitué de chiffres, de lettres et caractères spéciaux";
                    }
                    elseif(!preg_match("#[a-zA-Z]+#",$password)) {
                        $message = "Votre mot de passe doit contenir au minimum ".$this->getParameter("minpassword")." caractères, constitué de chiffres, de lettres et caractères spéciaux";
                    }
                    elseif(!preg_match("/[|!@#$%&*\/=?,;.:\-_+~^\\\]/",$password)) {
                        $message = "Votre mot de passe doit contenir au minimum ".$this->getParameter("minpassword")." caractères, constitué de chiffres, de lettres et caractères spéciaux";
                    }
                }           
                
                if($message!="") {
                    $form->addError(new FormError($message));
                    $errors = $form->getErrors();
                    foreach( $errors as $error ) {
                        $request->getSession()->getFlashBag()->add("error", $error->getMessage());
                    }                
                }
            }
            
            if ($form->get('submit')->isClicked() && $form->isValid()) {
                $user[0]->setPassword($data["password"]);
                $user[0]->setKeyvalue(null);
                $user[0]->setKeyexpire(null);

                // Sauvegarde
                $em->getManager()->flush();  

                $url=$this->getUrlLogin();
                $info="<p>Nouveau mot de passe prise en compte</p><p>Vous allez être redirigé vers la mire de connexion</p><p><a href='".$url."'>Connexion</a>";
                $mode="success";
                $request->getSession()->set('registrationinfo', $info);
                $request->getSession()->set('registrationmode', $mode);  
                $request->getSession()->set('registrationredirectto', null);  
                return $this->redirectToRoute('app_core_registration_info');
            }

            // Affichage du formulaire
            return $this->render($this->nameentity.'\resetpwd02.html.twig', [
                'useheader'         => true,
                'usemenu'           => false,
                'usesidebar'        => false,                   
                'form'              => $form->createView()
            ]);            
        }
    }

    protected function getUrlLogin()
    {
        $url = $this->generateUrl('app_core_login');
        return $url;
    }


    protected function getDatas($em)
    {
        $datas = $em->getRepository($this->labelentity)->findAll();
        return $datas;
    }

    protected function getData($em,$id)
    {
        $data = $em->getRepository($this->labelentity)->find($id);

        if (!$data) {
            throw $this->createNotFoundException('Unable to find '.$this->labeldata);
        }

        return $data;
    }

    protected function getUserBy($em,$key,$value)
    {
        $datas = $em->getManager()->createQueryBuilder()
                      ->select('u')
                      ->from('App\Entity\User',  'u')
                      ->where('u.'.$key.'=:value')
                      ->getQuery()->setParameter("value", $value)
                      ->getResult();
        if (!$datas) return false;
        else return $datas;
    }


    protected function getErrorForm($em,$id,$form,$request,$data,$mode,$idstatut) {
        if ($form->get('submit')->isClicked()&&$mode=="delete") {
        }

        if ($form->get('submit')->isClicked() && $mode=="submit") {
            // Taille du login > 5
            if (is_null($data->getUsername()) || strlen($data->getUsername()) < '5') {
                $form->addError(new FormError('Taille minimum du login 5 caractères'));
            }

            // On s'assure que le username ne contient pas des caractères speciaux
            $string = preg_replace('~[^@a-zA-Z0-9._-]~', '', $data->getUsername());
            if($string!=$data->getUsername())
            {
                $form->addError(new FormError('Caractères interdit dans votre login'));
            }
            
            // On s'assure que le username et le mail n'existe pas dans la table des users
            if($this->getUserBy($em,"username",$data->getUsername())||$this->getUserBy($em,"email",$data->getEmail())) {
                $form->addError(new FormError('Un utilisateur utilise déjà ce login ou cet email'));
            }

            // Si niveau01 commence par autre = niveau01other obligatoire
            $niveau01=strtolower($data->getNiveau01()->getLabel());
            if(stripos($niveau01,"autre")===0) {
                if(!$data->getNiveau01other()) {
                    $form->addError(new FormError("Merci de compléter le champ 'Autre ".$this->getParameter("labelniveau01")."'")); 
                }
            }

            // Si validation par administrateur demander une motivation
            $moderegistration   = $this->getParameter('moderegistration');
            if(is_null($data->getMotivation())&&$moderegistration=="byadmin") {
                // On recherche le domaine du mail dans la liste blanche
                $email=explode("@",$data->getEmail());
                $domaine=end($email);
                $whitelist = $em->getRepository("App\Entity\Whitelist")->findBy(["label"=>$domaine]);
                if(!$whitelist)
                    $form->addError(new FormError("Attention, le suffixe de votre adresse mail n’est pas dans la liste des administrations autorisées, merci de bien vouloir privilégier votre adresse professionnelle si vous en avez une.<br>Si ce n’est pas le cas, il faut que vous renseigniez la case motivation de votre demande")); 
            }
        }

        if ($form->get('submit')->isClicked() && !$form->isValid()) {
            $errors = $form->getErrors();
            foreach( $errors as $error ) {
                $request->getSession()->getFlashBag()->add("error", $error->getMessage());
            }
        }
    }


}
