<?php

namespace FiloBlu\Refilo\Plugins\Api;

use FiloBlu\ExtCartRule\Model\SalesRuleRepository;
use Magento\Framework\App\ObjectManager;
use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Model\QuoteIdMask;

/**
 * Class ShipmentEstimationInterface
 * @package FiloBlu\Refilo\Plugins\Api
 */
class ShipmentEstimationInterface
{
    /**
     * @var \Magento\Quote\Api\CartRepositoryInterface
     */
    protected $repository;

    /**
     * @var \Magento\Quote\Model\QuoteIdMaskFactory
     */
    protected $maskFactory;

    /**
     * @var \Magento\Quote\Model\ShippingMethodManagement
     */
    protected $shippingMethodManagement;

    /**
     * @var \FiloBlu\Refilo\Helper\Data
     */
    protected $helper;

    /**
     * @var \Magento\Framework\Webapi\Rest\Request
     */
    protected $request;

    /**
     * ShipmentEstimationInterface constructor.
     * @param \Magento\Framework\Webapi\Rest\Request $request
     * @param \Magento\Quote\Api\CartRepositoryInterface $repository
     * @param \Magento\Quote\Model\QuoteIdMaskFactory $maskFactory
     * @param \Magento\Quote\Model\ShippingMethodManagement $shippingMethodManagement
     * @param \FiloBlu\Refilo\Helper\Data $helper
     */
    public function __construct(
        \Magento\Framework\Webapi\Rest\Request $request,
        \Magento\Quote\Api\CartRepositoryInterface $repository,
        \Magento\Quote\Model\QuoteIdMaskFactory $maskFactory,
        \Magento\Quote\Model\ShippingMethodManagement $shippingMethodManagement,
        \FiloBlu\Refilo\Helper\Data $helper
    )
    {
        $this->request = $request;
        $this->repository = $repository;
        $this->maskFactory = $maskFactory;
        $this->shippingMethodManagement = $shippingMethodManagement;
        $this->helper = $helper;
    }

    /**
     * @param \Magento\Quote\Api\ShipmentEstimationInterface $subject
     * @param callable $proceed
     * @param $cartId
     * @param AddressInterface $address
     * @return mixed
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     * @throws \Magento\Framework\Exception\StateException
     */
    public function aroundEstimateByExtendedAddress(\Magento\Quote\Api\ShipmentEstimationInterface $subject, callable $proceed, $cartId, AddressInterface $address)
    {
        $isEnabled = $this->helper->isCheapestCarrierConfigEnabled();

        $quote = null;

        if ($isEnabled) {
            $quote = $this->repository->getActive($this->getCarId());
            $shippingAddress = $quote->getShippingAddress();
            $shippingAddress->addData($address->getData());
            $shippingAddress->setCollectShippingRates(true);
            // Order is important! must be called before proceed
            $carriers = $this->shippingMethodManagement->getList($quote->getId()) ?? [];
        }

        $result = $proceed($cartId, $address);

        if (!$isEnabled || empty($result) || empty($carriers)) {
            return $result;
        }

        if (!$this->helper->hasFreeShipping($quote)) {
            return $result;
        }

        $allowedCarriersMethods = [];
        foreach ($result as $shippingMethod) {
            $allowedCarriersMethods[] = $shippingMethod->getMethodCode();
        }

        $carrier = $this->helper->getCarrier($carriers, $allowedCarriersMethods);

        if ($carrier === null) {
            return $result;
        }

        foreach ($result as $item) {
            if ($item->getMethodCode() === $carrier->getMethodCode()) {
                return [$item];
            }
        }

        return $result;
    }

    /**
     * @return mixed
     */
    public function getCarId()
    {
        $cartId = $this->request->getParam('cartId');

        /** @var \Magento\Quote\Model\QuoteIdMask $idMask */
        $idMask = $this->maskFactory->create();
        $idMask->load($cartId, 'masked_id');

        if ($idMask->getId()) {
            $cartId = $idMask->getQuoteId();
        }

        return $cartId;
    }
}
