<?php
/**
 * Copyright © 2019 Wyomind. All rights reserved.
 * See LICENSE.txt for license details.
 */

/**
 * Created by PhpStorm.
 * User: Paul
 * Date: 20/11/2019
 * Time: 11:02
 */

namespace Wyomind\ElasticsearchLayeredNavigation\Helper;


use Magento\Customer\Model\Session;
use Magento\Framework\App\Response\Http;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\App\RequestInterface;
use Magento\Store\Model\StoreManager;
use Wyomind\ElasticsearchCore\Helper\Currency;
use Wyomind\ElasticsearchCore\Helper\Data;
use Wyomind\ElasticsearchCore\Helper\Tax;

class Frontend extends \Magento\Framework\App\Helper\AbstractHelper
{

    /**
     * @var Data
     */
    protected $dataHelper;
    /**
     * @var Category
     */
    protected $categoryHelper;
    /**
     * @var Toolbar
     */
    protected $toolbarHelper;
    /**
     * @var Config
     */
    protected $configHelper;
    /**
     * @var Currency
     */
    protected $currencyHelper;
    /**
     * @var Tax
     */
    protected $taxHelper;
    /**
     * @var RequestInterface
     */
    public $request;
    /**
     * @var Http
     */
    protected $response;
    /**
     * @var StoreManager
     */
    protected $storeManager;
    /**
     * @var Session
     */
    protected $customerSession;

    /**
     * @var array
     */
    private $result = null;

    private $seoCategoryUrlSuffix = ".html";

    protected $productRepository;

    protected $gender;

    protected $helperImage;

    /**
     * Frontend constructor.
     * @param Data $dataHelper
     * @param Category $categoryHelper
     * @param Toolbar $toolbarHelper
     * @param Config $configHelper
     * @param Currency $currentyHelper
     * @param Tax $taxHelper
     * @param RequestInterface $request
     * @param Http $response
     * @param StoreManager $storeManager
     * @param Session $customerSession
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function __construct(
        Data $dataHelper,
        Category $categoryHelper,
        Toolbar $toolbarHelper,
        Config $configHelper,
        Currency $currentyHelper,
        Tax $taxHelper,
        RequestInterface $request,
        Http $response,
        StoreManager $storeManager,
        Session $customerSession,
        \Magento\Catalog\Api\ProductRepositoryInterface  $productRepository,
        \Drop\PaciottiGenderFirst\Helper\Gender          $gender,
        \Magento\Catalog\Helper\Image                    $helperImage
    )
    {
        $this->dataHelper = $dataHelper;
        $this->categoryHelper = $categoryHelper;
        $this->toolbarHelper = $toolbarHelper;
        $this->configHelper = $configHelper;
        $this->currencyHelper = $currentyHelper;
        $this->taxHelper = $taxHelper;
        $this->request = $request;
        $this->response = $response;
        $this->storeManager = $storeManager;
        $this->seoCategoryUrlSuffix = $configHelper->getSEOCategoryUrlSuffix($this->storeManager->getStore()->getId());
        $this->customerSession = $customerSession;

        $this->productRepository = $productRepository;
        $this->gender            = $gender;
        $this->helperImage       = $helperImage;
    }

    /**
     * @param $blockType
     * @return array
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getResult($blockType)
    {

        if ($this->result == null) {
            $storeId = $this->dataHelper->getCurrentStoreId();
            $storeCode = $this->dataHelper->getCurrentStoreCode();
            $searchTerm = "";
            $params = $this->request->getParams(); //filter_input_array(INPUT_GET);


            if (isset($params['q']) && $params['q'] !== null) {
                $searchTerm = $params['q'];
            }
            $currentCategory = $this->categoryHelper->getCurrentCategoryId();

            $currentOrder = $this->toolbarHelper->getCurrentOrder($blockType);
            $currentDirection = $this->toolbarHelper->getCurrentDirection($blockType);
            $isInfiniteScrollEnabled = $this->configHelper->isInfiniteScrollEnabled($blockType, $storeId);

            $infiniteScrollStep = $this->configHelper->getInfiniteScrollStep($blockType, $storeId);
            $isHighlightEnabled = $this->configHelper->isHighlightEnabled($storeId);
            $currentPerPage = $this->toolbarHelper->getCurrentPerPage();
            $layerUpdateSorting = $this->configHelper->getLayerUpdateSorting($blockType, $storeId);

            $size = $isInfiniteScrollEnabled ? $infiniteScrollStep : $currentPerPage;
            $from = 0;
            if (!$isInfiniteScrollEnabled && isset($params['page']) && $params['page'] !== null) {
                $from = ($params['page']-1)*$size;
            }

            try {
                $config = new \Wyomind\ElasticsearchCore\Helper\Autocomplete\Config($storeCode);
                $configData = $config->getData();

                $client = new \Wyomind\ElasticsearchCore\Model\Client($config);
                $client->init($storeCode);

                $cache = new \Wyomind\ElasticsearchCore\Helper\Cache\FileSystem();
                $synonymsHelper = new \Wyomind\ElasticsearchCore\Helper\Synonyms();

                $searchTerm = trim($searchTerm);

                $requester      = new \Wyomind\ElasticsearchCore\Helper\Requester($client, $config, $cache, $synonymsHelper, $this->productRepository, $this->gender, $this->helperImage);
                if (isset($configData['display_outofstock_products'])) {
                    $requester->setDisplayOutofstockProducts($configData['display_outofstock_products']);
                }

                if (!isset($customerGroupId)) {
                    if ($this->customerSession->isLoggedIn()) {
                        $customerGroupId = $this->customerSession->getCustomer()->getGroupId();
                    } else {
                        $customerGroupId = 0;
                    }
                }



                $filters = $this->getFilters();

                $this->result = $requester->getProducts($storeCode, $customerGroupId, $currentCategory, $searchTerm, $from, $size, $currentOrder, $currentDirection, $filters, true, true, $isHighlightEnabled, $layerUpdateSorting);
                $eaHighlightEnabled = true;//@todo $eaConfig['highlight_enabled'];
                $this->result['suggest'] = $requester->getSuggestions($storeCode, $searchTerm, 1);
                $categoriesLimit = 5;
                $this->result["category"] = $requester->searchByType($storeCode, "category", $searchTerm, $categoriesLimit, $eaHighlightEnabled);
                $cmsLimit = 5;
                $this->result["cms"] = $requester->searchByType($storeCode, "cms", $searchTerm, $cmsLimit, $eaHighlightEnabled);

                $this->result['customerGroupId'] = $customerGroupId;

            } catch (\Exception $e) {
                //$this->response->setRedirect('/');
                throw $e;
            }
        }

        return $this->result;
    }

    public function getFilters()
    {
        $args = $this->request->getParam('filters');
        $json = [];
        if ($args != null) {
            foreach ($args as $key => $data) {
                if ($key == "q" || $key == "id") {
                    continue;
                }
                if (substr($data, 0, 1) == "[") {
                    $tmpjson = [];
                    $tmpdata = explode(',', str_replace(['[', ']'], '', $data));
                    foreach ($tmpdata as $prop) {
                        $prop = explode(':', $prop);
                        $tmpjson[$prop[0]] = $prop[1];
                    }
                    $data = $tmpjson;
                } else {
                    $data = explode('-', $data);
                    $c = count($data);
                    for ($i = 0; $i < $c; $i++) {
                        $data[$i] = urldecode(str_replace('_', '-', $data[$i]));
                    }
                }
                $json[$key] = $data;
            }
        }
        return $json;

    }


    public function getPrice($price, $productTaxClassId = null)
    {
        return $this->calculateTax($this->convertPrice($price), $productTaxClassId);
    }

    public function calculateTax($price, $productTaxClassId)
    {
        return $price;
        $needPriceConversion = $this->taxHelper->needPriceConversion();
        $taxRates = $this->taxHelper->getRates();
        if (!$productTaxClassId || !$needPriceConversion || !$taxRates[$productTaxClassId]) {
            return $price;
        }

        $rate = $taxRates[$productTaxClassId] / 100;
        $priceIncludesTax = $this->taxHelper->priceIncludesTax();

        if ($priceIncludesTax) {
            return $price / (1 + $rate);
        }

        return $price + $price * $rate;
    }

    public function convertPrice($price)
    {
        //$rate = $this->currencyHelper->getCurrentCurrencyRate();
        return $price;// * $rate;
    }

    public function getParams()
    {
        return $this->request->getParams();
    }


//    public function urldecode($toDecode) {
//        return urldecode(str_replace(['®','™'],['r','tm'],$toDecode));
//    }

    public function createFilterUrl($generateUrl, $attributeCode, $label)
    {
        if (!$generateUrl) return "#";
        $attributeCode = str_replace('_ids', '', $attributeCode);
        $label = strtolower($label);
        $requestParams = $this->request->getParam('filters');
        if (isset($requestParams[$attributeCode]) && is_string($requestParams[$attributeCode])) {
            $requestParams[$attributeCode] = explode('-', $requestParams[$attributeCode]);

        }
        $requestParams[$attributeCode][] = str_replace('-', '_', $label);

        $params = [];
        foreach ($requestParams as $attribute => $param) {
            //if ($attribute != "q") {
            if (!is_array($param)) {
                $param = explode('-', $param);
            }
            asort($param);
            $param = implode('-', array_unique(array_filter($param)));
            $params[] = str_replace('_ids', '', $attribute) . "/" . $param;
            //}
        }
        $params = implode("/", $params);
        if ($this->request->getParam('q') != null) {
            $params = "catalogsearch/result/" . $this->request->getParam('q') . "/" . $params;
            return "/" . strtolower($params);
        } else {
            return str_replace($this->seoCategoryUrlSuffix, '', $this->categoryHelper->getCurrentCategoryUrl()) . '/' . strtolower($params) . $this->seoCategoryUrlSuffix;
        }
    }

    public function createFilterUrlMinus($generateUrl, $attributeCode, $label)
    {
        if (!$generateUrl) return "#";
        $attributeCode = str_replace('_ids', '', $attributeCode);
        $label = strtolower(str_replace('-', '_', $label));
        $requestParams = $this->request->getParam('filters');

        if (isset($requestParams[$attributeCode]) && is_string($requestParams[$attributeCode])) {
            $requestParams[$attributeCode] = explode('-', $requestParams[$attributeCode]);
        }

        $requestParams[$attributeCode][] = $label;
        $values = array_unique(array_filter($requestParams[$attributeCode]));
        $values = array_filter($values, function ($value) use ($label) {
            return $value != $label;
        });
        $requestParams[$attributeCode] = implode('-', $values);
        $params = [];
        foreach ($requestParams as $attribute => $param) {
            if ($attribute != "q" && $param != "") {
                $params[] = str_replace('_ids', '', $attribute) . "/" . $param;
            }
        }
        $params = implode("/", $params);
        if (isset($requestParams['q'])) {
            $params = "catalogsearch/result/" . $requestParams['q'] . "/" . $params;
        }
        if (isset($requestParams['q']) && $params != "") {
            return "/" . strtolower($params);
        } else {
            return str_replace($this->seoCategoryUrlSuffix, '', $this->categoryHelper->getCurrentCategoryUrl()) . '/' . strtolower($params) . $this->seoCategoryUrlSuffix;
        }
    }

    public function getBaseMediaUrl() {
        return $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . \Magento\Swatches\Helper\Media::SWATCH_MEDIA_PATH;
    }

}