<?php

namespace KupShop\ProxyCacheBundle\EventListener;

use KupShop\KupShopBundle\Context\CacheContext;
use KupShop\KupShopBundle\Util\Contexts;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class CacheKeyChangeListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::RESPONSE => [
                ['changeCacheKeyCookie', 200],
                ['changeAdminCookie', 200],
            ],
        ];
    }

    protected string $cacheKeyword = 'cachekey';
    protected string $adminLoggedKeyword = 'adminlogged';

    public function changeCacheKeyCookie(ResponseEvent $event): void
    {
        /**
         * @var $cacheContext CacheContext
         */
        $cacheContext = Contexts::get(CacheContext::class);

        $response = $event->getResponse();

        $cacheKey = $this->getCacheKey();

        $key = $this->hashKey($cacheContext->getKey($cacheKey));
        $activeKey = $event->getRequest()->cookies->get($this->cacheKeyword);

        if ($key == $activeKey) {
            return;
        }

        $defaultKey = $this->hashKey($cacheContext->getDefaultKey($cacheKey));

        if ($key == $defaultKey) {
            if ($activeKey) {
                $response->headers->clearCookie($this->cacheKeyword);
            }

            return;
        }

        $response->headers->setCookie(new Cookie($this->cacheKeyword, $key, strtotime('now +1 year')));
    }

    protected function hashKey(?string $key): ?string
    {
        if (is_null($key)) {
            return null;
        }

        return $key;
    }

    protected function getCacheKey(): array
    {
        return [CacheContext::TYPE_FULL_PAGE];
    }

    public function changeAdminCookie(ResponseEvent $event): void
    {
        $adminLoggedCookie = $event->getRequest()->cookies->has($this->adminLoggedKeyword);
        if (getAdminUser() && !$adminLoggedCookie) {
            $event->getResponse()->headers->setCookie(new Cookie($this->adminLoggedKeyword, 1));
        } elseif (!getAdminUser() && $adminLoggedCookie) {
            $event->getResponse()->headers->clearCookie($this->adminLoggedKeyword);
        }
    }
}
