<?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
        {
                // A tester calculer ce montant en faisant TotalOrderWithTax - TotalOrderTaxes

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


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


        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;
        }
}