<?php

namespace Leadlion\SalesOrder\Model\Order;

use Exception;
use Magento\Backend\Model\Session\Quote as QuoteSession;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product\Type;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\InventoryReservationsApi\Model\ReservationInterface;
use Magento\Quote\Api\Data\CartItemInterfaceFactory;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteFactory;
use Magento\Quote\Model\ResourceModel\Quote\Item as ResourceItem;
use Magento\Sales\Api\OrderManagementInterface as OrderManagement;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Creditmemo\ItemFactory as CreditmemoItemFactory;
use Magento\Sales\Model\Order\Invoice\ItemFactory as InvoiceItemFactory;
use Magento\Sales\Model\Order\Item;
use Magento\Sales\Model\Order\ItemFactory;
use Magento\Sales\Model\Order\Shipment\ItemFactory as ShipmentItemFactory;
use Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory as ItemCollectionFactory;
use Magento\Sales\Model\ResourceModel\Order\Tax\Item as TaxItem;
use Mageplaza\EditOrder\Helper\Data as HelperData;
use Mageplaza\EditOrder\Model\Quote\IsSalableWithReservationsCondition as EditOrderIsSalableWithReservationsCondition;
use Mageplaza\EditOrder\Model\Quote\QuoteManagement;
use Mageplaza\EditOrder\Model\ItemComparison;
use Mageplaza\EditOrder\Model\OrderManager;

class Total extends \Mageplaza\EditOrder\Model\Order\Total
{
    /**
     * Get total discount compensationamount all items
     *
     * @param Order $order
     *
     * @return float|null
     */
    public function getDiscTaxCompensation($order)
    {
        $discountCompensation = 0;

        /** @var Item $item */
        foreach ($order->getAllItems() as $item) {
            $discountCompensation += $item->getDiscountTaxCompensationAmount();
        }

        return $discountCompensation;
    }

    public function collectTotalsByItems($order, $itemsData, $orderDataUpdate)
    {
        $weight            = 0;
        $shipTax           = $order->getBaseShippingTaxAmount();
        $newTaxAmount      = $itemsData['tax_amount'] + $shipTax;
        $shipDiscount      = $order->getBaseShippingDiscountAmount();
        $newDiscountAmount = $itemsData['discount_amount'] + $shipDiscount;
        $shipAmount        = $order->getBaseShippingAmount();
        $removeItemQuote   = $orderDataUpdate[ItemComparison::REMOVE_ITEMS];

        //calculate weight
        foreach ($order->getItems() as $item) {
            $weight += $this->itemComparison->weightCalculate($item->getProductId(), $item->getQtyOrdered());
        }
        foreach ($removeItemQuote as $quote) {
            $weight -= $this->itemComparison->weightCalculate($quote['product_id'], $quote['qty']);
        }
        $order->setWeight($weight);
        $newSubtotal        = $this->itemComparison->getSubtotalByItems($order);
        $fixedProductTax    = $this->getTotalFPT($order); // not in Tax Amount of Item
        $discountTaxCompensation = $this->getDiscTaxCompensation($order);
        $newSubtotalInclTax = $itemsData['tax_amount'] + $newSubtotal + $fixedProductTax + $discountTaxCompensation;
        $newGrandTotal      = $newSubtotal + $shipAmount + $newTaxAmount + $fixedProductTax + $discountTaxCompensation - $newDiscountAmount;

        if ($this->_helperData->isIncludeFPTInSubtotal()) {
            $newSubtotal += $fixedProductTax;
        }
        return [
            'tax_amount'        => $newTaxAmount,
            'subtotal'          => $newSubtotal,
            'discount_amount'   => $newDiscountAmount,
            'grand_total'       => $newGrandTotal,
            'subtotal_incl_tax' => $newSubtotalInclTax
        ];
    }

    /**
     * @param Order $order
     * @param array $data
     * @param array $qty
     *
     * @return array
     * @throws Exception
     */
    public function saveOrder($order, $data)
    {
        $origItems = $oldShippedQty = [];
        foreach ($order->getItems() as $item) {
            if ($item->getParentItemId()) {
                continue;
            }
            $origItem = $this->orderItemFactory->create();
            $origItem->setData($item->getData());
            $origItems[]                    = $origItem;
            $oldShippedQty[$item->getSku()] = $item->getQtyShipped();
        }

        $total = $this->collectTotals($order, $data);

        $newOrderIds  = [];
        if (array_key_exists('orderData', $data)) {
            $orderData = $data['orderData'];
            foreach ($order->getAllItems() as $orderItem) {
                $newOrderIds[] = $orderItem->getProductId();
                if ((isset($orderData['invoiceData'][$orderItem->getProductId()])) &&
                    (float) $orderData['invoiceData'][$orderItem->getProductId()] > (float) $orderItem->getQtyOrdered()) {
                    $orderData['invoiceData'][$orderItem->getProductId()] = $orderItem->getQtyOrdered();
                }
            }
        }

        $this->itemComparison->changeSubTotalOrder($data, $order, $total);

        $discountTaxCompensation = $this->getDiscTaxCompensation($order);
            $order->setDiscountTaxCompensationAmount($discountTaxCompensation)
                ->setBaseDiscountTaxCompensationAmount($discountTaxCompensation);
                
        $order->setMpIsEditOrder('1');
        $order->save();

        return [
            'success' => true
        ];
    }

    
}
