<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Company;
use AppBundle\Entity\Content;
use AppBundle\Entity\DemandePEE;
use AppBundle\Entity\Establishment;
use AppBundle\Entity\Interest;
use AppBundle\Entity\Menu;
use AppBundle\Entity\Module;
use AppBundle\Entity\OperationITDLC;
use AppBundle\Entity\OperationPEE;
use AppBundle\Entity\Partner;
use AppBundle\Entity\Preference;
use AppBundle\Entity\Slider;
use AppBundle\Entity\Testimonial;
use AppBundle\Entity\User;
use AppBundle\Enum\UserType;
use AppBundle\Helper\ModuleHelper;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;

class RenderController extends Controller
{
    /**
     * @var EntityManagerInterface
     */
    protected $em;

    /**
     * @var RouterInterface
     */
    protected $router;

    protected $env;
    
    public function __construct(
        EntityManagerInterface $em,
        RouterInterface $router,
        $env
    )
    {
        $this->em = $em;
        $this->env = $env;
        $this->router = $router;
    }

    /**
     *
     * @param string $menu_type Définit le type de rendu Twig souhaité ('main' ou 'sitemap')
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function menuAction(string $menu_type = 'main')
    {
        // Select all the menus except 'Actualités' (id=55) and 'Archives & ressources' (id=61) and their sub-menus (until the 3rd level)
        $qb = $this->em->createQueryBuilder();
        $qb
            ->select('m1, m1tt, m2, m2tt, m3, m3tt')
            ->from('AppBundle:Menu', 'm1')
            ->leftJoin('m1.typeTemplate', 'm1tt')
            ->leftJoin('m1.children', 'm2', 'with', $qb->expr()->andX(
                'm1.id != :m1_news_id', // Except 'Actualités'
                'm1.id != :m1_archives_id', // Except 'Archives & ressources'
                'm2.is_active = :m2_is_active',
                'm2.is_visible != :m2_is_visible'
            ))
            ->leftJoin('m2.typeTemplate', 'm2tt')
            ->leftJoin('m2.children', 'm3', 'with', $qb->expr()->andX(
                'm3.is_active = :m3_is_active',
                'm3.is_visible != :m3_is_visible'
            ))
            ->leftJoin('m3.typeTemplate', 'm3tt')
            ->where($qb->expr()->isNull('m1.parent')) // Root menus (level 1)
            ->andWhere('m1.is_active = :m1_is_active')
            ->andWhere('m1.is_visible != :m1_is_visible')
            ->andWhere('m1.menu_type = :m1_menu_type')
            ->orderBy('m1.position', 'asc')
            ->addOrderBy('m1.id', 'asc')
            ->addOrderBy('m2.position', 'asc')
            ->addOrderBy('m2.id', 'asc')
            ->addOrderBy('m3.position', 'asc')
            ->addOrderBy('m3.id', 'asc')
            ->setParameters(array(
                'm1_menu_type' => $menu_type,
                'm1_is_active' => 't',
                'm1_is_visible' => 'f',
                'm1_news_id' => 55,
                'm1_archives_id' => 61,
                'm2_is_active' => 't',
                'm2_is_visible' => 'f',
                'm3_is_active' => 't',
                'm3_is_visible' => 'f',
            ));
        $menus = $qb->getQuery()->getArrayResult();
        
        $request = Request::createFromGlobals();

        $referer = $request->server->get('REQUEST_URI');
        $url_params = $request->server->get('QUERY_STRING');
        
        $referer = str_replace(array('/app_dev.php', '/app.php', '?'.$url_params), '', $referer);

        $routeParams = $this->router->match($referer);
        
        $active = array();

        if ( isset($routeParams['id']) ) {
            $active[] = $routeParams['id'];
        }

        if ( isset($routeParams['idlevel1']) ) {
            $active[] = $routeParams['idlevel1'];
        }

        if ( isset($routeParams['idlevel2']) ) {
            $active[] = $routeParams['idlevel2'];
        }
        
        return $this->render('Front/Render/Menu/' . $menu_type .'.html.twig', array(
            'menus' => $menus,
            'active_ids' => $active
        ));
    }

    /**
     *
     * @param string $position Définit la position du module à charger
     * @param string $force_type Définit le type de module souhaité
     * @param string $force_layout Définit le type de rendu Twig souhaité
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function moduleAction( string $position, string $force_type = null, string $force_layout = null )
    {
        $request = Request::createFromGlobals();

        $referer = $request->server->get('REQUEST_URI');
        $url_params = $request->server->get('QUERY_STRING');
        
        $referer = str_replace(array('/app_dev.php', '/app.php', '?'.$url_params), '', $referer);

        $routeParams = $this->router->match($referer);

        // if error, return empty string
        if ( empty($routeParams) ) {
            return new Response('');
        }
        
        //If position begin by home_ : display modules only on home page
        if (strpos($position, 'home_') === 0 && ( isset($routeParams['_route']) && $routeParams['_route'] !== '_welcome' )) {
            return new Response('');
        }

        $filters = array(
            'isActive' => true, 
            'position' => $position,
        );

        if (!empty($force_type)) {
            $filters['type'] = $force_type;
        }
        
        if (!empty($routeParams['_controller']) && $routeParams['_controller'] == "AppBundle\Controller\TemplatesController::actuAction" && !empty($routeParams['idlevel1'])) {
            $menu = $this->em->getRepository(Menu::class)->find($routeParams['idlevel1']);
            $modules = $this->em->getRepository(Module::class)->findByMenu(
                $menu->getId(), 
                $filters
            );
        }
        elseif (!empty($routeParams['_controller']) && $routeParams['_controller'] == "AppBundle\Controller\TemplatesController::testimonialAction" && !empty($routeParams['idlevel1'])) {
            $menu = $this->em->getRepository(Menu::class)->find($routeParams['idlevel1']);
            $modules = $this->em->getRepository(Module::class)->findByMenu(
                $menu->getId(), 
                $filters
            );
        }
        elseif (!empty($routeParams['id']) && (strpos($position, 'modal_') !== 0 && strpos($position, 'menu_') !== 0)) {
            $menu = $this->em->getRepository(Menu::class)->find($routeParams['id']);
            $modules = $this->em->getRepository(Module::class)->findByMenu(
                $menu->getId(), 
                $filters
            );
        }
        else {
            $modules = $this->em->getRepository(Module::class)->findBy(
                $filters, [
                'ordering' => 'ASC',
                'created' => 'DESC',
            ]);
        }

        //If there are no modules, return empty string
        if (empty($modules)) {
            return new Response('');
        }

        $render = '';

        foreach ($modules as $module) {
            $module->setType($module->getType());

            $controllerClass = ModuleHelper::getModuleControllerClass($module);
            
            $moduleResponse = $this->forward($controllerClass . '::renderModule', array(
                'moduleId' => $module->getId(),
                'menuId' => (isset($menu)) ? $menu->getId() : null,
                'force_layout' => $force_layout,
            ));

            ob_start();
                $moduleResponse->sendContent();

                $render .= html_entity_decode(ob_get_contents());
            ob_end_clean();
        }
        return new Response($render);
    }

    /**
     * Affichage d'une vidéo
     *
     * @Route(
     *      "/video/{ref}",
     *      name = "video"
     * )
     *
     * @param string $ref Identifiant de la vidéo
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function videoAction($ref)
    {
        return $this->render('Front/Render/video.html.twig', [
            'refVideo' => $ref,
        ]);
    }


    /**
     * Affichage d'un marker
     *
     * @Route(
     *      "/map-pee/marker/{type}",
     *      name = "map_pee_marker"
     * )
     * 
     * @param Request $request
     * @param string $type 
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function markerAction(Request $request, string $type)
    {
        $id = $request->get('id');
        
        $appPath = $this->container->getParameter('kernel.root_dir');
        $markerPath = realpath($appPath . '/../web/front/images/__cgenial/map/marker-' . $type . '.png');
        
        $marker = imagecreatefrompng($markerPath); 

        // imagealphablending($marker,false);
        // imagesavealpha($marker,true);

        if (!empty($id)) {
            // Add $id on image
            $fontFile = realpath($appPath . '/../web/front/fonts/oswald/Oswald-Bold.ttf');
            if (file_exists($fontFile)) {
                $font = $fontFile;
            }

            $text_size = $request->get('tz') ?? 20;

            switch (strlen($id)) {
                case 2 :
                        $x = 15;
                        $y = 42;
                        break;
                case 3 :
                        $x = 11;
                        $y = 40;
                        $text_size = $request->get('tz') ?? 18;
                        break;
                case 1 :
                default:
                        $x = 22;
                        $y = 42;
                        break;
            }

            $text_color_red = $request->get('tcr') ?? 255;
            $text_color_green = $request->get('tcg') ?? 255;
            $text_color_blue = $request->get('tcb') ?? 255;

            $text_color = imagecolorallocatealpha($marker, intval($text_color_red), intval($text_color_green), intval($text_color_blue), 0);
            imagettftext($marker, $text_size, 0, $x, $y, $text_color, $font, $id);
        }

        // imageantialias($marker, true);

        ob_start();
        imagepng($marker);
        $render = ob_get_contents();
        ob_end_clean();
        imagedestroy($marker);
        
        $headers = array(
            'Content-Disposition' => 'inline; filename="'.('cursor_default' . ( !empty($id) ? '_'.$id : '' ) . 'png').'"',
            'Content-Type' => 'image/png'
        );
        
        return new Response($render, 200, $headers);
    }


    /**
     * Modal : Affichage d'un partenaire
     *
     * @Route(
     *      "/modal-partner/{partner}",
     *      name = "modal_partner"
     * )
     *
     * @param Request $request
     * @param Partner $partner
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalPartnerAction(Request $request, Partner $partner)
    {
        return $this->render('Front/Render/Modal/partner.html.twig', array(
            'partner' => $partner
        ));
    }

    /**
     * Modal : Affichage d'une entreprise
     *
     * @Route(
     *      "/modal-company/{company}",
     *      name = "modal_company"
     * )
     *
     * @param Request $request
     * @param Company $company
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalCompanyAction(Request $request, Company $company)
    {
        return $this->render('Front/Render/Modal/company.html.twig', array(
            'company' => $company
        ));
    }


    /**
     * Modal : Affichage d'un témoignage
     *
     * @Route(
     *      "/modal-testimonial/{testimonial}",
     *      name = "modal_testimonial"
     * )
     *
     * @param Request $request
     * @param Testimonial $testimonial
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalTestimonialAction(Request $request, Testimonial $testimonial)
    {
        return $this->render('Front/Render/Modal/testimonial.html.twig', array(
            'testimonial' => $testimonial
        ));
    }

    /**
     * Modal : Affichage d'un contenu
     *
     * @Route(
     *      "/modal-content/{content}",
     *      name = "modal_content"
     * )
     *
     * @param Request $request
     * @param Content $content
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalContentAction(Request $request, Content $content)
    {
        return $this->render('Front/Render/Modal/content.html.twig', array(
            'content' => $content
        ));
    }

    /**
     * Modal : Affichage d'une demande PEE
     *
     * @Route(
     *      "/modal-demande-pee/{demande}",
     *      name = "modal_demande_pee"
     * )
     *
     * @param Request $request
     * @param DemandePEE $demande
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalDemandePEEAction(Request $request, DemandePEE $demande)
    {
        return $this->render('Front/Render/Modal/PEE/demande.html.twig', array(
            'demande' => $demande
        ));
    }

    /**
     * Modal : Affichage d'une opération PEE
     *
     * @Route(
     *      "/modal-ope-pee/{ope}",
     *      name = "modal_ope_pee"
     * )
     *
     * @param Request $request
     * @param OperationPEE $ope
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalOpePEEAction(Request $request, OperationPEE $ope)
    {
        $placesTaken = $this->em->getRepository(OperationPEE::class)->getPlacesTaken($ope);

        $isInterested = $this->em->getRepository(Interest::class)->findOneBy(array('user' => $this->getUser(), 'operationpee' => $ope));
        
        return $this->render('Front/Render/Modal/PEE/ope.html.twig', array(
            'ope' => $ope,
            'placesTaken' => $placesTaken,
            'isInterested' => $isInterested
        ));
    }

    /**
     * Modal : Affichage d'une demande ITDLC
     *
     * @Route(
     *      "/modal-demande-itdlc/{demande}",
     *      name = "modal_demande_itdlc"
     * )
     *
     * @param Request $request
     * @param OperationITDLC $demande
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalDemandeITDLCAction(Request $request, OperationITDLC $demande)
    {
        $isInterested = $this->em->getRepository(Interest::class)->findOneBy(array('user' => $this->getUser(), 'operationitdlc' => $demande));

        return $this->render('Front/Render/Modal/ITDLC/demande.html.twig', array(
            'demande' => $demande,
            'isInterested' => $isInterested
        ));
    }

    /**
     * Modal : Affichage d'une opération ITDLC
     *
     * @Route(
     *      "/modal-ope-itdlc/{ope}",
     *      name = "modal_ope_itdlc"
     * )
     *
     * @param Request $request
     * @param OperationPEE $ope
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalOpeITDLCAction(Request $request, OperationITDLC $ope)
    {
        return $this->render('Front/Render/Modal/ITDLC/ope.html.twig', array(
            'ope' => $ope
        ));
    }


    /**
     * Modal : Affichage d'un utilisateur
     *
     * @Route(
     *      "/modal-user/{user}",
     *      name = "modal_user"
     * )
     *
     * @param Request $request
     * @param User $user
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
     */
    public function modalUserAction(Request $request, User $user)
    {
        $loggedUser = $this->getUser();
        $display_preference = true;

        $isPreferred = $this->em->getRepository(Preference::class)->findOneBy(array('mainUser' => $loggedUser, 'selectedUser' => $user));
        
        if ($user->getType() == UserType::TEACHER) {
            return $this->render('Front/Render/Modal/User/teacher.html.twig', array(
                'user' => $user,
                'isPreferred' => $isPreferred,
                'display_preference' => $display_preference
            ));
        }
        else {
            // Engineer
            return $this->render('Front/Render/Modal/User/engineer.html.twig', array(
                'user' => $user,
                'isPreferred' => $isPreferred,
                'display_preference' => $display_preference
            ));
        }
    }
}
