<?php
/**
 * @author Amasty Team
 * @copyright Copyright (c) Amasty (https://www.amasty.com)
 * @package Advanced Search Base for Magento 2
 */

namespace Amasty\Xsearch\Controller\Autocomplete;

use Amasty\Xsearch\Block\MultipleWishlist\Behavior;
use Magento\Catalog\Model\Layer\Resolver;
use Magento\Framework\App\Action\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Search\Model\QueryFactory;
use Amasty\Xsearch\Controller\RegistryConstants;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\CatalogSearch\Model\ResourceModel\EngineProvider;

class Index extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Amasty\Xsearch\Helper\Data
     */
    private $helper;

    /**
     * @var \Magento\Framework\Url\DecoderInterface
     */
    private $urlDecoder;

    /**
     * @var \Magento\Framework\Url\Helper\Data
     */
    private $urlHelper;

    /**
     * @var QueryFactory
     */
    private $queryFactory;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var Resolver
     */
    private $layerResolver;

    /**
     * @var \Magento\Framework\Registry
     */
    private $coreRegistry;

    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    private $resultJsonFactory;

    /**
     * @var \Magento\Framework\View\LayoutFactory
     */
    private $layoutFactory;

    /**
     * @var \Magento\CatalogSearch\Helper\Data
     */
    private $searchHelper;

    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var \Magento\Framework\Data\Form\FormKey\Validator
     */
    private $formKeyValidator;

    /**
     * @var Behavior
     */
    private $behavior;

    public function __construct(
        Context $context,
        StoreManagerInterface $storeManager,
        QueryFactory $queryFactory,
        Resolver $layerResolver,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Framework\View\LayoutFactory $layoutFactory,
        \Magento\Framework\Registry $coreRegistry,
        \Amasty\Xsearch\Helper\Data $helper,
        \Magento\Framework\Url\DecoderInterface $urlDecoder,
        \Magento\Framework\Url\Helper\Data $urlHelper,
        \Magento\CatalogSearch\Helper\Data $searchHelper,
        ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator,
        Behavior $behavior
    ) {
        parent::__construct($context);
        $this->helper = $helper;
        $this->urlDecoder = $urlDecoder;
        $this->urlHelper = $urlHelper;
        $this->queryFactory = $queryFactory;
        $this->storeManager = $storeManager;
        $this->layerResolver = $layerResolver;
        $this->coreRegistry = $coreRegistry;
        $this->resultJsonFactory = $resultJsonFactory;
        $this->layoutFactory = $layoutFactory;
        $this->searchHelper = $searchHelper;
        $this->scopeConfig = $scopeConfig;
        $this->formKeyValidator = $formKeyValidator;
        $this->behavior = $behavior;
    }

    public function execute()
    {
        if (!$this->getRequest()->isAjax() || !$this->formKeyValidator->validate($this->getRequest())) {
            $this->getResponse()->setStatusHeader(403, '1.1', 'Forbidden');
            return null;
        }

        $this->layerResolver->create(Resolver::CATALOG_LAYER_SEARCH);

        /** @var \Magento\Search\Model\Query $query */
        $query = $this->queryFactory->get();
        $query->setStoreId($this->storeManager->getStore()->getId());
        $engine = $this->scopeConfig->getValue(EngineProvider::CONFIG_ENGINE_PATH);
        $query = $this->helper->setStrippedQueryText(
            $query,
            $engine
        ); //replace only for mysql (for a search by products)

        $this->coreRegistry->register(RegistryConstants::CURRENT_AMASTY_XSEARCH_QUERY, $query, true);
        if ($query->getQueryText() != '') {
            if ($this->searchHelper->isMinQueryLength()) {
                $query->setId(0)->setIsActive(1)->setIsProcessed(1);
            } else {
                $query->saveIncrementalPopularity();
            }
        }

        $layout = $this->layoutFactory->create();
        $resultJson = $this->resultJsonFactory->create();
        $beforeUrl = $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED);

        $blocks = $this->helper->getBlocksHtml($layout);
        if ($beforeUrl && is_string($beforeUrl)) {
            $blocks = $this->replaceRelatedUrl($blocks, $beforeUrl);
        }

        $blocks['behavior'] = $this->behavior->toHtml();

        return $resultJson->setData($blocks);
    }

    private function replaceRelatedUrl(array $blocks, string $beforeUrl): array
    {
        foreach ($blocks as $key => $data) {
            if (is_array($data) && array_key_exists('html', $data)) {
                /**
                 * by xss protection
                 */
                $beforeUrl = $this->urlDecoder->decode($beforeUrl);
                $beforeUrl = $this->urlHelper->getEncodedUrl($beforeUrl);
                $blocks[$key]['html'] = str_replace($this->urlHelper->getEncodedUrl(), $beforeUrl, $data['html']);
            }
        }

        return $blocks;
    }
}
