<?php

namespace Lc\ShopBundle\Services\Price;

use Lc\ShopBundle\Context\OrderReductionCreditInterface;
use Lc\ShopBundle\Context\OrderShopInterface;
use Lc\ShopBundle\Context\OrderShopPriceUtilsInterface;
use Lc\ShopBundle\Model\ReductionCart;

class OrderShopPriceUtils implements OrderShopPriceUtilsInterface
{
        use PriceUtilsTrait;

        protected $orderProductPriceUtils;

        public function __construct(OrderProductPriceUtils $orderProductPriceUtils)
        {
                $this->orderProductPriceUtils = $orderProductPriceUtils;
        }

        //Inclus les ReductionCatalog des OrderProducts
        public function getTotalOrderProducts(OrderShopInterface $orderShop): float
        {
                // A tester calculer ce montant en faisant TotalOrderWithTax - TotalOrderTaxes

                $total = 0;
                foreach ($orderShop->getOrderProducts() as $orderProduct) {
                        $total += $this->orderProductPriceUtils->getTotalWithReduction($orderProduct);
                }
                return $total;
        }


        //Inclus les ReductionCatalog des OrderProducts
        public function getMarginOrderProducts(OrderShopInterface $orderShop): float
        {
                $total = 0;
                foreach ($orderShop->getOrderProducts() as $orderProduct) {
                        $total += $this->orderProductPriceUtils->getTotalMargin($orderProduct);
                }
                return $total;
        }

        public function getMarginOrderProductsPercent(OrderShopInterface $orderShop): float
        {
                if ($this->getTotalOrderProducts($orderShop)) {
                        return $this->round($this->getMarginOrderProducts($orderShop) / $this->getTotalOrderProducts($orderShop) * 100);
                } else {
                        return 0;
                }

        }


        public function getTotalOrderProductsWithTax(OrderShopInterface $orderShop): float
        {
                return $this->getTotalOrderProductsWithTaxByOrderProducts($orderShop->getOrderProducts());
        }

        public function getTotalBuyingPriceOrderProductsWithTax($orderProducts): float
        {
                $total = 0;

                foreach ($orderProducts as $orderProduct) {
                        $total += $this->orderProductPriceUtils->getTotalBuyingPriceWithTax($orderProduct);
                }

                return $total;
        }

        public function getTotalOrderProductsWithTaxByOrderProducts($orderProducts): float
        {
                $total = 0;
                foreach ($orderProducts as $orderProduct) {
                        $total += $this->orderProductPriceUtils->getTotalWithTaxAndReduction($orderProduct);
                }

                return $total;
        }

        public function getTotalOrderProductsTaxes(OrderShopInterface $orderShop): float
        {
                $total = 0;

                foreach ($orderShop->getOrderProducts() as $orderProduct) {
                        $total += $this->orderProductPriceUtils->getTotalTaxes($orderProduct) / $this->getReductionsCoef($orderShop);
                }

                return $total;
        }

        public function getOrderProductsTaxesAsArray(OrderShopInterface $orderShop): array
        {
                $orderProductsTaxes = [];
                foreach ($orderShop->getOrderProducts() as $orderProduct) {

                        $idTaxRate = $orderProduct->getTaxRate()->getId();

                        if (!isset($orderProductsTaxes[$idTaxRate])) {
                                $orderProductsTaxes[$idTaxRate] = [
                                        'label' => $orderProduct->getTaxRate()->getValue() . '%',
                                        'totalOrderProducts' => 0,
                                        'totalTaxes' => 0,
                                ];
                        }

                        $orderProductsTaxes[$idTaxRate]['totalOrderProducts'] += $this->orderProductPriceUtils->getTotalWithReduction($orderProduct) / $this->getReductionsCoef($orderShop);
                        $orderProductsTaxes[$idTaxRate]['totalTaxes'] += $this->orderProductPriceUtils->getTotalTaxes($orderProduct) / $this->getReductionsCoef($orderShop);
                }

                return $orderProductsTaxes;
        }

        private function getReductionsCoef(OrderShopInterface $orderShop): float
        {
                return $this->getTotalOrderProducts($orderShop) / $this->getTotalOrderProductsWithReductions($orderShop);
        }

        private function getTaxRateAverage(OrderShopInterface $orderShop): float
        {
                return $this->getTotalOrderProductsWithTax($orderShop) / $this->getTotalOrderProducts($orderShop);
        }

        public function getTotalOrderProductsWithReductions(OrderShopInterface $orderShop)
        {
                $total = $this->getTotalOrderProducts($orderShop);
                $total -= $this->getTotalReductionCartsAmount($orderShop);
                $total -= $this->getTotalReductionCreditsAmount($orderShop);
                return $total;
        }

        public function getTotalOrderProductsWithReductionCarts(OrderShopInterface $orderShop)
        {
                $total = $this->getTotalOrderProducts($orderShop);
                $total -= $this->getTotalReductionCartsAmount($orderShop);
                return $total;
        }

        public function getTotalReductionCartsAmount(OrderShopInterface $orderShop)
        {
                $totalReductionAmount = 0;
                foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
                        $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax($orderShop, $orderReductionCart);
                }
                return $totalReductionAmount;
        }

        public function getTotalReductionCreditsAmount(OrderShopInterface $orderShop)
        {
                $totalReductionAmount = 0;
                foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
                        $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax($orderShop, $orderReductionCredit);
                }
                return $totalReductionAmount;
        }

        public function getTotalOrderProductsWithTaxAndReductions(OrderShopInterface $orderShop)
        {
                $total = $this->getTotalOrderProductsWithTax($orderShop);
                $total -= $this->getTotalReductionCartsAmountWithTax($orderShop);
                $total -= $this->getTotalReductionCreditsAmountWithTax($orderShop);
                return $total;
        }


        public function getMarginOrderProductsWithReductions(OrderShopInterface $orderShop): float
        {
                $total = $this->getMarginOrderProducts($orderShop);

                $totalReductionAmount = 0;
                foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
                        $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithoutTax($orderShop, $orderReductionCart);
                }

                foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
                        $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithoutTax($orderShop, $orderReductionCredit);
                }

                $total -= $totalReductionAmount;

                return $total;
        }


        public function getTotalOrderProductsWithTaxAndReductionCarts(OrderShopInterface $orderShop)
        {
                $total = $this->getTotalOrderProductsWithTax($orderShop);
                $total -= $this->getTotalReductionCartsAmountWithTax($orderShop);
                return $total;
        }

        public function getTotalReductionCartsAmountWithTax(OrderShopInterface $orderShop)
        {
                $totalReductionAmount = 0;
                foreach ($orderShop->getOrderReductionCarts() as $orderReductionCart) {
                        $totalReductionAmount += $this->getOrderProductsReductionCartAmountWithTax($orderShop, $orderReductionCart);
                }
                return $totalReductionAmount;
        }

        public function getTotalReductionCreditsAmountWithTax(OrderShopInterface $orderShop)
        {
                $totalReductionAmount = 0;
                foreach ($orderShop->getOrderReductionCredits() as $orderReductionCredit) {
                        $totalReductionAmount += $this->getOrderProductsReductionCreditAmountWithTax($orderShop, $orderReductionCredit);
                }
                return $totalReductionAmount;
        }

        public function getOrderProductsReductionCartAmountWithoutTax(OrderShopInterface $order, $orderReductionCart)
        {
                $amount = 0;
                if ($orderReductionCart->getAppliedTo() === ReductionCart::APPLIED_TO_ORDER_PRODUCTS) {

                        if ($orderReductionCart->getUnit() == 'percent') {
                                $amount = $this->amountReductionByPercentValue(
                                        $this->getTotalOrderProducts($order),
                                        $orderReductionCart->getValue()
                                );
                        } else if ($orderReductionCart->getUnit() == 'amount') {
                                if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') {
                                        $amount = $orderReductionCart->getValue();
                                } else if ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') {
                                        $amount = $this->round($orderReductionCart->getValue() / $this->getTaxRateAverage($order));
                                }

                        }
                }
                return $amount;

        }

        public function getOrderProductsReductionCartAmountWithTax(OrderShopInterface $order, $orderReductionCart)
        {
                $amount = 0;

                if ($orderReductionCart->getAppliedTo() === ReductionCart::APPLIED_TO_ORDER_PRODUCTS) {
                        if ($orderReductionCart->getUnit() == 'percent') {
                                $amount = $this->amountReductionByPercentValue(
                                        $this->getTotalOrderProductsWithTax($order),
                                        $orderReductionCart->getValue()
                                );
                        } elseif ($orderReductionCart->getUnit() == 'amount') {
                                if ($orderReductionCart->getBehaviorTaxRate() == 'tax-excluded') {
                                        $amount = $this->round($orderReductionCart->getValue() * $this->getTaxRateAverage($order));
                                } elseif ($orderReductionCart->getBehaviorTaxRate() == 'tax-included') {
                                        $amount = $orderReductionCart->getValue();
                                }

                        }
                }

                return $amount;
        }

        public function getOrderProductsReductionCreditAmountWithoutTax(OrderShopInterface $order, OrderReductionCreditInterface $orderReductionCredit)
        {
                $amount = 0;
                if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') {
                        $amount = $orderReductionCredit->getValue();
                } else if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') {
                        $amount = $this->round($orderReductionCredit->getValue() / $this->getTaxRateAverage($order));
                }

                return $amount;
        }

        public function getOrderProductsReductionCreditAmountWithTax(OrderShopInterface $order, OrderReductionCreditInterface $orderReductionCredit)
        {
                $amountWithTax = 0;
                if ($orderReductionCredit->getBehaviorTaxRate() == 'tax-excluded') {
                        $amountWithTax = $this->round($orderReductionCredit->getValue() * $this->getTaxRateAverage($order));
                } elseif ($orderReductionCredit->getBehaviorTaxRate() == 'tax-included') {
                        $amountWithTax = $orderReductionCredit->getValue();
                }

                return $amountWithTax;
        }
}