<?php

namespace AppBundle\EventListener;

use AppBundle\Mail\NewsletterMailer;
use AppBundle\Security\GRecaptchaHandler;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Psr\Log\LogLevel;
use Psr\Log\LoggerInterface;
class RequestSubscriber implements EventSubscriberInterface
{
    /**
     * @var NewsletterMailer
     */
    private $newsletterMailer;

    /**
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @var UserManagerInterface
     */
    private $userManager;

    /**
     * @var ValidatorInterface
     */
    private $validator;

    /**
     * @var GRecaptchaHandler
     */
    private $grecaptchaHandler;

    /**
     * @var LoggerInterface
     */
    private $logger;


    public function __construct(
        NewsletterMailer $newsletterMailer,
        TranslatorInterface $translator,
        UserManagerInterface $userManager,
        ValidatorInterface $validator,
        GRecaptchaHandler $grecaptchaHandler, 
        LoggerInterface $logger
    ) {
        $this->newsletterMailer = $newsletterMailer;
        $this->translator = $translator;
        $this->userManager = $userManager;
        $this->validator = $validator;
        $this->grecaptchaHandler = $grecaptchaHandler;
        $this->logger = $logger;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::REQUEST => [
                'addToNewsletter',
            ],
        ];
    }

    /**
     * 
     *
     * @param GetResponseEvent $event
     * @return void
     */
    public function addToNewsletter(GetResponseEvent $event): void
    {
        if (HttpKernel::MASTER_REQUEST === $event->getRequestType()) {
            $request = $event->getRequest();
            $session = $request->getSession();
            $newsletterEmail = $request->get('newsletter_subscription_simple_email');

            // Gère l'inscription à la newsletter depuis le formulaire simple :
            // Si la requête principale est un POST et que le champ newsletter_subscription_simple_email n'est pas vide,
            // alors on inscrit l'adresse mail à la newsletter.
            if ('POST' === $request->getMethod() && null !== $newsletterEmail) {
                // Check Recaptcha
                $result = $this->grecaptchaHandler->validateGRecaptchaResponse($request);

                if (is_array($result) && count($result) > 0) {
                    foreach ($result as $error) {
                        $session->getFlashBag()->add('newsletter_subscription_simple_errors', $error);
                    }
                } elseif ( $result === true ) {
                    // Dans un premier temps, on cherche à savoir si l'adresse mail correspond à celle d'un utilisateur enregistré
                    // afin de savoir s'il faudra mettre à jour son profil (case à cocher "Je souhaite m'inscrire à la newsletter")
                    $user = $this->userManager->findUserByEmail($newsletterEmail);
                    if (!$user) { // L'utilisateur n'est pas enregistré : création d'un utilisateur quasiment vide (requis pour l'inscription à la newsletter)
                        $user = $this->userManager->createUser();
                        $user->setEmail($newsletterEmail);
                    }

                    $violations = $this->validator->validateProperty($user, 'email', 'Registration');
                    if (count($violations) > 0) { // Erreurs de validation trouvées (normalement 1 seule possible : celle de l'adresse mail)
                        $this->logger->log(LogLevel::WARNING, json_encode($violations));
                        foreach ($violations as $violation) {
                            $session->getFlashBag()->add('newsletter_subscription_simple_errors', $violation->getMessage());
                        }
                        $session->getFlashBag()->add('newsletter_subscription_simple_errors', 'Cette adresse e-mail est déjà inscrite à la newsletter. 1');
                        // Redirige vers la page d'accueil
                      
                        $event->setResponse(new RedirectResponse($this->router->generate('_welcome')) . '#formNewsletter');
                    } else {
                        $user->setNewsletter(true);

                        $subscriptionResponse = $this->newsletterMailer->subscribe($user);
                        $this->logger->log(LogLevel::WARNING, json_encode($subscriptionResponse));
                        // Si l'utilisateur a été inscrit, on émet un message flash et on redirige l'utilisateur
                        // vers la même page, mais à l'aide d'une méthode GET cette fois-ci.
                        if ('success' === $subscriptionResponse['code']) {
                          
                            if ($user->getId()) { // Si l'utilisateur existe en BDD, on met à jour son profil
                                $this->userManager->updateUser($user);
                            }

                            $session->getFlashBag()->add(
                                'newsletter_subscription_simple_success', 'Vous êtes inscrit à notre newsletter'
                            );
                        } else {
                            $this->logger->log(LogLevel::WARNING, "ERROR");
                            $session->getFlashBag()->add('newsletter_subscription_simple_errors', 'Cette adresse e-mail est déjà inscrite à la newsletter. ' . $subscriptionResponse['code']);
                        }
                    }

                    $event->setResponse(new RedirectResponse($request->getRequestUri() . '#formNewsletter'));
                }
            }
        }
    }
}
