<?php
/**
 * Plumrocket Inc.
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the End-user License Agreement
 * that is available through the world-wide-web at this URL:
 * http://wiki.plumrocket.net/wiki/EULA
 * If you are unable to obtain it through the world-wide-web, please
 * send an email to support@plumrocket.com so we can send you a copy immediately.
 *
 * @package     Plumrocket Product Filter v3.x.x
 * @copyright   Copyright (c) 2019 Plumrocket Inc. (http://www.plumrocket.com)
 * @license     http://wiki.plumrocket.net/wiki/EULA  End-user License Agreement
 */

namespace Plumrocket\ProductFilter\Block\Swatches\LayeredNavigation;

use Magento\Eav\Model\Entity\Attribute;
use Magento\Catalog\Model\ResourceModel\Layer\Filter\AttributeFactory;
use Magento\Framework\View\Element\Template;
use Magento\Eav\Model\Entity\Attribute\Option;
use Magento\Catalog\Model\Layer\Filter\Item as FilterItem;

class RenderLayered extends \Magento\Swatches\Block\LayeredNavigation\RenderLayered
{
    /**
     * Data helper
     * @var Plumrocket\ProductFilter\Helper\Data
     */
    protected $_dataHelper;

    /**
     * Url helper
     * @var Plumrocket\ProductFilter\Helper\Url
     */
    protected $_urlHelper;

    protected $_currentOption;

    /**
     * @var array
     */
    protected $storedOptions = [];

    /**
     * @param Template\Context $context
     * @param Attribute $eavAttribute
     * @param AttributeFactory $layerAttribute
     * @param \Magento\Swatches\Helper\Data $swatchHelper
     * @param \Magento\Swatches\Helper\Media $mediaHelper
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        Attribute $eavAttribute,
        AttributeFactory $layerAttribute,
        \Magento\Swatches\Helper\Data $swatchHelper,
        \Magento\Swatches\Helper\Media $mediaHelper,
        \Plumrocket\ProductFilter\Helper\Data $dataHelper,
        \Plumrocket\ProductFilter\Helper\Url $urlHelper,
        array $data = []
    ) {

        $this->_dataHelper = $dataHelper;
        $this->_urlHelper = $urlHelper;

        parent::__construct(
            $context,
            $eavAttribute,
            $layerAttribute,
            $swatchHelper,
            $mediaHelper,
            $data
        );
    }

    /**
     * @return array
     */
    public function getSwatchData()
    {
        $data = parent::getSwatchData();

        $attributeOptions = $data['options'];
        $swatches = $data['swatches'];

        $newAttributeOptions = [];
        $newSwatches = [];

        foreach ($this->eavAttribute->getOptions() as $option) {
            if (isset($attributeOptions[$option->getValue()])) {
                $newAttributeOptions[$this->_dataHelper->getConvertedAttributeValue($option->getValue())]
                    = $attributeOptions[$option->getValue()];
            }
            if (isset($swatches[$option->getValue()])) {
                $newSwatches[$this->_dataHelper->getConvertedAttributeValue($option->getValue())]
                    = $swatches[$option->getValue()];
            }
        }

        $data['options'] = $newAttributeOptions;
        $data['swatches'] = $newSwatches;

        return $data;
    }

    /**
     * @param string $attributeCode
     * @param string $value
     * @return string
     */
    public function buildUrl($attributeCode, $value)
    {
        if ($this->_dataHelper->moduleEnabled()) {
            if ($this->_urlHelper->useSeoFriendlyUrl()) {
                if ($currentFilter = $this->_request->getParam($attributeCode)) {
                    $_currentFilterOptions = explode(',', $currentFilter);

                    if (in_array($this->_currentOption->getValue(), $_currentFilterOptions)) {
                        $value = $this->_dataHelper->getConvertedAttributeValue($value);
                        $value = $this->refactorValue($value);
                        return $this->_urlHelper->getResetUrl(
                            $attributeCode,
                            $value,
                            $this->_currentOption->getValue()
                        );
                    }
                }

                $value = $this->_dataHelper->getConvertedAttributeValue($value);
                $value = $this->refactorValue($value);

                $url = $this->_urlHelper->getUrlForItem(
                    $attributeCode,
                    $value
                );

                $url = $this->_urlHelper->checkUrl($url);
                return $url;
            }

            $value = $this->_dataHelper->getConvertedAttributeValue($value);
            $value = $this->refactorValue($value);
            $values = explode('-', $this->_urlHelper->getOriginParam($attributeCode));
            foreach ($values as $k => $v) {
                if (!$v) {
                    unset($values[$k]);
                }
            }

            $key = array_search($value, $values, true);

            if ($key === false) {
                $values[] = $value;
            } else {
                unset($values[$key]);
            }

            if (empty($values)) {
                $value = null;
            } else {
                sort($values);
                $value = implode('-', $values);
            }
        }

        if ($this->_request->getRouteName() == "catalogsearch") {
            $additionalParameters = [$attributeCode => $value];

            return $this->_urlHelper->catalogSearchUrlBuilder($additionalParameters);
        }
        
        return parent::buildUrl($attributeCode, $value);
    }

    /**
     * {@inheritdoc}
     */
    protected function getOptionViewData(FilterItem $filterItem, Option $swatchOption)
    {
        $this->_currentOption = $swatchOption;
        if ($this->_dataHelper->moduleEnabled()) {
            $style = '';

            $link = $this->buildUrl($this->eavAttribute->getAttributeCode(), $filterItem->getLabel());

            if ($this->isOptionDisabled($filterItem)) {
                $link = 'javascript:void();';
                $style = 'disabled';
            }

            return [
                'link' => $link,
                'custom_style' => $style,
                'label' => $swatchOption->getLabel()
            ];
        }

        return parent::getOptionViewData($filterItem, $swatchOption);
    }

    /**
     * @param $value
     * @return string
     */
    private function refactorValue($value)
    {
        if ($value && isset($this->storedOptions[$value])) {
            $value .= '_' . $this->_currentOption->getValue();
        }

        $this->storedOptions[$value] = true;

        return $value;
    }
}
