<?php
/**
 * @author Colinet Julien
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\EventListener;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Client\IpGeoClient;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Utils\Mailer;
use CpCreation\VitiCore\Shop\Model\ShopConfig;
use CpCreation\VitiCore\Shop\Model\ShopConfigDisableCountry;
use CpCreation\VitiCore\Shop\Repository\ShopConfigDisableCountryRepository;
use CpCreation\VitiCore\Shop\Repository\ShopConfigRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;

class FilterShopCountrySubscriber implements EventSubscriberInterface
{
    private $ipGeoClient;
    private $shopConfigRepository;
    private $shopConfigDisableCountryRepository;
    private $session;
    private $mailer;

    /**
     * FilterShopCountrySubscriber constructor.
     * @param IpGeoClient          $ipGeoClient
     * @param ShopConfigRepository $shopConfigRepository
     * @param SessionInterface     $session
     * @param Mailer               $mailer
     */
    public function __construct(
        IpGeoClient $ipGeoClient,
        ShopConfigRepository $shopConfigRepository,
        ShopConfigDisableCountryRepository $shopConfigDisableCountryRepository,
        SessionInterface $session,
        Mailer $mailer
    ) {
        $this->ipGeoClient                        = $ipGeoClient;
        $this->shopConfigRepository               = $shopConfigRepository;
        $this->shopConfigDisableCountryRepository = $shopConfigDisableCountryRepository;
        $this->session                            = $session;
        $this->mailer                             = $mailer;


    }

    public
    function onKernelRequest(RequestEvent $event
    ) {
        $request = $event->getRequest();

        if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST || $request->attributes->get('_route') != "shop") {
            return;
        }

        if (preg_match('/baidu|dareboost|bingbot|facebookexternalhit|googlebot|-google|ia_archiver|msnbot|naverbot|pingdom|seznambot|slurp|teoma|twitter|yandex|yeti|speed|insights|woobot|ighth|tmetr|eadle|gtmetrix|lighthouse/i', $_SERVER['HTTP_USER_AGENT'])) {
            $this->session->set('country', 'FR');
            $this->session->set('blockShop', false);

            return;
        }
        $blockShop = $this->session->get('blockShop', null);
        if (is_null($blockShop)) {
            try {
                $response = $this->ipGeoClient->get(
                    '/'.$request->getClientIp(), [
                        'query' => [
                            'access_key' => 'b9f002d1df3521ce2f32fdc9eb2a08de',
                        ],
                    ]
                );

                $result = json_decode($response->getBody()->getContents(), true);
                if ($result['country_code']) {
                    $country = $result['country_code'];
                } else {
                    $this->mailer->sendErrorIpLocate('Request OK, but country is not defined '.json_encode($result), $request->getClientIp());
                    $country = 'FR';
                }
            } catch (\Exception $e) {

                $this->mailer->sendErrorIpLocate($e->getMessage(), $request->getClientIp());
                $country = 'FR';
            }

            $this->testCountry($country);
        }
    }

    public
    static function getSubscribedEvents()
    {
        return [
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            KernelEvents::REQUEST => [['onKernelRequest', 20]],
        ];
    }

    /**
     * @param $country
     * @return RedirectResponse
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    private function testCountry($country)
    {
        /** @var ShopConfig $configShop */
        $configShop = $this->shopConfigRepository->findOne();
        if ($configShop->getDisableCountries()->count() > 0) {
            if ($this->shopConfigDisableCountryRepository->findOneBy(['country' => $country])) {
                $this->session->set('blockShop', true);
                $this->session->set('blockShopCountry', $country);

                return;
            }
        }
        if (count($configShop->getEnableCountriesForShop()) > 0) {
            if (!in_array($country, $configShop->getEnableCountriesForShop())) {
                $this->session->set('blockShop', true);
                $this->session->set('blockShopCountry', $country);

                return;
            }
        }


        $this->session->set('blockShopCountry', $country);
        $this->session->set('blockShop', false);

        return;
    }
}
