<?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\Filesystem\Filesystem;
use Symfony\Component\Form\FormError;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpKernel\KernelInterface;

use App\Entity\Page;
use App\Form\PageSubmitType;
use App\Form\PageUpdateToolType;
use App\Form\PageUpdateURLType;
use App\Form\PageUpdateWidgetType;
use App\Form\PageUpdateEditorType;
use App\Form\PageShareType;

class PageController extends AbstractController
{
    private $nameentity  = 'Page';
    private $labelentity="App\Entity\Page";
    private $routeprimary="app_portal_config_page";
    private $appKernel;

    public function __construct(KernelInterface $appKernel)
    {
        $this->appKernel = $appKernel;
    }

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

    public function ajaxlist($access="config",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');
        $alluser= $request->query->get('alluser');

        // On sauvegarde en session le flag alluser
        $request->getSession()->set("alluserpage",$alluser);

        // Query de base
        $qbase=$em->getManager()->createQueryBuilder()->from($this->labelentity,'table');
        $qsearch=$em->getManager()->createQueryBuilder()->from($this->labelentity,'table');

        if($alluser=="false") {
            $qbase->where("table.user is null");
            $qbase->andWhere('table.parentfor is null') ;
            $qsearch->where("table.user is null");
            $qsearch->andWhere('table.parentfor is null') ;

        }
        else {
            $qbase->from('App\Entity\User','user')
                  ->where("table.user=user");

            $qsearch->from('App\Entity\User','user')
                    ->where("table.user=user");
        }

        if($alluser=="false") 
            $qsearch->andwhere('table.id LIKE :value OR table.name LIKE :value');
        else
            $qsearch->andWhere('table.id LIKE :value OR table.name LIKE :value OR user.username LIKE :value') ;  

        
        $qsearch->setParameter("value", "%".$search["value"]."%");                  

        // Nombre total d'enregistrement
        $total = $qbase->select('COUNT(table)')->getQuery()->getSingleScalarResult();
        

        // Nombre d'enregistrement filtré
        if($search["value"]=="")
            $totalf = $total;
        else
            $totalf= $qsearch->select('COUNT(table)')->getQuery()->getSingleScalarResult();
        

        // Parcours des Enregistrement
        if($search["value"]=="")
            $qb = $qbase->select('table');
        else
            $qb = $qsearch->select('table');

        // Order
        switch($order[0]["column"]) {
            case 1 : 
            $qb->orderBy('table.roworder',$order[0]["dir"]);
            break;
            case 2 : 
            $qb->orderBy('table.name',$order[0]["dir"]);
            break;
            case 4 : 
            if($alluser=="true") $qb->orderBy('user.username',$order[0]["dir"]);
            break;            
        }

        // Execution de la requete d'affichage
        $datas=$qb->setFirstResult($start)->setMaxResults($length)->getQuery()->getResult();

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

            $route=str_replace("_config_","_".$access."_",$this->routeprimary);
            $action = "";
            //$action.="<a href='".$this->generateUrl($route.'_update', array('id'=>$data->getId()))."'><i class='fa fa-file fa-fw'></i></a>";
            $action.="<a href='".$this->generateUrl($route.'_update', array('id'=>$data->getId()))."' title='Configurer'><i class='fa fa-cog fa-fw fa-2x'></i></a>";
            $action.="<a href='".$this->generateUrl($route.'_view', array('id'=>$data->getId()))."' title='Afficher'><i class='fa fa-eye fa-fw fa-2x'></i></a>";
            $action.="<a href='".$this->generateUrl($route.'_delete', array('id'=>$data->getId()))."' data-method='delete' title='Supprimer'><i class='fa fa-trash fa-fw fa-2x'></i></a>";

            $user="";
            if($data->getUser()) {
                $user.="<img src='/".$this->getParameter('alias')."uploads/avatar/".$data->getUser()->getAvatar()."' class='avatar' style='margin:0px 5px 0px 0px;display:inline-block;'>";
                $user.=$data->getUser()->getUsername();
            }

            $icon="";
            if($data->getFonticon())
                $icon.="<i class='".$data->getFonticon()." fa-fw'></i>&nbsp;";

            array_push($output["data"],[
                $action,
                $data->getRoworder(),
                $icon.$data->getName(),
                $data->getPagecategory()->getName(),
                $user
            ]);
        }

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

    public function ajaxseleclist(Request $request, ManagerRegistry $em)
    {
        // S'assurer que c'est un appel ajax
        if (!$request->isXmlHttpRequest()) {
            return new JsonResponse(array('message' => 'Interdit'), 400);
        }

        $output=array();
        $page_limit=$request->query->get('page_limit');
        $q=$request->query->get('q');
        
        $qb = $em->getManager()->createQueryBuilder();
        $qb->select('table')->from("App\Entity\Page",'table')
           ->where('table.name LIKE :value')
           ->setParameter("value", "%".$q."%")
           ->orderBy('table.name');
        
        $datas=$qb->setFirstResult(0)->setMaxResults($page_limit)->getQuery()->getResult();
        foreach($datas as $data) {
            array_push($output,array("id"=>$data->getId(),"text"=>$data->getName()));
        }

        $response = new Response(json_encode($output));    
        $response->headers->set('Content-Type', 'application/json');      
        return $response;
    } 

    private function entityForm($access="config",Page $entity, ManagerRegistry $em)
    {
        $route=str_replace("_config_","_".$access."_",$this->routeprimary);

        if ($em->getManager()->contains($entity)) {
            // Type Tools
            if($entity->getPagecategory()->getId()<0 ) {
                return $this->createForm(PageUpdateToolType::class, $entity, [
                    "mode"   => "update",
                    "access" => $access
                ]);
            }

            // Type URL
            if($entity->getPagecategory()->getId()==1 ) {
                return $this->createForm(PageUpdateURLType::class, $entity, [
                    "mode"   => "update",
                    "access" => $access
                ]);
            }
            // Type Widget
            elseif($entity->getPagecategory()->getId()==2 ) {
                return $this->createForm(PageUpdateWidgetType::class, $entity, [
                    "mode"   => "update",
                    "access" => $access
                ]);
            }
            // Type Editeur
            elseif($entity->getPagecategory()->getId()==3 ) {
                return $this->createForm(PageUpdateEditorType::class, $entity, [
                    "mode"   => "update",
                    "access" => $access
                ]);
            }
        }
        else {
            return $this->createForm(PageSubmitType::class, $entity, [
                "mode"   => "update",
                "access" => $access,
                "user" => $this->getUser()
            ]);
        }
    }

    public function submit($access="config",Request $request, ManagerRegistry $em)
    {
        if($access=="user"&&!$request->getSession()->get('cancreatepage'))
            throw $this->createNotFoundException('Permission denied');

        $entity = new Page();
        $entity->setMaxwidth(0);
        $entity->setRoworder(0);
        $entity->getFgpreference(true);

        $form   = $this->entityForm($access,$entity,$em);
        $form->handleRequest($request);


        // Sur erreur
        $this->getErrorForm(null,$form,$request,$entity,"submit");
        
        // Sur validation
        if ($form->get('submit')->isClicked() && $form->isValid()) {  
            if($access=="user") $entity->setUser($this->getUser());

            // Si template on duplique le template
            if($entity->getPage()) {
                $page=$em->getManager()->getRepository("App\Entity\Page")->clonePage($this->getUser(),$entity->getPage());
                $page->setName($entity->getName());
                $page->setRoworder($entity->getRoworder());
                $page->setMaxwidth($entity->getMaxwidth());
                foreach($entity->getGroups() as $group) {
                    $page->addGroup($group);
                }
                $em->getManager()->persist($page);
                $em->getManager()->flush();
                $route=str_replace("_config_","_".$access."_",$this->routeprimary);
                return $this->redirect($this->generateUrl($route.'_update',["id"=>$page->getId()]));
            }
            else {
                $em->getManager()->persist($entity);
                $em->getManager()->flush();
                $route=str_replace("_config_","_".$access."_",$this->routeprimary);
                return $this->redirect($this->generateUrl($route.'_update',["id"=>$entity->getId()]));
        
            }
        }

        return $this->render($this->nameentity.'\submit.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => ($access=="config"),     
            'maxwidth'          => ($access=="user"),     
            'entity'            => $entity,
            'mode'              => "submit",
            'access'            => $access,
            'form'              => $form->createView()
        ]);
    }

    public function update($id,$access="config",Request $request, ManagerRegistry $em)
    {
        $entity = $em->getRepository($this->labelentity)->find($id);
        if (!$entity) throw $this->createNotFoundException('Unable to find entity.');

        // On s'assure que l'utilisateur à la permission de modifier
        if($access=="user") {
            $em->getRepository($this->labelentity)->getPermission($this->getUser(),$entity,$cansee,$canupdate,$canadd);
            if(!$canupdate) throw $this->createNotFoundException('Permission denied');
        }            
        
        // Création du formulaire
        $form = $this->entityForm($access,$entity,$em);
        $form->handleRequest($request);

        if ($form->get('submit')->isClicked() && $form->isValid()) {
            $em->getManager()->flush();

            if($access=="config")
                return $this->redirect($this->generateUrl($this->routeprimary.'_view',["id"=>$id]));
            else    
                return $this->redirect($this->generateUrl('app_core_home',["id"=>$id]));
        }

        // Type Tool
        if($entity->getPagecategory()->getId()<0 ) {
            return $this->render($this->nameentity.'\updatetool.html.twig', [
                'useheader'         => true,
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),  
                'maxwidth'          => ($access=="user"),                       
                'entity'            => $entity,
                'access'            => $access,
                'mode'              => "update",
                'form'              => $form->createView(),
            ]);
        }

        // Type URL
        if($entity->getPagecategory()->getId()==1 ) {
            return $this->render($this->nameentity.'\updateurl.html.twig', [
                'useheader'         => true,
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),  
                'maxwidth'          => ($access=="user"),                       
                'entity'            => $entity,
                'access'            => $access,
                'mode'              => "update",
                'form'              => $form->createView(),
            ]);
        }
        // Type Widget
        elseif($entity->getPagecategory()->getId()==2 ) {
            return $this->render($this->nameentity.'\updatewidget.html.twig', [
                'useheader'         => true,
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),    
                'maxwidth'          => ($access=="user"),                     
                'entity'            => $entity,
                'access'            => $access,
                'mode'              => "update",
                'form'              => $form->createView(),
            ]);
        }        
        // Type Editeur
        elseif($entity->getPagecategory()->getId()==3 ) {
            return $this->render($this->nameentity.'\updateeditor.html.twig', [
                'useheader'         => true,
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),    
                'maxwidth'          => ($access=="user"),                     
                'entity'            => $entity,
                'access'            => $access,
                'mode'              => "update",
                'form'              => $form->createView(),
            ]);
        }        
    }

    public function share($id,$access="config",Request $request, ManagerRegistry $em)
    {
        $entity = $em->getRepository($this->labelentity)->find($id);
        if (!$entity) throw $this->createNotFoundException('Unable to find entity.');

        // On s'assure que l'utilisateur à la permission de modifier
        if($access=="user") {
            $em->getRepository($this->labelentity)->getPermission($this->getUser(),$entity,$cansee,$canupdate,$canadd);
            if(!$canupdate) throw $this->createNotFoundException('Permission denied');
        }            
        
        // Création du formulaire
        $form = $this->createForm(PageShareType::class, $entity, ["access" => $access, "user" => $this->getUser()]);
        $form->handleRequest($request);

        if ($form->get('submit')->isClicked() && $form->isValid()) {
            $em->getManager()->flush();

            if($access=="config")
                return $this->redirect($this->generateUrl($this->routeprimary.'_view',["id"=>$id]));
            else    
                return $this->redirect($this->generateUrl('app_core_home',["id"=>$id]));
        }


        return $this->render($this->nameentity.'\share.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => ($access=="config"),    
            'maxwidth'          => ($access=="user"),
            'entity'            => $entity,
            'access'            => $access,
            'form'              => $form->createView(),
        ]);
    }

    public function delete($id,$access="config",Request $request, ManagerRegistry $em)
    {
        $entity = $em->getRepository($this->labelentity)->find($id);
        if (!$entity) throw $this->createNotFoundException('Unable to find entity.');
    
        // On s'assure que l'utilisateur à la permission de supprimer
        if($access=="user") {
            $em->getRepository($this->labelentity)->getPermission($this->getUser(),$entity,$cansee,$canupdate,$canadd);
            if(!$canupdate) throw $this->createNotFoundException('Permission denied');
        }

        // Suppression
        $em->getManager()->remove($entity);
        $em->getManager()->flush();

        // Retour
        if($access=="config")
            return $this->redirect($this->generateUrl($this->routeprimary));
        else   
            return $this->redirect($this->generateUrl("app_core_home"));
    }

    public function order($access="config",Request $request, ManagerRegistry $em)
    {
        // S'assurer que c'est un appel ajax
        if (!$request->isXmlHttpRequest()) return new JsonResponse(array('message' => 'Interdit'), 400);

        $output=array();
        $id=$request->request->get('id');
        $order=$request->request->get('order');

        $entity = $em->getRepository($this->labelentity)->find($id);
        if (!$entity) throw $this->createNotFoundException('Unable to find entity.');
    
        // On s'assure que l'utilisateur à la permission
        if($access=="user") {
            $em->getRepository($this->labelentity)->getPermission($this->getUser(),$entity,$cansee,$canupdate,$canadd);
            if(!$canupdate) throw $this->createNotFoundException('Permission denied');
        }

        $entity->setRoworder($order);
        $em->getManager()->flush();

        $response = new Response(json_encode($output));    
        $response->headers->set('Content-Type', 'application/json');        
        return $response; 
    }

    public function view($id,$access=null,Request $request, ManagerRegistry $em) {
        // usage soit portal / user / group
        $usage=$request->query->get('usage');
        $groupid=$request->query->get('group');
        $look=$request->query->get('look');
        $selwidget=$request->query->get('selwidget');

        $entity = $em->getRepository($this->labelentity)->find($id);
        if (!$entity) {
            return $this->render('Core\reconnect.html.twig', [
                'useheader'         => false,
                'usemenu'           => false,
                'usesidebar'        => false,                    
            ]);   
        }

        // Permissions
        if($access=="config") {
            $canupdate = true;
        }
        else {
            // On s'assure que l'utilisateur à la permission de voir
            $em->getRepository($this->labelentity)->getPermission($this->getUser(),$entity,$cansee,$canupdate,$canadd);
            if(!$cansee) {
                return $this->render('Core\reconnect.html.twig', [
                    'useheader'         => false,
                    'usemenu'           => false,
                    'usesidebar'        => false,                    
                ]);                
            }
        }
      
        // Compteur de visite
        if($this->getUser()) {
            if($groupid) {
                $group=$em->getRepository("App\Entity\Group")->find($groupid);
                if($group && $group->getFgcanshare()) {
                    $usergroup=$em->getRepository("App\Entity\UserGroup")->findoneby(["group"=>$group,"user"=>$this->getUser()]);
                    if($usergroup) {
                        $visitedate=$usergroup->getVisitedate();
                        if($visitedate) $visitedate->add(new \DateInterval("PT1H"));
                        $now=new \DateTime();
                        if($visitedate<$now) {
                            $usergroup->setVisitedate($now);
                            $usergroup->setVisitecpt($usergroup->getVisitecpt()+1);
                            $em->getManager()->flush();                    
                        }                      
                    }
                } 
            }
        }

        // Type Calendrier
        if($entity->getPageCategory()->getId()==-100) {
            $entity->setUrl($this->generateUrl('app_portal_user_calendar_view'));
            return $this->render($this->nameentity.'\viewurl.html.twig', [
                'useheader'         => ($access=="config"),
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),                    
                'entity'            => $entity,
                'access'            => $access,
                'canupdate'         => $canupdate,
                'usage'             => $usage,
                'group'             => $groupid
            ]);
        }

        // Type Blob
        if($entity->getPageCategory()->getId()==-90) {
            $entity->setUrl($this->generateUrl('app_portal_user_blog_view'));
            return $this->render($this->nameentity.'\viewurl.html.twig', [
                'useheader'         => ($access=="config"),
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),                    
                'entity'            => $entity,
                'access'            => $access,
                'canupdate'         => $canupdate,
                'usage'             => $usage,
                'group'             => $groupid
            ]);
        }

        // Type Blob
        if($entity->getPageCategory()->getId()==-80) {
            $entity->setUrl($this->generateUrl('app_portal_user_project_view'));
            return $this->render($this->nameentity.'\viewurl.html.twig', [
                'useheader'         => ($access=="config"),
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),                    
                'entity'            => $entity,
                'access'            => $access,
                'canupdate'         => $canupdate,
                'usage'             => $usage,
                'group'             => $groupid
            ]);
        }

        // Type URL
        if($entity->getPageCategory()->getId()==1) {
            return $this->render($this->nameentity.'\viewurl.html.twig', [
                'useheader'         => ($access=="config"),
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),                    
                'entity'            => $entity,
                'access'            => $access,
                'canupdate'         => $canupdate,
                'usage'             => $usage,
                'group'             => $groupid
            ]);
        }

        // Type Widgets
        if($entity->getPageCategory()->getId()==2) {
            $user=$this->getUser();
            if($user) {
                // Sauvegarder les préférences
                if($look) $this->setPreference($em,$user,"pagelook",$id,$look);
                if($selwidget)  $this->setPreference($em,$user,"pageselwidget",$id,$selwidget);

                // Récupérer les préférences
                if($entity->getFgpreference()) {
                    $look=$this->getPreference($user,"pagelook",$id,"view");
                    $selwidget=$this->getPreference($user,"pageselwidget",$id,null);
                }
            }

            if($look=="list") $entity->setMaxwidth(0);

            return $this->render($this->nameentity.'\viewwidget.html.twig', [
                'useheader'         => ($access=="config"),
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),                    
                'entity'            => $entity,
                'access'            => $access,
                'canupdate'         => $canupdate,
                'mode'              => "view",
                'look'              => $look,
                'selwidget'         => $selwidget,
                'widgets'           => $em->getRepository("App\Entity\Widget")->getWidgetAccess($access,'config'),
                'usage'             => $usage,
                'group'             => $groupid
            ]);
        } 
        // Type Editeur
        if($entity->getPageCategory()->getId()==3) {
            return $this->render($this->nameentity.'\vieweditor.html.twig', [
                'useheader'         => ($access=="config"),
                'usemenu'           => false,
                'usesidebar'        => ($access=="config"),                    
                'entity'            => $entity,
                'access'            => $access,
                'canupdate'         => $canupdate,
                'usage'             => $usage,
                'group'             => $groupid
            ]);
        }    

    }

    public function application($access=null,Request $request, ManagerRegistry $em) {
        // usage soit portal / user / group
        $usage=$request->query->get('usage');
        $group=$request->query->get('group');

        $entity = $em->getRepository($this->labelentity)->findOneBy(["parentfor"=>"app"]);
        if (!$entity) {
            return $this->render('Core\reconnect.html.twig', [
                'useheader'         => false,
                'usemenu'           => false,
                'usesidebar'        => false,                    
            ]);   
        }

        $canupdate = false;

        return $this->render($this->nameentity.'\viewwidget.html.twig', [
            'useheader'         => ($access=="config"),
            'usemenu'           => false,
            'usesidebar'        => ($access=="config"),                    
            'entity'            => $entity,
            'access'            => $access,
            'canupdate'         => $canupdate,
            'mode'              => "view",
            'widgets'           => $em->getRepository("App\Entity\Widget")->getWidgetAccess($access,'config'),
            'usage'             => $usage,
            'group'             => $group,
            'look'              => 'view',
            'selwidget'         => null,
        ]);
    }

    public function upload($access=null,Request $request, ManagerRegistry $em) {
        // Fichier temporaire uploadé
        $tmpfile    = $request->files->get('upload');
        $extention  = $tmpfile->getClientOriginalExtension();

        // Répertoire de Destination
        $fs         = new Filesystem();
        $rootdir    = $this->appKernel->getProjectDir()."/public";
        $fs->mkdir($rootdir."/uploads/ckeditor");
        
        // Fichier cible
        $targetName = uniqid().".".$extention;
        $targetFile = $rootdir."/uploads/ckeditor/".$targetName;
        $targetUrl  = "/".$this->getParameter('alias')."uploads/ckeditor/".$targetName;
        $message    = "";

        move_uploaded_file($tmpfile,$targetFile);
        
        $output["uploaded"]=1;
        $output["fileName"]=$targetName;
        $output["url"]=$targetUrl;

        return new Response(json_encode($output));

    }

    public function msgcounter($access="config",Request $request, ManagerRegistry $em)
    {
        // S'assurer que c'est un appel ajax
        if (!$request->isXmlHttpRequest()) {
            return new JsonResponse(array('message' => 'Interdit'), 400);
        }

        $user=$this->getUser();
        $em->getRepository("App\Entity\Page")->getPagesUser($user,null,$entity,$pagesuser,$pagesadmin,$groupsshared);

        $output=[];
        foreach($groupsshared as $groupshared) {
            $output[$groupshared->getId()]=$groupshared->pagesshared[0]->getCounterRead();
        }

        $response = new Response(json_encode($output));    
        $response->headers->set('Content-Type', 'application/json');        
        return $response;           

    }

    protected function getErrorForm($id,$form,$request,$data,$mode) {
        if ($form->get('submit')->isClicked() && $mode=="submit") {
            $usage = $form->get('usage')->getData();

            // Une page d'usage groupe doit avoir au moins un group de selectionné
            if($usage=="group"&&$data->getGroups()->isEmpty()) {
                $form->addError(new FormError('Vous devez selectionner au minimum un groupe'));
            }
        }

      

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

    protected function getPreference($user,$key,$id,$default) {
        $preference=$user->getPreference();
        $return=$default;

        if(is_array($preference)) {
            if(array_key_exists($key,$preference)) {
                if(array_key_exists($id,$preference[$key]))
                    $return=$preference[$key][$id];
            }
        }        

        return $return;
    }
    protected function setPreference($em,$user,$key,$id,$value) {
        $preference=$user->getPreference();
        if(!$preference) $preference=[];
        
        $toupdate=false;
        if(!array_key_exists($key,$preference)) {
            $toupdate=true;
            $preference[$key]=[];
        }
        if((!array_key_exists($id,$preference[$key]))) {
            $toupdate=true;
            $preference[$key][$id]=$value;
        }
        if($value&&$preference[$key][$id]!=$value) {
            $toupdate=true;
            $preference[$key][$id]=$value;            
        }        

        // Mise à jour des préferences
        if($toupdate) {
            $user->setPreference($preference);
            $em->getManager()->flush();             
        }
    }
}
