<?php

namespace Eesa\SantanderBundle\Controller;

use Eesa\CoreBundle\Controller\Controller;

use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Validator\Constraints\NotBlank;

use Eesa\WebinarBundle\Form\Filter\WebinarFilterType;
use Eesa\SantanderBundle\Form\Type\Webinar\UserType;

use Eesa\SantanderBundle\Entity\User;
use Eesa\SantanderBundle\Entity\Profile;
use Eesa\WebinarBundle\Entity\Webinar;
use Eesa\SantanderBundle\Entity\AuthenticationLog;
use Eesa\SantanderBundle\Event\AuthenticationEvent;
use Eesa\WebinarBundle\Form\WebinarType;

/**
 * Webinar controller.
 * @TODO : Supprimer l'action countryAction & categoryAction qui ne sont plus utilisé
 * @TODO : Refactorer indexAction et renderList
 */
class WebinarController extends Controller
{
    public function navAction($route, $params)
    {
        $countryRepository = $this->container->get('eesa_santander.repository.country');
        $categoryRepository = $this->container->get('eesa_webinar.repository.category');

        if ($route == 'fo_webinar_index_user') {
            $nav = 'my_webinar';
        } elseif ($route == 'fo_webinar_archive') {
            $nav = 'archive';
        } elseif ($route == 'fo_webinar_country') {
            $nav = 'country';
        } elseif ($route == 'fo_webinar_category') {
            $nav = 'category';
        } elseif ($route == 'fo_webinar_get') {
            if (!empty($params['slug'])) {
                $webinarRepository = $this->container->get('eesa_webinar.repository.webinar');
                $webinar = $webinarRepository->findOneBySlug($params['slug']);

                if (empty($webinar)) {
                    return $this->return404();
                } elseif ($webinar->isIsOver()) {
                        $nav = 'archive';
                } else {
                    $nav = 'index';
                }
            } else {
                $nav = 'index';
            }
        } else {
            //fo_webinar_index
            $nav = 'index';
        }

        return $this->render('EesaSantanderBundle:Webinars:nav.html.twig', array(
            'countries'     => $countryRepository->findAllWithWebinar(),
            'categories'    => $categoryRepository->findAllWithWebinar(),
            'nav'           => $nav
        ));
    }

    /**
     * @param Request $request
     * @return JsonResponse|Response
     */
    public function listAction(Request $request)
    {
        $itemPerPage = 5;

        $contextManager = $this->get('eesa_santander.context_manager');
        $currentCountry = $contextManager->getUserCountry();
        if (!empty($currentCountry) && $currentCountry->getId() == 0) $currentCountry = null;

        if (!$request->isXmlHttpRequest()) {
            $page = $request->query->get('page', 1);
        } else {
            $page = $request->request->get('page', 1);
        }

        // TODO : Voir pour une autre méthode
        $options = [];
        if ($request->get('_route') == 'fo_webinar_archive') {
            // Page webcast
            $options = ['archive' => true];
        } elseif ($request->get('_route') == 'fo_webinar_index_user') {
            // Page my webinars
            $user = $this->getUser();
            if (!$user) {
                // TODO :
                return $this->return404();
            }
            $options = ['user' => $user];
        }

        // Init webinar form filter
        $formFilter = $this->get('form.factory')->create(
            new WebinarFilterType($this->getDataFilter($options, $currentCountry), $this->container->get('eesa_i18n.current_locale'))
        );

        if ($request->query->has($formFilter->getName()) || $request->request->has($formFilter->getName())) {
            $requestData = array_merge(
                (array) $request->request->get($formFilter->getName()),
                (array) $request->query->get($formFilter->getName())
            );

            $formFilter->submit($requestData);
        }

        // Get all webinars
        $webinarRepository = $this->container->get('eesa_webinar.repository.webinar');

        (empty($options['archive']) && empty($options['user'])) ? $lastPromotedWebinar = $webinarRepository->getLastPromotedWebinar() : $lastPromotedWebinar = null;

        $webinars = $webinarRepository->getAllWebinar(
            $page,
            $itemPerPage,
            $this->get('lexik_form_filter.query_builder_updater'),
            $formFilter,
            (in_array($request->request->get('order'), ['DESC', 'ASC'])) ? $request->request->get('order') : null,
            $options,
            $currentCountry,
            $lastPromotedWebinar
        );
        $countWebinar = $webinars->count();
        $hasNext = (ceil($countWebinar / $itemPerPage) <= $page) ? false : true;

        // On récupère les webinars ou le user est inscrit
        $isAttendeeIds = [];
        if ($this->getUser() && empty($options['user'])) {
            $isAttendeeIds = $this->getEm()->getRepository('EesaWebinarBundle:Attendee')->findAllWebinarIdByProfile($this->getUser()->getProfile());
        }

        // Retour
        // TODO : A revoir avec Thomas
        if ($request->isXmlHttpRequest()) {
            $html = $this->renderView('EesaSantanderBundle:Webinars:webinar.html.twig', array(
                'ajax' => true,
                'webinars' => $webinars,
                'count' => count($webinars),
                'isAttendeeIds' => $isAttendeeIds
            ));

            $response = new JsonResponse(array(
                'html' => $html,
                'next' => $hasNext,
            ));
        } else {
            $response = $this->render('EesaSantanderBundle:Webinars:index.html.twig', array(
                'webinars'              => $webinars,
                'count'                 => count($webinars),
                'page'                  => $page,
                'formFilter'            => $formFilter->createView(),
                'next'                  => $hasNext,
                'lastPromotedWebinar'   => (empty($options['archive']) && empty($options['user'])) ? $webinarRepository->getLastPromotedWebinar() : null,
                'archive'               => (!empty($options['archive'])) ? $options['archive'] : false,
                'user'                  => (!empty($options['user'])) ? $options['user'] : false,
                'isAttendeeIds'         => $isAttendeeIds
            ));
        }

        return $response;
    }

    /**
     * Retourne les données nécessaires pour les filtres de l'action renderList.
     * LexikFormFilterBundle ne gère pas les filtres sur des many to many.
     *
     * @param $options
     * @return array
     * @todo : Déplacer dans un service ?
     */
    private function getDataFilter($options, $currentCountry)
    {
        $webinarRepository = $this->container->get('eesa_webinar.repository.webinar');
        //$countryRepository = $this->container->get('eesa_santander.repository.country');
        $tagRepository = $this->container->get('eesa_webinar.repository.tag');
        $categoryRepository = $this->container->get('eesa_webinar.repository.category');
        $langRepository = $this->container->get('eesa_santander.repository.lang');

        // Data filtres
        $dataFilters = array();
        $categories = $categoryRepository->findAllWithWebinar($options);
        $dataFilters['categories'] = array();
        foreach ($categories as $category) {
            $count = $webinarRepository->countBy(array('name' => 'categories', 'value' => $category->getId()), $options, $currentCountry);
            if ($count == 0) continue;
            $dataFilters['categories'][$category->getId()] = $category->getTitle() . '|||' . $count;
        }
        $tags = $tagRepository->findAllWithWebinar($options);
        foreach ($tags as $tag) {
            $count = $webinarRepository->countBy(array('name' => 'tags', 'value' => $tag->getId()), $options, $currentCountry);
            if ($count == 0) continue;
            $dataFilters['tags'][$tag->getId()] = $tag->getTitle() . '|||' . $count;
        }
        /*$countries = $countryRepository->findAllWithWebinar($options);
        foreach ($countries as $country) {
            $count = $webinarRepository->countBy(array('name' => 'countries', 'value' => $country->getId()), $options);
            if ($count == 0) continue;
            $dataFilters['countries'][$country->getId()] = $country->getTitle() . '|||' . $count;
        }*/
        $langs = $langRepository->findAllWithWebinar($options);
        foreach ($langs as $lang) {
            $count = $webinarRepository->countBy(array('name' => 'lang', 'value' => $lang->getId()), $options, $currentCountry);
            if ($count == 0) continue;
            $dataFilters['lang'][$lang->getId()] = $lang->getTitle() . '|||' . $count;
        }

        return $dataFilters;
    }

    /**
     * @param Request $request
     * @return Response
     */
    public function getAction($slug)
    {
        $webinarRepository = $this->container->get('eesa_webinar.repository.webinar');
        $webinar = $webinarRepository->findOneBySlug($slug);

        if (empty($webinar)) {
            return $this->return404();
        }

        $profileManager = $this->container->get('eesa_santander.manager.profile');
        $isAttendee = $profileManager->isAttendee($this->getUser(), $webinar);

        return $this->render('EesaSantanderBundle:Webinars:get.html.twig', array(
            'webinar' => $webinar,
            'isAttendee' => $isAttendee
        ));
    }

    public function embedAction($slug)
    {
        $webinarRepository = $this->container->get('eesa_webinar.repository.webinar');
        $webinar = $webinarRepository->findOneBySlug($slug);

        return $this->render('EesaSantanderBundle:Webinars:embed.html.twig', array(
            'webinar' => $webinar,
        ));
    }

    public function registerAction()
    {
        switch ($this->getLocale()) {
            case 'es':
                $contactLink = 'https://santandertrade.com/es/contacte-banco-santander';
            case 'pt':
                $contactLink = 'https://santandertrade.com/pt/contacto-banco-santander';
            case 'pl':
                $contactLink = 'https://santandertrade.com/pl/kontakt-santander-bank';
            default:
                $contactLink = 'https://santandertrade.com/en/contact-santander-bank';
                break;
        }

        if($country = $this->get('eesa_santander.context_manager')->getUserCountry()) {
            $contactLink .= '?actualiser_id_banque=oui&id_banque=' . $country->getEesaId();
        }

        $this->addParam('contactLink', $contactLink);

        $userManager = $this->get('eesa_santander.user_manager');
        $user = $userManager->createUser();

        $nomenclatureManager = $this->container->get('eesa_data.nomenclature_manager');
        $form = $this->createForm(new \Eesa\SantanderBundle\Form\Type\Webinar\RegisterType(), $user, array('nomenclatureManager' => $nomenclatureManager));

        if ($this->isPost()) {
            $form->bind($this->getRequest());

            $vat = $form->get('profile')->get('companyVAT');
            $country = $form->get('profile')->get('country');

            // TODO : Faire un validateur
            if (!$this->container->get('eesa_geo.manager.vat')->tester_vat_selon_pays($country->getData()->getEesaId(), $vat->getData())) {
                $form->addError(new FormError('A valid VAT number is needed'));
                $this->addParam('vatError', true);
            }

            if ($form->isValid()) {
                $industryParent = $form->get('profile')->get('industryParent')->getData();
                $industry = $form->get('profile')->get('industry')->getData();
                $nomenclatureManager->setForProfile($user->getProfile(), $industryParent, $industry);

                $userManager->updateUserLevel($user, User::USER_LEVEL_CLIENT, false);
                $userManager->addUser($user, 'webinar');
                $this->addParam('user', $user);
                
                return $this->renderWithParams('EesaSantanderBundle:Webinars:register_end.html.twig');
            }
        }

        $this->addParams(array(
            'user' => $user,
            'form' => $form->createView(),
            'mainInterestChoices' => Profile::getMainInterestChoices(),
        ));

        return $this->renderWithParams('EesaSantanderBundle:Webinars:register.html.twig');
    }

    public function inscribeAction(Request $request, $slug)
    {
        $webinar = $this->container->get('eesa_webinar.repository.webinar')->findOneBySlug($slug);
        $user = $this->getUser();

        $profileManager = $this->container->get('eesa_santander.manager.profile');
        $isAttendee = $profileManager->isAttendee($user, $webinar);

        if ($request->getMethod(Request::METHOD_POST) && $request->isXmlHttpRequest() && $user && !empty($webinar) && !$isAttendee) {
            $this->container->get('eesa_webinar.service.webinar')->addAttendee($webinar, $user->getProfile());
            die('ok');
        } else {
            throw new \Symfony\Component\Security\Core\Exception\BadCredentialsException();
            die('ko');
        }
    }

    public function listNomenclatureAction()
    {
        $id = $this->getRequest()->get('nomenclature_id');

        $result = array();

        if($id) {
            $nomens = $this->get('eesa_data.nomenclature_manager')->getChildrens($id);

            foreach ($nomens as $nomen) {
                $result[$nomen->getId()] = $nomen->getLibelle($this->getLocale());
            }
        }
        
        return new JsonResponse($result);
    }

    public function uniqueEmailAction()
    {
        $email = $this->getRequest()->get('email');

        $user = $this->get('eesa_santander.user_manager')->getRepository()->findOneBy(array('email' => $email));

        if($user) {
            return $this->createResponse(400, 'ko');
        } else {
            return $this->createResponse(200, 'ok');
        }
    }

    public function afterWebinarAction()
    {
        // TODO : Rédirection en fonction de la langue :
        //$request->getPreferredLanguage();

        return $this->render('EesaSantanderBundle:Webinars:after_webinar.html.twig', array());
    }

    public function faqAction()
    {
        $lang = $this->container->get('eesa_santander.context_manager')->getCurrentContext();

        $isoCode = $lang->getCodeIso6391();
        if (!in_array($isoCode, ['en', 'es', 'pt', 'pl'])) {
            $isoCode = 'en';
        }

        return $this->render('EesaSantanderBundle:Webinars\Static:webinar-faq-' . $isoCode . '.html.twig', array());
    }

    public function tacAction()
    {
        $lang = $this->container->get('eesa_santander.context_manager')->getCurrentContext();

        $isoCode = $lang->getCodeIso6391();
        if (!in_array($isoCode, ['en', 'es', 'pt', 'pl'])) {
            $isoCode = 'en';
        }

        $this->addParam('isoCode', $isoCode);

        return $this->renderWithParams('EesaSantanderBundle:Webinars\Static:webinar-tac.html.twig', array());
    }

    /*public function importAttendee()
    {
        $em = $this->getEntityManager();
        $webinars = $em->getRepository('EesaWebinarBundle:Webinar')->findBy(['isPublished' => false, 'id' => 51]);
        $service = $this->container->get('eesa_webinar.service.webinar');

        foreach ($webinars as $webinar) {
            if ($webinar->getPromoter()) {
                $service->addAttendee($webinar, $webinar->getPromoter(), true);
            }
            foreach ($webinar->getSpeakers() as $speaker) {
                $service->addAttendee($webinar, $speaker);
            }
        }
    }*/

    public function vatAction(Request $request)
    {
        $id     = $request->query->get('id');
        $vat    = $request->query->get('vat');

        $response = new JsonResponse();

        if (!empty($vat) && !empty($id) && $this->container->get('eesa_geo.manager.vat')->tester_vat_selon_pays($id, $vat)) {
            $data = ['state' => 'success'];
            $response->setData($data);
            return $response;
        } else {
            $data = ['state' => 'error'];
            $response->setData($data);
            $response->setStatusCode(400);
            return $response;
        }
    }

    public function getCitiesFromTimezoneAction()
    {
        $timezone = $this->getRequest()->get('timezone');
        if(!$this->isAjax() || !$timezone) {
            return $this->return404();
        }

        $citiesTimezone = array(
            'Canberra' => 'Australia/Canberra', 
            'Manaus' => 'America/Manaus', 
            'Buenos Aires' => 'America/Buenos_Aires', 
            'Bogota' => 'America/Bogota', 
            'Bangkok' => 'Asia/Bangkok', 
            'Sao Paulo' => 'America/Sao_Paulo', 
            'London' => 'Europe/London', 
            'Shanghai' => 'Asia/Shanghai', 
            'Mexico City' => 'America/Mexico_City', 
            'Madrid' => 'Europe/Madrid', 
            'Denver' => 'America/Denver', 
            'Warsaw' => 'Europe/Warsaw', 
            'Berlin' => 'Europe/Berlin', 
            'Montevideo' => 'America/Montevideo', 
            'Lima' => 'America/Lima', 
            'Seoul' => 'Asia/Seoul', 
            'Lisbon' => 'Europe/Lisbon', 
            'Juneau' => 'America/Juneau', 
            'Los Angeles' => 'America/Los_Angeles', 
            'Moscow' => 'Europe/Moscow', 
            'Honolulu' => 'Pacific/Honolulu', 
            'La Paz' => 'America/La_Paz', 
            'Istanbul' => 'Asia/Istanbul', 
            'Qatar' => 'Asia/Qatar', 
            'Bangkok' => 'Asia/Bangkok', 
            'Port Moresby' => 'Pacific/Port_Moresby', 
            'Beirut' => 'Asia/Beirut',
            'Santiago' => 'America/Santiago',
        );
    
        $zone = new \DateTimeZone($timezone);
        $offset = $zone->getOffset(date_create('now'));

        $cities = array();
        foreach ($citiesTimezone as $cityName => $cityTimezoneName) {
            $cityTimezone = new \DateTimeZone($cityTimezoneName);
            if($cityTimezone->getOffset(date_create('now')) == $offset) {
                $cities[] = $cityName;
            }
        }
    
        return $this->createResponse(200, implode(', ', $cities));
    }

    public function visitorChooseCountryAction()
    {
        if(!$this->isPost() && !$this->isAjax()) {
            $this->return404();
        }

        $form = $this->createFormBuilder()
        ->add('country', 'entity', array(
            'label' => 'Select your country',
            'class' => 'EesaSantanderBundle:Country',
            'required' => true,
        ))
        ->add('lang', 'choice', array(
            'label' => 'Select your language',
            'choices' => array('en' => 'English', 'es' => 'Spanish', 'pt' => 'Portuguese', 'pl' => 'Polish'),
            'required' => true,
            'data' => 'en',
            'expanded' => true,
        ))->getForm();

        if($this->isFormBound($form)) {
            $this->get('eesa_santander.context_manager')->setUserCountry($form->get('country')->getData());

            return $this->redirectToRoute('fo_webinar_index', array('_locale' => $form->get('lang')->getData()));
        }

        $this->addParam('form', $form->createView());

        return $this->renderWithParams('EesaSantanderBundle:Webinars:modal/visitorChooseCountry.html.twig');
    }

    public function visitorLoginInvitationAction()
    {
        if(!$this->isAjax()) {
            $this->return404();
        }

        return $this->renderWithParams('EesaSantanderBundle:Webinars:modal/loginInvitation.html.twig');
    }

    public function visitorEmailInvitationAction()
    {
        $backUrl = $this->getRequest()->get('backUrl');

        $form = $this->createFormBuilder()
            ->add('email', 'email', array(
                'label' => 'Email',
                'required' => true,
                'constraints' => array(new NotBlank()),
            ))
            ->getForm();

        if($this->isFormBound($form)) {
            try {
                $this->getUser()->setEmail($form->get('email')->getData());
                $this->getUser()->setHasFakeEmail(false);
                $this->flush();
            } catch(\Exception $e) {
                $this->addFlash('warning', $this->trans('This email is already used.'));
            }

            return $this->redirect($backUrl);
        }

        $this->addParams(array(
            'form' => $form->createView(),
            'backUrl' => $backUrl,
        ));

        return $this->renderWithParams('EesaSantanderBundle:Webinars:modal/emailInvitation.html.twig');
    }

    public function termsModalAction()
    {
        if((!$this->isPost() && !$this->isAjax()) || !$this->getUser() || $this->getUser()->getProfile()->getWebinarTerms()) {
            $this->return404();
        }

        $form = $this->createFormBuilder()
        ->add('terms', 'checkbox', array(
            'label' => 'I have read and agreed to Santader Trade Webinars\'s Terms & Conditions.',
            'required' => false,
            'data' => false,
        ))->getForm();

        if($this->isFormBound($form)) {
            if($form->get('terms')->getData()) {
                $this->getUser()->getProfile()->setWebinarTerms(true);
                $this->flush();
            }

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

        $this->addParam('form', $form->createView());

        return $this->renderWithParams('EesaSantanderBundle:Webinars:modal/webinarTerms.html.twig');
    }
}