<?php

declare(strict_types=1);

namespace KupShop\CatalogElasticBundle\Util;

use KupShop\CatalogBundle\ProductList\Builder\BuilderState;
use KupShop\CatalogBundle\ProductList\Builder\CompileStrategy;
use KupShop\CatalogBundle\ProductList\Builder\FilteredProductListInterface;
use KupShop\CatalogBundle\ProductList\DynamicFilterAttributes;
use KupShop\CatalogElasticBundle\SectionRequest;
use KupShop\RestrictionsBundle\Utils\Restrictions;

class ElasticCompileStrategy implements CompileStrategy
{
    public function __construct(
        protected readonly ElasticQueryClient $queryClient,
        protected readonly ?Restrictions $restrictions,
    ) {
    }

    public function compile(BuilderState $state): FilteredProductListInterface
    {
        $baseFilterParams = $state->baseFilterParams ?? \FilterParams::createDefault($state->resultEntity);
        $filterParams = $state->filterData instanceof \FilterParams
            ? $state->filterData
            : clone $baseFilterParams;

        $filter = new \Filter($filterParams);
        if (is_array($state->filterData) && !empty($state->filterData)) {
            $filter->setFilterData($state->filterData);
        }

        $filterAttributes = $state->dynamicFilterAttributes ?? new DynamicFilterAttributes();
        $restrictionFilterParams = findModule(\Modules::RESTRICTIONS) ? $this->restrictions->getRestrictionFilterParams() : null;

        $request = new SectionRequest(
            filterParams: $filterParams,
            baseFilterParams: $baseFilterParams,
            restrictionsFilterParams: $restrictionFilterParams,
            dynamicFilterAttributes: $filterAttributes,
            categorySort: $state->categorySort,
            orderBy: $state->orderBy,
            orderDir: $state->orderDirection,
            pager: $state->pager,
            fetchAllFilters: $state->fetchAllFilters,
        );

        if ($request->isSearchRequest()) {
            $filterParams->setShowInSearch(true);
        }

        // Nevolám ->applyDefaultFilterParams()!
        // Stejně nefungují custom specky, takže pokud chceš něco upravit ve \FilterParams, tak se to stane když se nahoře
        // \FilterParams vytvoří (ta eventa se zavolá). Ale custom specky se stejně nenavážou, pouze změny v membrech,
        // všechno musí jít přes ES.
        $productList = new \ProductList($state->resultEntity === \FilterParams::ENTITY_VARIATION);

        return $this->queryClient->prepareSectionQuery(
            $request,
            $productList,
            $filter,
            $state->pager,
            $filterAttributes,
        );
    }
}
