<?php

namespace Lc\CaracoleBundle\EventSubscriber\User;

use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Resolver\MerchantResolver;
use Lc\SovBundle\Definition\RolesDefinition;
use Lc\SovBundle\Model\User\UserInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;

class UserRolesEventSubscriber implements EventSubscriberInterface
{
    protected $em;
    protected $tokenStorage;
    protected $router;
    protected $merchantResolver;

    public function __construct(
            TokenStorageInterface $tokenStorage,
            EntityManagerInterface $entityManager,
            RouterInterface $router,
            MerchantResolver $merchantResolver
    ) {
        $this->em = $entityManager;
        $this->tokenStorage = $tokenStorage;
        $this->router = $router;
        $this->merchantResolver = $merchantResolver;
    }

    public static function getSubscribedEvents()
    {
        return [
                KernelEvents::REQUEST => ['setUserRolesFromKernelRequest'],
                SecurityEvents::INTERACTIVE_LOGIN => ['setUserRolesAuthenticationSuccess'],
        ];
    }

    public function setUserRolesFromKernelRequest(RequestEvent $event)
    {
        if (!$event->isMasterRequest()) {
            return;
        }
        if ($this->setUserRoles($event->getRequest())) {
            $response = new RedirectResponse($this->router->generate('app_admin_dashboard'));
            $event->setResponse($response);
        }
    }

    public function setUserRolesAuthenticationSuccess(InteractiveLoginEvent $interactiveLoginEvent)
    {
        $this->setUserRoles($interactiveLoginEvent->getRequest());
    }


    public function setUserRoles(Request $request): bool
    {
        if ($this->tokenStorage && $this->tokenStorage->getToken()) {
            $token = $this->tokenStorage->getToken();
            $sessionUser = $token->getUser();

            if ($sessionUser instanceof UserInterface) {
                $userMerchant = $this->merchantResolver->getUserMerchant($sessionUser);

                if ($userMerchant) {
                    $roles = $userMerchant->getRoles();
                } else {
                    $roles = [RolesDefinition::ROLE_USER];
                }

                if ($roles != $sessionUser->getRoles()) {
                    $sessionUser->setRoles($roles);
                    $this->em->update($sessionUser);
                    $this->em->flush();

                    $token = new UsernamePasswordToken(
                            $sessionUser,
                            null,
                            'main',
                            $sessionUser->getRoles()
                    );
                    $this->tokenStorage->setToken($token);

                    return true;
                }
            }

        }
        return false;
    }


}