<?php
/**
 * Mageplaza
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Mageplaza.com license that is
 * available through the world-wide-web at this URL:
 * https://www.mageplaza.com/LICENSE.txt
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade this extension to newer
 * version in the future.
 *
 * @category  Mageplaza
 * @package   Mageplaza_EditOrder
 * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)
 * @license   https://www.mageplaza.com/LICENSE.txt
 */

namespace Mageplaza\EditOrder\Plugin\Model\Quote\Item;

use Magento\Framework\App\RequestInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\Quote\Item\AbstractItem;
use Magento\SalesRule\Model\Validator;
use Mageplaza\EditOrder\Helper\Data as HelperData;

/**
 * Class CustomDiscount
 * @package Mageplaza\EditOrder\Plugin\Model
 */
class CustomDiscount
{
    /**
     * @var RequestInterface
     */
    protected $_request;

    /**
     * @var HelperData
     */
    protected $_helperData;

    /**
     * CustomDiscount constructor.
     *
     * @param RequestInterface $request
     * @param HelperData $helperData
     */
    public function __construct(
        RequestInterface $request,
        HelperData $helperData
    ) {
        $this->_request    = $request;
        $this->_helperData = $helperData;
    }

    /**
     * AfterSortItemsByPriority
     *
     * @param Validator $subject
     * @param array $result
     * @param Item[] $items
     *
     * @return array
     * @throws LocalizedException
     */
    public function afterSortItemsByPriority(Validator $subject, $result, $items)
    {
        if (!$this->_helperData->isMpEdit()) {
            return $result;
        }
        $request = $this->_request->getParams();
        if (!isset($request['item'])
            || !count($items)
            || !str_contains($this->_request->getFullActionName(), 'mpeditorder')
            || !$this->_helperData->isEnabled($items[0]->getStore()->getId())) {

            return $result;
        }

        foreach ($items as $item) {
            foreach ($request['item'] as $itemId => $data) {
                if ($itemId === (int) $item->getId()) {
                    if (isset($data['discount_type']) && $data['discount_type'] !== 'default') {
                        $type      = $data['discount_type'];
                        $value     = (is_numeric($data['discount_value']) && $data['discount_value'] > 0)
                            ? $data['discount_value'] : 0;
                        $itemPrice = $subject->getItemPrice($item);
                        if ($itemPrice < 0) {
                            return $result;
                        }

                        $this->calculateDiscount($type, $value, $item, $itemPrice);
                        $children = $item->getChildren();
                        if (!empty($children)) {
                            foreach ($children as $child) {
                                $this->calculateDiscount($type, $value, $child, $subject->getItemPrice($child));
                            }
                        }
                    } else {
                        $item->setMpCustomDiscountType(null);
                        $item->setMpCustomDiscountValue(null);
                    }
                }
            }
        }

        return $result;
    }

    /**
     * CalculateDiscount
     *
     * @param string $type
     * @param string $value
     * @param Item|AbstractItem $item
     * @param string $itemPrice
     *
     * @return void
     * @throws LocalizedException
     */
    public function calculateDiscount($type, $value, $item, $itemPrice)
    {
        if ($itemPrice <= 0 || $item->getProductType() === 'bundle') {
            $item->setMpCustomDiscountType($type);
            $item->setMpCustomDiscountValue($value);

            return;
        }
        $itemQty            = $this->_helperData->getQtyItem($item);
        $discountAmount     = $type === 'fixed'
            ? $value * $itemQty
            : ($itemPrice * $value * $itemQty) / 100;
        $discountAmount     = min($itemPrice * $itemQty, $discountAmount);
        $discountPercent    = $type === 'percent' ? $value : ($value * 100) / $itemPrice;
        $baseDiscountAmount = $discountAmount / $item->getStore()->getCurrentCurrencyRate();
        $item->setDiscountAmount($discountAmount);
        $item->setBaseDiscountAmount($baseDiscountAmount);
        $item->setDiscountPercent($discountPercent);
        $item->setMpCustomDiscountType($type);
        $item->setMpCustomDiscountValue($value);
    }
}
