<?php

namespace FiloBlu\Rma\Model;

use Exception;
use FiloBlu\Esb\Model\Loader\OrderLoader;
use FiloBlu\Rma\Api\RmaManagementInterface;
use FiloBlu\Rma\Handlers\CanCreateRmaHandler;
use FiloBlu\Rma\Helper\ChangeSizeAttributeHelper;
use FiloBlu\Rma\Helper\EasyReturnHelper;
use FiloBlu\Rma\Helper\RmaHelper;
use FiloBlu\Rma\Logger\Logger;
use Magento\Framework\DataObject;
use Magento\Rma\Api\Data\RmaInterface;
use Magento\Rma\Helper\Data;
use Magento\Rma\Model\ResourceModel\Item;
use Magento\Rma\Model\ResourceModel\Order\Item\Collection;
use Magento\Sales\Api\OrderItemRepositoryInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;
use Throwable;
use FiloBlu\Rma\Helper\ChangeSizeOrder;

/**
 *
 */
class RmaManagement implements RmaManagementInterface
{
    /**
     * @var RmaHelper
     */
    protected $rmaHelper;
    /**
     * @var OrderItemREPositoryInterface
     */
    protected $orderItemRepository;
    /**
     * @var OrderLocator
     */
    protected $orderLocator;
    /**
     * @var Item
     */
    private $item;

    /**
     * @var DataObject
     */
    private $dataObject;
    /**
     * @var CanCreateRmaHandler
     */
    private $canCreateRmaHandler;
    /**
     * @var OrderRepositoryInterface
     */
    private $orderRepository;
    /**
     * @var Logger
     */
    private $logger;
    /**
     * @var EasyReturnHelper
     */
    private $easyReturnHelper;
    /**
     * @var ChangeSizeAttributeHelper
     */
    private $changeSizeAttributeHelper;
    /**
     * @var Data
     */
    private $data;
    /**
     * @var ChangeSizeOrder
     */
    private $changeSizeOrderHelper;


    /**
     * @param Item $item
     * @param DataObject $dataObject
     * @param CanCreateRmaHandler $canCreateRmaHandler
     * @param OrderRepositoryInterface $orderRepository
     * @param Logger $logger
     * @param EasyReturnHelper $easyReturnHelper
     * @param ChangeSizeAttributeHelper $changeSizeAttributeHelper
     * @param Data $data
     * @param RmaHelper $rmaHelper
     * @param OrderItemRepositoryInterface $orderItemRepository
     * @param OrderLocator $orderLocator
     * @param ChangeSizeOrder $changeSizeOrderHelper
     */
    public function __construct(
        Item                      $item,
        DataObject                $dataObject,
        CanCreateRmaHandler       $canCreateRmaHandler,
        OrderRepositoryInterface  $orderRepository,
        Logger                    $logger,
        EasyReturnHelper          $easyReturnHelper,
        ChangeSizeAttributeHelper $changeSizeAttributeHelper,
        Data                      $data,
        RmaHelper                 $rmaHelper,
        OrderItemREPositoryInterface $orderItemRepository,
        OrderLocator $orderLocator,
        ChangeSizeOrder $changeSizeOrderHelper
    )
    {
        $this->item = $item;
        $this->dataObject = $dataObject;
        $this->canCreateRmaHandler = $canCreateRmaHandler;
        $this->orderRepository = $orderRepository;
        $this->logger = $logger;
        $this->easyReturnHelper = $easyReturnHelper;
        $this->changeSizeAttributeHelper = $changeSizeAttributeHelper;
        $this->data = $data;
        $this->rmaHelper = $rmaHelper;
        $this->orderItemRepository = $orderItemRepository;
        $this->orderLocator = $orderLocator;
        $this->changeSizeOrderHelper = $changeSizeOrderHelper;
    }

    /**
     * @param int $orderId
     * @return array|DataObject|mixed|null
     */
    public function getReturnableItems(int $orderId)
    {
        if (!$this->isReturnable($orderId)) {
            return $this->dataObject->getData();
        }

        /** @var Collection $orderItems */
        $orderItems = $this->item->getOrderItemsCollection($orderId);
        $returnableItems = [];
        if ($orderItems->getTotalCount()) {
            foreach ($orderItems->getItems() as $orderItem) {
                /** @var \Magento\Sales\Model\Order\Item $orderItem */
                if ($this->data->canReturnProduct($orderItem->getProduct())) {

                    if (!$this->checkIfItemHasAllowedReturn($orderItem)) {
                        continue;
                    }

                    $returnableItems [] = $orderItem;
                }
            }
        }

        if (count($returnableItems) == 0) {
            return $this->dataObject->getData();
        }

        $items = $this->item->getReturnableItems($orderId) ?? [];
        foreach ($items as $k => $v) {
            if ($v > 0) {
                foreach ($returnableItems as $returnableItem) {
                    if ($returnableItem->getItemId() == $k) {
                        $this->dataObject->setData($k, ['item_id' => $k, 'returnable_qty' => $v]);
                    }
                }
            }
        }

        return $this->dataObject->getData();

    }

    /**
     * @param int $orderId
     * @return bool
     */
    protected function isReturnable(int $orderId)
    {
        try {
            $order = $this->orderRepository->get($orderId);
            return $this->canCreateRmaHandler->getCanOrderCreateRma($order);
        } catch (Exception $e) {
            $this->logger->critical('FiloBlu_Rma_RmaManagement:' . $e->getMessage(), ['exception' => $e]);
        } catch (Throwable $t) {
            $this->logger->critical('FiloBlu_Rma_RmaManagement:' . $t->getMessage(), ['exception' => $t]);
        }
        return false;
    }

    /**
     * @param RmaInterface $data
     * @return DataObject|mixed
     */
    public function getReturnTypes(RmaInterface $data)
    {
        /**
         * Blu Headless temporary workaround
         */
        if (!isset($data->getItems()[0]) || !$data->getItems()[0]->getOrderItemId()) {
            $response = $this->dataObject->setData('data', [
                'normal_return' => true,
                'easy_return' => (bool)$this->easyReturnHelper->isEasyReturnEnabled(),
                'iban_required_for_rma' => true
            ]);

            return $response->getData();
        }

        $orderItemId = $data->getItems()[0]->getOrderItemId();
        $orderItem = $this->orderItemRepository->get($orderItemId);

        $order = $this->orderRepository->get($orderItem->getOrderId());

        $ibanRequired = $this->getIbanRequiredForReturn($data, $order);

        $this->orderLocator->setCurrentOrder($order);

        $retunType = 'easy_return';
        $changeSizereturn = false;
        if($data->getItems()[0]->getResolution() == $this->changeSizeAttributeHelper->getChangeSizeAttributeOptionId()){
            $retunType = 'change_size';
            $changeSizereturn = true;
        }

        $easyReturnAmount = (int)$this->easyReturnHelper->simulateEasyReturnShippingCost(
            $order->getShippingAddress(),
            $order->getStore(),
            $order->getWeight(),
            $order->getGrandTotal(),
            0,
            'price',
            $retunType,
            $order->getId()
        );

        try {
            $normalReturn = true;
            $easyReturn = (bool)$this->easyReturnHelper->isEasyReturnEnabled();

            if (!$easyReturnAmount && $easyReturn) {
                $normalReturn = false;
                $easyReturn = true;
            }


            if ((int)$easyReturnAmount && $easyReturn) {
                $normalReturn = true;
            }

            if ($this->easyReturnHelper->isForceEasyReturnEnabled() && $this->changeSizeAttributeHelper->isChangeSizeEnabled()) {
                $changeSizeResolutionId = $this->changeSizeAttributeHelper->getChangeSizeAttributeOptionId();
                foreach ($data->getItems() as $item) {
                    if ($item->getResolution() == $changeSizeResolutionId) {
                        $normalReturn = false;
                    }
                }
            }

            if($changeSizereturn){
                $easyReturn = true;
            }

            $response = $this->dataObject->setData('data', [
                'normal_return' => $normalReturn,
                'easy_return' => $easyReturn,
                'iban_required_for_rma' => $ibanRequired
                //'change_size' => $changeSizereturn
            ]);



            return $response->getData();
        } catch (Exception $e) {
            $this->logger->critical('FiloBlu_Rma_RmaManagement:' . $e->getMessage(), ['exception' => $e]);
        } catch (Throwable $t) {
            $this->logger->critical('FiloBlu_Rma_RmaManagement:' . $t->getMessage(), ['exception' => $t]);
        }

        return null;
    }

    /**
     * @param $orderItem
     * @return bool
     */
    public function checkIfItemHasAllowedReturn($orderItem) {

        if(!$this->changeSizeOrderHelper->isAllowedReturnGiftWrap()) {
            $giftWrapSkus = $this->changeSizeOrderHelper->getGiftWrapProductsSkus();
            if(in_array($orderItem->getSku(), $giftWrapSkus)) {
                return false;
            }
        }

        if ($this->rmaHelper->isCustomizedProductRefundAllowed()) {
            return true;
        }

        $productOptions = $orderItem->getProductOptions();
        if (isset($productOptions['options'])) {
            return false;
        }

        return true;
    }

    public function getIbanRequiredForReturn($data, Order $order)
    {
        $changeSizeAttributeId = $this->changeSizeAttributeHelper->getChangeSizeAttributeOptionId();

        $ibanRequired = $order->getExtensionAttributes()->getIbanRequiredForReturn();

        $changeSizeRmaItems = 0;

        foreach ($data->getItems() as $rmaItem ){
            if ($rmaItem->getResolution() == $changeSizeAttributeId) {
                $changeSizeRmaItems++;
            }
        }

        return count($data->getItems()) == $changeSizeRmaItems ? false : $ibanRequired;
    }
}
