<?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\Finder\Finder;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpKernel\KernelInterface;

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

use App\Entity\Projecttask;
use App\Form\ProjecttaskType;

class ProjecttaskController extends AbstractController
{
    private $nameentity="Projecttask";
    private $labelentity="App\Entity\Projecttask";
    private $routeprimary="app_portal_config_projecttask";

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

    private function entityForm($access="config", Projecttask $entity, ManagerRegistry $em)
    {
        if ($em->getManager()->contains($entity)) {
            return $this->createForm(ProjecttaskType::class, $entity, [
                "mode"   => "update",
                "access" => $access,
                "user" => $this->getUser(),
                "projecttask" => $entity
            ]);
        }
        else {
            return $this->createForm(ProjecttaskType::class, $entity, [
                "mode"   => "submit",
                "access" => $access,
                "user" => $this->getUser(),
                "projecttask" => $entity
            ]);
        }
    }

    public function submit($idproject, $access="config",Request $request, ManagerRegistry $em)
    {
        $entity = new Projecttask();
        $project=$em->getRepository("App\Entity\Project")->find($idproject);
        if($project) $entity->setProject($project);
        $entity->setPriority(0);
        $entity->setPercentage(0);
        $pageid=$request->get("page");
        if($pageid) {
            $page=$em->getRepository("App\Entity\Page")->find($pageid);
            $groups=$page->getGroups();
            $idgroup=$groups[0]->getId();
        }
        
        $form   = $this->entityForm($access,$entity,$em);
        $form->handleRequest($request);

        if ($form->get('submit')->isClicked() && $form->isValid()) {
            if($entity->getPercentage()>100) $entity->setPercentage(100);
            $entity->setOwner($this->getUser());
            $entity->setSubmit(new \Datetime());

            $em->getManager()->persist($entity);
            $em->getManager()->flush();

            if($entity->getUser()&&$entity->getUser()!=$entity->getOwner()) {
                $this->notifMail($entity,$request);
            }

            foreach($entity->getProject()->getGroups() as $group) {
                if($group->getFgcanshare()) {
                    $url=$this->generateUrl('app_core_redirect', ['route'=>'app_portal_user_projecttask_view','id'=>$entity->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
                    $message="Création tâche<br><a href='$url' target='_top'>".$entity->getName()."</a>";
                    $this->wss->addMessage($this->getUser()->getApikey(),$group->getId(),$message);
                }
            }

            if(is_null($pageid))
                return $this->redirect($this->generateUrl('app_portal_'.$access.'_projecttask_view',["id"=>$entity->getId()]));          
            else
                return $this->redirect($this->generateUrl('app_portal_'.$access.'_page_view',["id"=>$pageid,"usage"=>"group","group"=>$idgroup]));          
        }

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

    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.');
        $oldpercentage=$entity->getPercentage();
        $olduser=$entity->getUser();

        // On s'assure que l'utilisateur à la permission de modifier
        if($access=="user") {
            $user=$this->getUser();
            $em->getRepository("App\Entity\Project")->getPermission($user,$entity->getProject(),$cansee,$canupdate,$canadd);
            if($user && ((is_null($entity->getUser()) && $user==$entity->getOwner()) || $user==$entity->getUser())) $canadd=true;
            else $canadd = $em->getRepository("App\Entity\Project")->getInvalideur($user,$entity->getProject());
            if(!$canadd) 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()) {
            if($entity->getPercentage()>100) $entity->setPercentage(100);
            $em->getManager()->flush();

            if($entity->getUser()&&$entity->getUser()!=$entity->getOwner()&&$entity->getUser()!=$olduser) {
                $this->notifMail($entity,$request);
            }


            foreach($entity->getProject()->getGroups() as $group) {
                if($group->getFgcanshare()) {
                    $url=$this->generateUrl('app_core_redirect', ['route'=>'app_portal_user_projecttask_view','id'=>$entity->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
                    if($oldpercentage<100&$entity->getPercentage()==100)
                        $message="Tâche terminée<br><a href='$url' target='_top'>".$entity->getName()."</a>";
                    elseif($oldpercentage==100&$entity->getPercentage()<100)
                        $message="Tâche réouverte<br><a href='$url' target='_top'>".$entity->getName()."</a>";
                    else
                        $message="Modification tâche<br><a href='$url' target='_top'>".$entity->getName()."</a>";
                    
                    $this->wss->addMessage($this->getUser()->getApikey(),$group->getId(),$message);
                }
            }

            return $this->redirect($this->generateUrl('app_portal_'.$access.'_projecttask_view',["id"=>$entity->getId()]));          
        }


        return $this->render($this->nameentity.'\edit.html.twig', [
            'useheader'         => ($access=="config"),
            'usemenu'           => false,
            'usesidebar'        => ($access=="config"),  
            'maxwidth'          => ($access=="user"),                  
            'entity'            => $entity,
            'access'            => $access,
            'mode'              => "update",
            '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.');
        
        $idproject=$entity->getProject()->getId();

        // On s'assure que l'utilisateur à la permission de supprimer
        if($access=="user") {
            $user=$this->getUser();
            $em->getRepository("App\Entity\Project")->getPermission($user,$entity->getProject(),$cansee,$canupdate,$canadd);
            if($user && ((is_null($entity->getUser()) && $user==$entity->getOwner()) || $user==$entity->getUser())) $canadd=true;
            else $canadd = $em->getRepository("App\Entity\Project")->getInvalideur($user,$entity->getProject());

            if(!$canadd) throw $this->createNotFoundException('Permission denied');
        }

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

        // Retour
        return $this->redirect($this->generateUrl('app_portal_'.$access.'_project_view',["id"=>$idproject]));
    }

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

        // On recherche la premiere page associé au groupe du projet
        $groups=$entity->getProject()->getGroups();
        $idpage=null;
        $idgroup=null;
        if($groups[0]) {
            if($groups[0]->getFgcanshare()) {
                $pages=$groups[0]->getPages();
                if($pages[0]) {
                    $idpage=$pages[0]->getId();
                    $groups=$pages[0]->getGroups();
                    $idgroup=$groups[0]->getId();
                }
            }
        }

        // Permissions
        $user=$this->getUser();
        if($access=="config") {
            $canupdate = true;
            $canadd=true;

            $projects=$em->getRepository("App\Entity\Project")->findBy(["id"=>$entity->getProject()->getId()]);
        }
        else {
            // On récupère l'ensemble des projects de l'utilisateur
            $em->getRepository("App\Entity\Project")->getProjectsUser($user,$projectsuser,$projectsadmin,$projectsshared);
            $projects=array_merge($projectsuser,$projectsadmin->toArray(),$projectsshared);

            // permission
            if($id==0) {
                $cansee=true;
                $canadd=true;
            }
            else {
                $em->getRepository("App\Entity\Project")->getPermission($user,$entity->getProject(),$cansee,$canupdate,$canadd);
                $canadd = $em->getRepository("App\Entity\Project")->getInvalideur($user,$entity->getProject());                
            }
          
            if(!$cansee) throw $this->createNotFoundException('Permission denied');

            $canupdate=false;
            if($user) {
                $canupdate=true;
                if((is_null($entity->getUser()) && $user==$entity->getOwner()) || $user==$entity->getUser()) $canadd=true;
            }
        }

        $em->getRepository("App\Entity\Projecttask")->getProjectsTasks($projects,0,10,$count,$projecttasks);

        // Récupérer les fichiers de la tache
        $directory=$this->appKernel->getProjectDir()."/uploads/file/projecttask-".$id;
        $files=[];
        $fs = new Filesystem();

        if($fs->exists($directory)) {
            $finder = new Finder();
            $finder->sortByName()->in($directory)->exclude('thumb')->exclude('thumbmini');
            
            foreach ($finder as $file) {
                $tmp=[];
                $tmp["name"]=$file->getRelativePathname();
                $tmp["extension"]=strtolower($file->getExtension());
                $fileinfo = new file($file->getPathname());
                $tmp["minetype"]=$fileinfo->getMimeType();
                $tmp["minefamily"]=explode("/",$tmp["minetype"])[0];

                $tmp["thumb"]="";
                if($tmp["extension"]=="pdf") {
                    $tmp["thumb"]="/".$this->getParameter('alias')."images/files/".$tmp["extension"].".png";
                }
                elseif($fs->exists($directory."/thumbmini/".$tmp["name"])) {
                    $data = file_get_contents($directory."/thumbmini/".$tmp["name"]);
                    $tmp["thumb"]="data:image/" . $tmp["extension"] . ";base64," . base64_encode($data);
                }
                elseif($fs->exists($directory."/thumb/".$tmp["name"])) {
                    $data = file_get_contents($directory."/thumb/".$tmp["name"]);
                    $tmp["thumb"]="data:image/" . $tmp["extension"] . ";base64," . base64_encode($data);
                }
                elseif($fs->exists($this->appKernel->getProjectDir()."/public/images/files/".$tmp["extension"].".png")) {
                    $tmp["thumb"]="/".$this->getParameter('alias')."images/files/".$tmp["extension"].".png";
                }

                array_push($files,$tmp);
            }
        }

        return $this->render($this->nameentity.'\view.html.twig', [
            'useheader'         => ($access=="config"),
            'usemenu'           => false,
            'usesidebar'        => ($access=="config"),  
            'maxwidth'          => ($access=="user"),
            'entity'            => $entity,
            'access'            => $access,
            'canupdate'         => $canupdate,
            'canadd'            => $canadd,
            'projects'          => $projects,
            'projecttasks'      => $projecttasks,
            'files'             => $files,
            'idpage'            => $idpage,
            'idgroup'           => $idgroup,
        ]);

    }

    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 users($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();
        $page_limit=$request->query->get('page_limit');
        $q=$request->query->get('q');
        $projectid=$request->query->get('project');

        $project=$em->getRepository("App\Entity\Project")->find($projectid);
        if($project) {
            $user=$this->getUser();
            $canadd = $em->getRepository("App\Entity\Project")->getInvalideur($user,$project);
            
            // Si permission alors il peut affecter tt les personnes du groupe
            if($canadd||$access=="config") {
                $qb= $em->getManager()->createQueryBuilder()
                        ->select('user')

                        ->from('App\Entity\Project','project')
                        ->andwhere('project.id=:project')

                        ->from('App\Entity\UserGroup','usergroup')
                        ->andwhere("usergroup.group MEMBER OF project.groups")

                        ->from('App\Entity\User','user')
                        ->andwhere("usergroup.user=user")

                        ->setParameter('project',$projectid);
            
                $datas=$qb->setFirstResult(0)->setMaxResults($page_limit)->getQuery()->getResult();                    
                foreach($datas as $data) {
                    array_push($output,array("id"=>$data->getId(),"text"=>$data->getUsername()));
                }
            }
            // Sinon il ne peut que s'affecter lui
            else {
                array_push($output,array("id"=>$user->getId(),"text"=>$user->getUsername()));
            }
        }

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

    public function percentage($id, $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();
        $percentage=$request->get('percentage');
        $entity = $em->getRepository($this->labelentity)->find($id);
        if (!$entity) throw $this->createNotFoundException('Unable to find entity.');
        
        $idproject=$entity->getProject()->getId();
        $oldpercentage=$entity->getPercentage();

        // On s'assure que l'utilisateur à la permission de modifier
        if($access=="user") {
            $user=$this->getUser();
            if($user && ((is_null($entity->getUser()) && $user==$entity->getOwner()) || $user==$entity->getUser())) $canadd=true;
            else $canadd = $em->getRepository("App\Entity\Project")->getInvalideur($user,$entity->getProject());
            if(!$canadd) throw $this->createNotFoundException('Permission denied');
        }


        $entity->setPercentage($percentage);
        $em->getManager()->flush();

        foreach($entity->getProject()->getGroups() as $group) {
            if($group->getFgcanshare()) {
                $url=$this->generateUrl('app_core_redirect', ['route'=>'app_portal_user_projecttask_view','id'=>$entity->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
                $message="";
                if($oldpercentage<100&$entity->getPercentage()==100)
                    $message="Tâche terminée<br><a href='$url' target='_top'>".$entity->getName()."</a>";
                elseif($oldpercentage==100&$entity->getPercentage()<100)
                    $message="Tâche réouverte<br><a href='$url' target='_top'>".$entity->getName()."</a>";

                if($message!="") {
                    $this->wss->addMessage($this->getUser()->getApikey(),$group->getId(),$message);
                }
            }
        }

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

    private function notifMail($entity,$request) {
        $appname=$request->getSession()->get('appname');
        $subject=$appname." : Affectation Tâche dans le groupe ".$entity->getProject()->getName();
        $url=$this->generateUrl('app_core_redirect', ['route'=>'app_portal_user_projecttask_view','id'=>$entity->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
        $body="Une tâche vous a été affectée dans le groupe ".$entity->getProject()->getName()."<br>".$entity->getName()."<br><br>Vous pouvez la consulter sur<br><a href='$url'>".$url."</a>";
        $from =  $this->getParameter('noreply');
        $fromName = $this->getUser()->getFirstname()." ".$this->getUser()->getLastname();
        $to=$entity->getUser()->getEmail();

        $this->mail->sendEmail($subject, $body, $to, $from, $fromName);         
    }
}
