<?php

/**
 * Created by PhpStorm.
 * User: jderosa
 * Date: 20/04/20
 * Time: 11.57
 */

namespace FiloBlu\Rma\Block\Returns;

use Exception;
use FiloBlu\Rma\Handlers\RmaItemStatusUpdateHandler;
use FiloBlu\Rma\Helper\ChangeSizeAttributeHelper;
use FiloBlu\Rma\Helper\EasyReturnHelper;
use Magento\Eav\Model\Config;
use Magento\Eav\Model\Form\Factory;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\Data\Collection\ModelFactory;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Registry;
use Magento\Framework\View\Element\Template\Context;
use Magento\Rma\Helper\Data;
use Magento\Rma\Model\Item\FormFactory;
use Magento\Rma\Model\ItemFactory;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Store\Model\ScopeInterface;
use Throwable;

use function in_array;

/**
 *
 */
class Create extends \Magento\Rma\Block\Returns\Create
{
    const CREATE_TEMPLATE_MAGENTO_V2_3_X = 'FiloBlu_Rma::return/createv23x.phtml';
    const CREATE_TEMPLATE_MAGENTO_V2_2_X = 'FiloBlu_Rma::return/create.phtml';
    const CREATE_TEMPATE_MAGENTO_ORIGINAL = 'Magento_Rma::return/create.phtml';
    const SHIPPING_ADDRESS_TEMPLATE = 'FiloBlu_Rma::return/create/form.phtml';

    /**
     * @var ProductMetadataInterface
     */
    private $productMetadata;

    /**
     * @var EasyReturnHelper
     */
    private $easyReturnHelper;

    /**
     * @var Context
     */
    private $context;

    /**
     * Create constructor.
     * @param Context $context
     * @param ModelFactory $modelFactory
     * @param Factory $formFactory
     * @param Config $eavConfig
     * @param ItemFactory $itemFactory
     * @param FormFactory $itemFormFactory
     * @param Data $rmaData
     * @param Registry $registry
     * @param Renderer $addressRenderer
     * @param ProductMetadataInterface $productMetadata
     * @param EasyReturnHelper $easyReturnHelper
     * @param array $data
     */
    public function __construct(
        Context $context,
        ModelFactory $modelFactory,
        Factory $formFactory,
        Config $eavConfig,
        ItemFactory $itemFactory,
        FormFactory $itemFormFactory,
        Data $rmaData,
        Registry $registry,
        Renderer $addressRenderer,
        ProductMetadataInterface $productMetadata,
        EasyReturnHelper $easyReturnHelper,
        array $data = []
    ) {
        parent::__construct(
            $context,
            $modelFactory,
            $formFactory,
            $eavConfig,
            $itemFactory,
            $itemFormFactory,
            $rmaData,
            $registry,
            $addressRenderer,
            $data
        );
        $this->productMetadata = $productMetadata;
        $this->easyReturnHelper = $easyReturnHelper;
        $this->context = $context;
    }

    /**
     * @param string $template
     * @return \Magento\Rma\Block\Returns\Create
     */
    public function setTemplate($template)
    {
        if (!preg_match('/return\/create/', $template)) {
            return parent::setTemplate($template);
        }

        try {
            if (!$this->easyReturnHelper->isEasyReturnEnabled($this->context->getStoreManager()->getStore()->getId())) {
                return parent::setTemplate(self::CREATE_TEMPATE_MAGENTO_ORIGINAL);
            }

            $magentoVersion = $this->productMetadata->getVersion();

            if (version_compare($magentoVersion, '2.3.0') != -1) {
                $template = self::CREATE_TEMPLATE_MAGENTO_V2_3_X;
            } else {
                $template = self::CREATE_TEMPLATE_MAGENTO_V2_2_X;
            }

            return parent::setTemplate($template);
        } catch (Exception $exception) {
            $this->_logger->critical($exception->getMessage(), ['exception' => $exception]);
            return parent::setTemplate(self::CREATE_TEMPATE_MAGENTO_ORIGINAL);
        } catch (Throwable $throwable) {
            $this->_logger->critical($throwable->getMessage(), ['exception' => $throwable]);
            return parent::setTemplate(self::CREATE_TEMPATE_MAGENTO_ORIGINAL);
        }
    }

    /**
     * @param OrderInterface $order
     * @return bool
     * @throws NoSuchEntityException
     */
    public function isRegionRequired(OrderInterface $order)
    {
        $storeId = $this->context->getStoreManager()->getStore()->getId();
        $country = $this->_scopeConfig->getValue('general/region/state_required', ScopeInterface::SCOPE_STORE, $storeId) ?? '';
        $myCountry = $order->getShippingAddress()->getCountryId();

        return ($country != '') && in_array($myCountry, explode(',', $country));
    }


    /**
     * @return mixed
     */
    public function getItems()
    {
        // Temporary workaround PEUT-1618
        $items = $this->getData('items');
        $returnableItems = [];
        foreach ($items as $item) {
            if ($item->getPrice() > 0) {
                $returnableItems [] = $item;
            }
        }

        return $returnableItems;
    }

    public function getReasons()
    {
        $changeSizeReasons = $this->getWrongSizeReasons();
        $options =  array_map(static function ($i) {
            return $i->getData();
        }, $this->getAttributes()['reason']->getOptions());

        return json_encode([
            'change_size' => array_filter($options, function ($i) use ($changeSizeReasons) {
                return in_array($i['value'], $changeSizeReasons['change_size']);
            }),
            'default' => array_filter($options, function ($i) use ($changeSizeReasons) {
                return in_array($i['value'], $changeSizeReasons['visible']);
            })
        ]);
    }

    /**
     * @return int|mixed
     */
    public function getChangeSizeOptionId()
    {
        return $this->_scopeConfig->getValue(ChangeSizeAttributeHelper::RMA_CHANGE_SIZE_OPTION_MAPPING) ?? 0;
    }

    /**
     * @return array|array[]
     */
    public function getWrongSizeReasons()
    {
        $mapping = $this->_scopeConfig->getValue(RmaItemStatusUpdateHandler::XML_PATH_RMA_REASON_MAPPING);

        $reasons = ['change_size' => [], 'visible' => []];

        foreach (json_decode($mapping, true) as $reason) {
            if (!(bool)$reason['is_visible']) {
                continue;
            }

            if ($reason['standard_reason'] === 'wrong_size') {
                $reasons['change_size'][] = $reason['brand_reason'];
            }

            $reasons['visible'][] = $reason['brand_reason'];
        }

        return $reasons;
    }
}
