<?php

namespace FiloBlu\Rma\Plugin;

use Exception;
use FiloBlu\Rma\Helper\RmaPoliciesHelper;
use FiloBlu\Rma\Model\OrderLocator;
use function in_array;
use Magento\Framework\App\RequestInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Psr\Log\LoggerInterface;

use RuntimeException;

/**
 *
 */
class EasyReturnHelperPlugin
{
    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @var RmaPoliciesHelper
     */
    protected $rmaPoliciesHelper;

    /**
     * @var OrderRepositoryInterface
     */
    protected $orderRepository;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    private $logger;
    /**
     * @var \FiloBlu\Rma\Model\OrderLocator
     */
    private $orderLocator;

    /**
     * @param RequestInterface $request
     * @param RmaPoliciesHelper $rmaPoliciesHelper
     * @param OrderRepositoryInterface $orderRepository
     * @param \FiloBlu\Rma\Model\OrderLocator $orderLocator
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        RequestInterface $request,
        RmaPoliciesHelper $rmaPoliciesHelper,
        OrderRepositoryInterface $orderRepository,
        OrderLocator $orderLocator,
        LoggerInterface $logger
    ) {
        $this->request = $request;
        $this->rmaPoliciesHelper = $rmaPoliciesHelper;
        $this->orderRepository = $orderRepository;
        $this->logger = $logger;
        $this->orderLocator = $orderLocator;
    }

    /**
     * @param $subject
     * @param $result
     * @return float|mixed
     */
    public function afterSimulateEasyReturnShippingCost(
        $subject,
        $result
    ) {
        try {

            if (!$this->rmaPoliciesHelper->isPolicesCheckActive()) {
                return $result;
            }

            if (!$this->orderLocator->hasOrder()) {
                $this->orderLocator->load();
            }

            $order  = $this->orderLocator->getCurrentOrder();

            $isFirstReturn = $this->rmaPoliciesHelper->isFirstReturn($order);

            //controllo se ci sono resi eistenti
            if ($isFirstReturn) {
                //se è il primo prendo la config da be e applico le condizioni e l'azione
                $firstReturnPolicies = $this->rmaPoliciesHelper->getFirstRmaPolicies();
                return $this->checkPolicies($firstReturnPolicies, $order, $result);
            }

            //se ci sono resi applico le condizioni e l'azione per il secondo reso e successivi
            $secondaryReturnPolicies = $this->rmaPoliciesHelper->getSecondaryRmaPolicies();
            return $this->checkPolicies($secondaryReturnPolicies, $order, $result);
        } catch (Exception $exception) {
            $this->logger->error($exception, ['exception' => $exception]);
            return $result;
        }
    }

    /**
     * @return \Magento\Sales\Api\Data\OrderInterface|null
     * @throws \Magento\Framework\Exception\InputException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getOrder()
    {
        $orderId = $this->request->getParam('order_id');

        if ($orderId && (int)$orderId > 0) {
            return $this->rmaPoliciesHelper->getOrderById($orderId);
        }

        $orderItemId = $this->request->getParam('order_item_id');

        if ($orderItemId && (int)$orderItemId > 0) {
            $this->rmaPoliciesHelper->getOrderByItemId($orderItemId);
        }

        throw new RuntimeException('Could not find order by order_id or order_item_id');
    }

    /**
     * @param $policies
     * @param $order
     * @param $easyReturnOriginalCost
     * @return float|mixed
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function checkPolicies($policies, $order, $easyReturnOriginalCost)
    {
        /**
         * TODO: Rivedere questa logica e pensare ad eventuali
         * scenari dove potrebbe fallire
         */
        if (!$this->rmaPoliciesHelper->isOrderInEU($order)) {
            return $easyReturnOriginalCost;
        }

        if (empty($policies)) {
            return $easyReturnOriginalCost;
        }

        $customer = $this->rmaPoliciesHelper->getOrderCustomer($order);

        $customerGroup = 0;
        if ($customer) {
            $customerGroup = $customer->getGroupId();
        }

        foreach ($policies as $policy) {
            if (!in_array($customerGroup, $policy['customer_group'] ?? [])) {
                continue;
            }

            if (!$policy['return_cost']) {
                return 0.00;
            }
        }

        return $easyReturnOriginalCost;
    }
}
