<?php

declare(strict_types=1);

namespace FiloBlu\Rma\View\Element\Block;

use FiloBlu\Rma\Handlers\RmaItemStatusUpdateHandler;
use FiloBlu\Rma\Helper\ChangeSizeAttributeHelper;
use function in_array;
use Magento\Eav\Api\AttributeRepositoryInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;


/**
 * TODO: da rivedere per i magento 2.1
 */
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\View\Element\Block\ArgumentInterface;
/**
 * END TODO
 */


use Magento\Rma\Model\Item;

use Magento\Store\Model\StoreManagerInterface;

/**
 *
 */
class RmaConfig implements ArgumentInterface
{

    /**
     * @var \Magento\Framework\Serialize\Serializer\Json
     */
    private $serializer;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var \Magento\Eav\Model\Config
     */
    private $eavConfig;
    /**
     * @var \Magento\Eav\Api\AttributeRepositoryInterface
     */
    private $eavAttributeRepositoryInterface;
    /**
     * @var \Magento\Eav\Api\Data\AttributeInterface
     */
    private $reasonAttribute;

    /**
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Eav\Api\AttributeRepositoryInterface $eavAttributeRepositoryInterface
     * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        ScopeConfigInterface $scopeConfig,
        AttributeRepositoryInterface $eavAttributeRepositoryInterface,
        Json $serializer = null
    ) {
        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class);
        $this->storeManager = $storeManager;
        $this->scopeConfig = $scopeConfig;
        $this->eavAttributeRepositoryInterface = $eavAttributeRepositoryInterface;
    }

    /**
     * @return bool|string
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getSerializedConfig()
    {
        return $this->serializer->serialize($this->getConfig());
    }

    /**
     * Returns rma config
     *
     * @return array
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getConfig()
    {
        return [
            'baseUrl'            => $this->storeManager->getStore()->getBaseUrl(),
            'websiteId'          => $this->storeManager->getStore()->getWebsiteId(),
            'storeId'            => $this->storeManager->getStore()->getId(),
            'storeGroupId'       => $this->storeManager->getStore()->getStoreGroupId(),
            'changeSizeOptionId' => $this->getChangeSizeOptionId(),
            'reasons'            => $this->getReasons()
        ];
    }

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

    /**
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getReasons()
    {
        $changeSizeReasons = $this->getWrongSizeReasons();
        $options = array_map(static function ($i) {
            return $i->getData();
        }, $this->getReasonAttribute()->getOptions());

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

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

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

        foreach ($this->serializer->unserialize($mapping) 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;
    }

    /**
     * @return \Magento\Eav\Api\Data\AttributeInterface
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getReasonAttribute()
    {
        if ($this->reasonAttribute) {
            return $this->reasonAttribute;
        }

        return $this->reasonAttribute = $this->eavAttributeRepositoryInterface->get(Item::ENTITY, 'reason');
    }
}
