<?php

declare(strict_types=1);

namespace KupShop\ProxyCacheBundle\Util;

use KupShop\I18nBundle\Translations\SectionsTranslation;
use KupShop\KupShopBundle\Context\DomainContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\StringUtil;
use Query\Operator;
use Query\QueryBuilder;
use Query\Translation;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

class CookiesFunctionalityTest
{
    public const WIKI_LINK = 'https://gitlab.wpj.cz/kupshop/engine/-/wikis/Reverzn%C3%AD-ke%C5%A1ovac%C3%AD-proxy-%E2%80%93-full-page-cache';

    public function __construct(
        private HttpClientInterface $client,
        private UrlGeneratorInterface $urlGenerator,
        private array $domains,
    ) {
    }

    public function testInitialRequestCookiesAbsence()
    {
        $scheme = Contexts::get(DomainContext::class)->getActiveWithScheme();
        $domains = $this->getActiveDomains();

        if (empty($domains)) { // if "shop.domains" config is not set on the shop
            $domains = [Contexts::get(DomainContext::class)->getActiveId()];
        }

        foreach ($domains as $domain) {
            $requestPaths = [
                '/',
                $this->getSectionPath($domain),
            ];

            foreach (array_filter($requestPaths) as $requestPath) {
                $cookies = $this->makeRequest($scheme, $requestPath, $domain);

                foreach ($cookies as $cookie) {
                    yield $domain.$requestPath.': '.$cookie;
                }
            }
        }
    }

    private function getSectionPath($domain): string|false
    {
        $lang = $this->domains[$domain]['language'] ?? false;

        $someSectionId = sqlQueryBuilder()->select('s.id, s.figure')->from('sections', 's')
            ->andWhere(Translation::joinTranslations([$lang],
                ServiceContainer::getService(SectionsTranslation::class),
                function (QueryBuilder $qb, $columnName, $translatedField) {
                    $qb->andWhere(Operator::coalesce($translatedField, 's.figure').' = "Y" ');

                    return false;
                },
                ['figure']))
            ->andWhere('s.id > 0')
            ->orderBy('RAND()')->setMaxResults(1)->execute()->fetchColumn();

        if (!$someSectionId) {
            return false;
        }

        return $this->urlGenerator->generate('kupshop_catalog_catalog_section',
            ['parent_sections' => '', 'url_section' => 'test', 'id_section' => $someSectionId]);
    }

    private function makeRequest($scheme, $path, $domain): array
    {
        $bustCacheParam = '?cache_bust='.time();

        $response = $this->client->request('GET', $scheme.$path.$bustCacheParam, [
            'verify_host' => false,
            'verify_peer' => false,
            'headers' => [
                'X-WPJ-SOURCE' => 'PROXY_CACHE:CookiesFunctionalityTest',
                'Host' => $domain,
            ]]);

        if ($response->getStatusCode() !== 200) {
            return [];
        }

        $responseHeaders = $response->getHeaders();

        $cookies = array_filter($responseHeaders['set-cookie'] ?? [], function ($cookie) {
            return !str_starts_with($cookie, 'sf_redirect');
        });

        return $cookies;
    }

    private function getActiveDomains(): array
    {
        $domains = array_keys($this->domains);

        if (isProduction()) {
            $domains = array_filter($domains, function ($domain) {
                return !StringUtil::endsWith($domain, '.wpjshop.cz');
            });
        }

        if (!isLocalDevelopment()) {
            $domains = array_filter($domains, function ($domain) {
                return !StringUtil::endsWith($domain, 'kupshop.local');
            });
        }

        return $domains;
    }
}
