<?php

namespace AppBundle\Controller\Admin;

use AppBundle\Entity\Module;
use AppBundle\Enum\ModuleType as ModuleTypeEnum;
use AppBundle\Form\Type\ModuleType;
use AppBundle\Helper\ModuleHelper;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Liip\ImagineBundle\Controller\ImagineController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;

class ModuleController extends Controller
{
    /**
     * @var EntityManagerInterface
     */
    private $em;

    /**
     * @var SessionInterface
     */
    private $session;
    
    public function __construct(EntityManagerInterface $em, SessionInterface $session)
    {
        $this->em = $em;
        $this->session = $session;
    }

    /**
     *
     * @Route(
     *      "/module/list/{type}/{page}",
     *      requirements = {"page": "\d+"},
     *      name = "admin_module"
     * )
     *
     * @param Request $request
     * @param string type
     * @param int page
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function indexAction(Request $request, string $type = 'all', int $page = 1)
    {
        $resultsMaxPerPage = 100; //$this->getParameter('results.admin.max_per_page');
        $search_type = $request->get('mtype');
        $search_title = $request->get('title');
        $search_position = $request->get('position');

        // Mise à jour de la session avec les nouvelles valeurs
        $this->session->set($request->get('_route'), array(
            'type' => $type,
            'page' => $page,
        ));

        $qbModules = $this->em->createQueryBuilder()
            ->select('m')
            ->from(Module::class, 'm')
            ->orderBy('m.ordering', 'asc')
            ->addOrderBy('m.id', 'asc')
            ->setFirstResult(($page - 1) * $resultsMaxPerPage)
            ->setMaxResults($resultsMaxPerPage)
        ;
        if ('all' != $type) {
            $qbModules
                ->andWhere('m.type = :m_type')
                ->setParameter('m_type', $type);
        }
        elseif($search_type) {
            $qbModules
                ->andWhere('m.type = :m_type')
                ->setParameter('m_type', $search_type);
        }

        if ($search_title) {
            $qbModules
                ->andWhere($qbModules->expr()->like(
                    $qbModules->expr()->upper('m.title'),
                    $qbModules->expr()->upper(':m_title')
                ))
                ->setParameter('m_title', '%'.$search_title.'%')
            ;
        }
        if ($search_position) {
            $qbModules
                ->andWhere($qbModules->expr()->like(
                    $qbModules->expr()->lower('m.position'),
                    $qbModules->expr()->lower(':m_position')
                ))
                ->setParameter('m_position', $search_position)
            ;
        }
        //dump($qbModules->__toString()); die;
        $modules = new Paginator($qbModules->getQuery());

        $typeList = ModuleHelper::getTypeList();
        $positionList = ModuleHelper::getPositionList();

        return $this->render('Admin/Module/index.html.twig', array(
            'search_type' => $search_type,
            'search_title' => $search_title,
            'search_position' => $search_position,
            'positions' => $positionList,
            'types' => $typeList,
            'modules' => $modules,
            'type' => $type,
            'nb_pages' => ceil(count($modules) / $resultsMaxPerPage),
            'pageactuelle' => $page,
        ));
    }

    /**
     *
     * @Route(
     *      "/module/add/{type}",
     *      defaults = {"type" = "pdf|picture|video"},
     *      name = "admin_module_add"
     * )
     *
     * @param Request $request
     * @param string $type
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function addAction(Request $request, $type)
    {
        $module = new Module;
        $module->setType($type);

        $form = $this->createForm(ModuleType::class, $module);
        $form->handleRequest($request);
        
        $formModuleClass = ModuleHelper::getModuleFormClass($module);
        $formModule = $this->createForm($formModuleClass, $module->getParams());
        $formModule->handleRequest($request);
        
        if ($form->isSubmitted() && $form->isValid() && $formModule->isSubmitted() && $formModule->isValid()) {
            $params = (object) $formModule->getData();

            //Transform Doctrine ArrayCollection to id Array
            // foreach ($params as $i => $p) {
            //     if (is_object($p) && $p instanceof ArrayCollection) {
            //         $p = $p->toArray();
            //         $tmp = array();

            //         foreach($p as $item) {
            //             $tmp[] = $item->getId();
            //         } 
                    
            //         $params->$i = $tmp;
            //     }
            // }

            $module->setParams($params);

            $module->setCreated(new \DateTime);
            
            $module->preUploadFilePicture(); // @ORM\PrePersist() not working ?
            $this->em->persist($module);
            $module->uploadFilePicture(); // @ORM\PostPersist() not working ?

            $this->em->flush();

            // On définit un message flash
            $this->addFlash('success', 'Module ajouté');

            return $this->redirectToRoute('admin_module_edit', array(
                'id' => $module->getId(),
            ));
        }

        return $this->render('Admin/Module/add.html.twig', array(
            'form' => $form->createView(),
            'formModule' => $formModule->createView(),
            'type' => $type,
        ));
    }

    /**
     *
     * @Route(
     *      "/module/edit/{id}",
     *      requirements = {"id": "\d+"},
     *      name = "admin_module_edit"
     * )
     *
     * @param Request $request
     * @param Module $module
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function editAction(Request $request, Module $module)
    {        
        $type = $module->getType();
        $module->setFormClass($type);

        $form = $this->createForm(ModuleType::class, $module);
        $form->handleRequest($request);

        $formModuleClass = ModuleHelper::getModuleFormClass($module);
        $formModule = $this->createForm($formModuleClass, $module->getParams());
        $formModule->handleRequest($request);
        
        if ($form->isSubmitted() && $form->isValid() && $formModule->isSubmitted() && $formModule->isValid()) {
            if ($request->get('remove_picture')) {
                $module->setPicture(null);
                $module->removeUpload();
            }
            
            //Force params to null for update | Bug Doctrine
            $module->setParams(null);
            $this->em->persist($module);
            $this->em->flush();
            
            $params = (object) $formModule->getData();

            //Transform Doctrine ArrayCollection to id Array
            // foreach ($params as $i => $p) {
            //     if (is_object($p) && $p instanceof ArrayCollection) {
            //         $p = $p->toArray();
            //         $tmp = array();

            //         foreach($p as $item) {
            //             $tmp[] = $item->getId();
            //         } 
                    
            //         $params->$i = $tmp;
            //     }
            // }

            $module->setParams($params);
            $module->setUpdated(new \DateTime);
            
            $module->preUploadFilePicture(); // @ORM\PrePersist() not working ?
            $this->em->persist($module);
            $module->uploadFilePicture(); // @ORM\PostPersist() not working ?

            $this->em->flush();

            // On définit un message flash
            $this->addFlash('success', 'Module modifié');

            return $this->redirectToRoute('admin_module_edit', array(
                'id' => $module->getId(),
            ));
        }

        return $this->render('Admin/Module/add.html.twig', array(
            'form' => $form->createView(),
            'formModule' => $formModule->createView(),
            'type' => $type,
        ));
    }


    /**
     * Positionne un élément parmi ses semblables
     *
     * @Route(
     *      "/module/order",
     *      name = "module_ordering"
     * )
     *
     * @param Request $request
     * @return Response
     */
    public function orderAction(Request $request)
    {
        $type = $request->get('type');
        $liste = $request->get('list');

        $i = 1;
        foreach ($liste as $elementid) {
            $element = $this->em->getRepository('AppBundle:'.$type)->find($elementid);
            if (!$element) {
                throw $this->createNotFoundException(
                    'No item found for id '.$elementid
                );
            }

            $element->setOrdering($i);
            $i++;
        }
        $this->em->flush();

        return new Response();
    }

    /**
     *
     * @Route(
     *      "/module/actif",
     *      name = "admin_module_actif"
     * )
     * @param Request $request
     * @return Response
     */
    public function actifAction(Request $request)
    {
        $id = $request->get('id');
        $actif = $request->get('actif');
        $type = 'Module';

        $element = $this->em->getRepository('AppBundle:' . $type)->find($id);

        if (!$element) {
            throw $this->createNotFoundException(
                'No module found for id '.$id
            );
        }

        $element->setIsActive($actif);
        $this->em->flush();
        
        return new Response();
    }

    /**
     *
     * @Route(
     *      "/module/delete/{id}",
     *      requirements = {"id" = "\d+"},
     *      name = "admin_module_delete"
     * )
     * @param int $id
     * @return Response
     */
    public function deleteAction(int $id)
    {
        //$id = $request->get('id');
        $type = 'Module';

        $entity = $this->em->getRepository('AppBundle:' . $type)->findOneById($id);

        $this->em->remove($entity);
        $this->em->flush();

        $this->addFlash('success', $type.' supprimé');

        return new Response();
    }
}
