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

namespace Wyomind\ElasticsearchCore\Helper;

use Magento\Config\Model\ResourceModel\Config;
use Magento\Eav\Model\AttributeRepository;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Swatches\Helper\Data;
use Wyomind\Core\Helper\Data as CoreHelperData;
use Wyomind\ElasticsearchCore\Model\Index\MappingBuilder;

class JsonConfig extends \Magento\Framework\App\Helper\AbstractHelper
{
    const XML_PATH_WYOMIND_CONFIG = 'wyomind_elasticsearchcore/configuration';

    /**
     * @var Config|null
     */
    protected $_config = null;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_scopeConfig = null;

    /**
     * @var MappingBuilder|null
     */
    protected $_mappingBuilder = null;

    /**
     * @var AttributeRepository|null
     */
    protected $_attributeRepository = null;

    /**
     * @var SearchCriteriaInterface|null
     */
    protected $_searchCriteria = null;

    /**
     * @var Data|null
     */
    protected $_swatchesHelper = null;

    /**
     * @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory|null
     */
    protected $_categoryFactory = null;

    /**
     * @var IndexerFactory|null
     */
    protected $_indexerHelperFactory = null;

    protected $_storeManager = null;
    /**
     * @var CollectionFactory
     */
    protected $attrOptionCollectionFactory;
    /**
     * @var CoreHelperData
     */
    protected $coreHelper;

    /**
     * JsonConfig constructor.
     * @param \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryFactory
     * @param Config $config
     * @param AttributeRepository $attributeRepository
     * @param SearchCriteriaInterface $searchCriteria
     * @param Context $context
     * @param Data $swatchesHelper
     * @param IndexerFactory $indexerHelperFactory
     * @param MappingBuilder $mappingBuilder
     * @param StoreManagerInterface $storeManager
     * @param CollectionFactory $attrOptionCollectionFactory
     * @param CoreHelperData $coreHelper
     */
    public function __construct(
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryFactory,
        Config $config,
        AttributeRepository $attributeRepository,
        SearchCriteriaInterface $searchCriteria,
        Context $context,
        Data $swatchesHelper,
        IndexerFactory $indexerHelperFactory,
        MappingBuilder $mappingBuilder,
        StoreManagerInterface $storeManager,
        CollectionFactory $attrOptionCollectionFactory,
        CoreHelperData $coreHelper
    )
    {
        parent::__construct($context);
        $this->_config = $config;
        $this->_scopeConfig = $context->getScopeConfig();
        $this->_mappingBuilder = $mappingBuilder;
        $this->_attributeRepository = $attributeRepository;
        $this->_searchCriteria = $searchCriteria;
        $this->_swatchesHelper = $swatchesHelper;
        $this->_categoryFactory = $categoryFactory;
        $this->_indexerHelperFactory = $indexerHelperFactory;
        $this->_storeManager = $storeManager;
        $this->attrOptionCollectionFactory = $attrOptionCollectionFactory;
        $this->coreHelper = $coreHelper;
    }

    /**
     * @param string $storeCode
     * @param array $parameters
     * @throws \Magento\Framework\Exception\InputException
     */
    public function saveConfig($storeCode, $parameters = [])
    {
        $config = $this->getConfig($storeCode, $parameters);
        (new Autocomplete\Config($storeCode))->setData($config);
    }

    /**
     * @param string $storeId
     * @param array $parameters
     * @return array
     * @throws \Magento\Framework\Exception\InputException
     */
    public function getConfig($storeId, $parameters = [])
    {
        $config = $this->getClientConfig($storeId);


        $config['display_outofstock_products'] = $this->getValue("cataloginventory/options/show_out_of_stock",$storeId);

        if ($config === null) {
            $storeId = 0;
            $config = $this->getClientConfig($storeId);
        }

        $stores = $this->_storeManager->getStores(true, false);
        foreach ($stores as $store) {
            if ($store->getCode() === $storeId) {
                $storeId = $store->getId();
                break;
            }
        }

        foreach ($parameters as $name => $value) {
            if (array_key_exists($name, $config)) {
                $config[$name] = $value;
            }
        }
        $config['types'] = [];

        $types = &$config['types'];
        $indexers = $this->_indexerHelperFactory->create()->getAllIndexers();
        foreach ($indexers as $code => $type) {
            $types[$code] = $this->getValue('wyomind_elasticsearchcore/types/' . $code, $storeId);
            $types[$code]['index_properties'] = $type->getProperties($storeId, true);
            $types[$code]['search_fields'] = $type->getSearchFields($storeId, true, $config['compatibility']);
        }

        // categories tree
        $collection = $this->_categoryFactory->create();
        $collection->addNameToResult()
            ->addIsActiveFilter()
            ->setLoadProductCount(false)
            ->addOrderField('level')
            ->setStore($storeId);
        $tree = [];
        foreach ($collection as $cat) {
            if ($cat->getId() > 2) {
                if ($cat->getParentId() != $store->getRootCategoryId() && isset($tree[$cat->getParentId()])) {
                    $tree[$cat->getId()] = ['label' => $cat->getName(), 'level' => $cat->getLevel(), 'path' => $cat->getPath() . '/', 'position' => $cat->getPosition()];
                    $tree[$cat->getId()]['parent'] = $cat->getParentId();
                } elseif ($cat->getParentId() == $store->getRootCategoryId()) {
                    $tree[$cat->getId()] = ['label' => $cat->getName(), 'level' => $cat->getLevel(), 'path' => $cat->getPath() . '/', 'position' => $cat->getPosition()];
                }
            }
        }
        $config['categories'] = $tree;

        // filterable attributes information
        $attributes = $this->_attributeRepository->getList(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE, $this->_searchCriteria);

        $optionData = [];
        $ignoreBackendModel = ["MageWorx\ShippingRules\Model\Attribute\Backend\AvailableShippingMethods"];
        $ignoreAttributes = ['merchant_center_category'];
        foreach ($attributes->getItems() as $attribute) {
            if (in_array($attribute->getBackendModel(), $ignoreBackendModel) || in_array($attribute->getAttributeCode(), $ignoreAttributes)) {
                continue;
            }

            $attribute->setStoreId($storeId);
            //$options = $attribute->getSource()->getAllOptions();

            /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection $optionsCollection */
            $optionsCollection = $this->attrOptionCollectionFactory->create()
                ->setAttributeFilter($attribute->getAttributeId())
                ->setStoreFilter($attribute->getStoreId());

            if ($this->coreHelper->moduleIsEnabled('Wyomind_AttributeOptionPro')) {
                $table = $optionsCollection->getResource()->getTable("eav_attribute_option_image");
                $optionsCollection->getSelect()->joinLeft(
                    $table,
                    $table . ".option_id = main_table.option_id",
                    ["image"]
                );
            }

            $options = $optionsCollection->load();

            $label = "";
            $labels = $attribute->getFrontendLabels();
            if ($labels !== null) {
                foreach ($labels as $l) {
                    if (is_array($l)) {
                        foreach ($l as $ll) {
                            if ($ll->getStoreId() == $storeId) {
                                $label = $ll->getLabel();
                                break 2;
                            }    
                        }
                    } else {
                        if ($l->getStoreId() == $storeId) {
                            $label = $l->getLabel();
                            break;
                        }   
                    }
                }
            }
            if (empty($label)) {
                $label = $attribute->getFrontendLabel();
            }
            if (!empty($options) && $label !== null) {
                $optionData[$attribute->getAttributeCode()]['id'] = $attribute->getAttributeId();
                $optionData[$attribute->getAttributeCode()]['label'] = $label;
                $optionData[$attribute->getAttributeCode()]['visualSwatch'] = $this->_swatchesHelper->isVisualSwatch($attribute);
                $optionData[$attribute->getAttributeCode()]['textSwatch'] = $this->_swatchesHelper->isTextSwatch($attribute);
                if ($this->_swatchesHelper->isVisualSwatch($attribute) || $this->_swatchesHelper->isTextSwatch($attribute)) {
                    $valueIds = [];
                    foreach ($options as $option) {
                        if (!empty(trim($option->getOptionId()))) {
                            $valueIds[] = $option->getOptionId();
                            $optionData[$attribute->getAttributeCode()][$option->getOptionId()] = [
                                'label' => $option->getValue(),
                                'position' => $option->getSortOrder(),
                                'image' => ''
                            ];
                        }
                    }
                    $images = $this->_swatchesHelper->getSwatchesByOptionsId($valueIds);
                    foreach ($images as $image) {
                        $optionData[$attribute->getAttributeCode()][$image['option_id']]['options'] = [
                            'type' => $image['type'],
                            'swatch' => $image['value']
                        ];
                    }
                } else {
                    foreach ($options as $option) {
                        if (trim($option['value']) != '') {
                            $optionData[$attribute->getAttributeCode()][$option->getOptionId()] = [
                                'label' => $option->getValue(),
                                'position' => $option->getSortOrder(),
                                'image' => $option->getImage()
                            ];
                            $optionData[$attribute->getAttributeCode()][$option->getOptionId()]['options'] = ['type' => -1, 'swatch' => ''];
                        }
                    }
                }
            }
        }

        $config['swatches'] = $optionData;

        $config = array_merge($config, $this->getValue('wyomind_elasticsearchcore/debug'));

        return $config;
    }

    public function getClientConfig($store = null)
    {
        return $this->getValue(self::XML_PATH_WYOMIND_CONFIG, $store);
    }

    /**
     * @param string $path
     * @param null $store
     * @return mixed
     */
    public function getValue($path, $store = null)
    {
        return $this->_scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORES, $store);
    }
}