<?php
namespace App\EventListener;

use App\Events\MLCEvents;
use App\Events\FluxEvent;
use App\Entity\Flux;
use App\Entity\GlobalParameter;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Templating\EngineInterface;
use Symfony\Component\Translation\TranslatorInterface;

/**
 * Listener responsable des évènements liés aux flux (transfert, transaction, retrait, vente...)
 */
class MLCEventListener implements EventSubscriberInterface
{
    protected $em;
    protected $mailer;
    protected $params;
    protected $templating;
    protected $translator;
    protected $router;
    protected $userManager;
    protected $tokenGenerator;

    public function __construct(EntityManagerInterface $em, \Swift_Mailer $mailer, RouterInterface $router, ParameterBagInterface $params, EngineInterface $templating, TranslatorInterface $translator, UserManagerInterface $userManager, TokenGeneratorInterface $tokenGenerator)
    {
        $this->em = $em;
        $this->mailer = $mailer;
        $this->params = $params;
        $this->templating = $templating;
        $this->translator = $translator;
        $this->router = $router;
        $this->userManager = $userManager;
        $this->tokenGenerator = $tokenGenerator;
    }

    // public function setMailer(TwigSwiftMailer $maileri)
    // {
    // }

    public static function getSubscribedEvents()
    {
        return array(
            MLCEvents::REGISTRATION_ADHERENT => 'onRegistrationAdherent',
            MLCEvents::FLUX => 'onFlux',
            MLCEvents::COTISATION_COTISATION => 'onCotisation',
            MLCEvents::COTISATION_COTISATION_ADHERENT => 'onCotisation',
            MLCEvents::COTISATION_COTISATION_PRESTATAIRE => 'onCotisation',
            MLCEvents::TRANSACTION_ADHERENT_ADHERENT => 'onTransaction',
            MLCEvents::TRANSACTION_ADHERENT_PRESTATAIRE => 'onTransaction',
            MLCEvents::TRANSACTION_PRESTATAIRE_ADHERENT => 'onTransaction',
            MLCEvents::TRANSACTION_PRESTATAIRE_PRESTATAIRE => 'onTransaction',
            MLCEvents::TRANSFERT_COMPTOIR_GROUPE => 'onTransfert',
            MLCEvents::TRANSFERT_GROUPE_COMPTOIR => 'onTransfert',
            MLCEvents::TRANSFERT_GROUPE_SIEGE => 'onTransfert',
            MLCEvents::TRANSFERT_SIEGE_GROUPE => 'onTransfert',
            MLCEvents::TRANSFERT_PRESTATAIRE_COMPTOIR => 'onDepot',
            MLCEvents::TRANSFERT_PRESTATAIRE_SIEGE => 'onReconversion',
            MLCEvents::RETRAIT_COMPTOIR_ADHERENT => 'onRetrait',
            MLCEvents::RETRAIT_COMPTOIR_PRESTATAIRE => 'onRetrait',
            MLCEvents::VENTE_COMPTOIR_ADHERENT => 'onVente',
            MLCEvents::VENTE_COMPTOIR_PRESTATAIRE => 'onVente',
        );
    }

    public function onRegistrationAdherent(UserEvent $event)
    {
        $user = $event->getUser();
        //Set confirmation token (alike resetting password)
        if (null === $user->getConfirmationToken()) {
            $user->setConfirmationToken($this->tokenGenerator->generateToken());
        }

        // this depends on requirements
        $user->setPasswordRequestedAt(new \DateTime());
        $this->userManager->updateUser($user);

        $subject = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_NAME_SMALL).' : '.$this->translator->trans('Création de votre compte adhérent');
        $mail = (new \Swift_Message($subject))
            ->setFrom($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_NOTIF_EMAIL))
            ->setTo($user->getEmail())
            ->setBody(
                $this->templating->render(
                    'email/admin_add_adherent.html.twig',
                    array(
                        'subject' => $subject,
                        'user' => $user,
                        'confirmationUrl' => $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL),
                    )
                ),
                'text/html'
            );
        $this->mailer->send($mail);
    }

    public function onFlux(FluxEvent $event)
    {
        foreach ($event->getFlux()->getUsersToNotify() as $user) {
            if ($user instanceof User && $user->getAlertemailflux()) {
                $this->sendMail($user, $event->getFlux());
            } elseif ($user == 'siege') {
                $users = $this->em->getRepository(User::class)->findByRole('ROLE_ADMIN_SIEGE');
                foreach ($users as $userAdminSiege) {
                    if ($userAdminSiege->getAlertemailflux()) {
                        $this->sendMail($userAdminSiege, $event->getFlux());
                    }
                }
            }
        }
    }

    private function sendMail(User $user, Flux $flux)
    {
        // @TODO => un mail différent en fonction du type de flux (et de l'utilisateur ?)
        $subject = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_NAME_SMALL).' : ';
        $mail = (new \Swift_Message($subject))
            ->setFrom($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_NOTIF_EMAIL))
            ->setTo($user->getEmail())
            ->setBody(
                $this->templating->render(
                    'email/notification_flux.html.twig',
                    array(
                        'subject' => $subject,
                        'user' => $user,
                        'flux' => $flux
                    )
                ),
                'text/html'
            );
        $this->mailer->send($mail);
    }

    // @TODO => notifications/emails differents suivant le type d'action
    public function onCotisation(FluxEvent $event)
    {
    }

    public function onTransaction(FluxEvent $event)
    {
    }

    public function onTransfert(FluxEvent $event)
    {
    }

    public function onDepot(FluxEvent $event)
    {
    }

    public function onReconversion(FluxEvent $event)
    {
    }

    public function onRetrait(FluxEvent $event)
    {
    }

    public function onVente(FluxEvent $event)
    {
    }
}