<?php

namespace Lc\ShopBundle\Services;

use Doctrine\Common\Collections\Collection;
use Lc\ShopBundle\Context\OrderProductInterface;
use Lc\ShopBundle\Context\OrderShopInterface;
use Lc\ShopBundle\Context\ProductFamilyInterface;
use Lc\ShopBundle\Context\ProductInterface;
use Lc\ShopBundle\Context\ProductPropertyInterface;
use Lc\ShopBundle\Context\ReductionCatalogInterface;

class PriceUtilsOld
{

        public function getPrice($entity)
        {
                if ($entity instanceof ProductPropertyInterface) {
                        if ($entity->getBehaviorPriceInherited() == 'by-piece') {
                                return $entity->getPriceInherited();
                        } elseif ($entity->getBehaviorPriceInherited() == 'by-reference-unit') {
                                if ($entity->getQuantityInherited() > 0) {
                                        return $entity->getPriceByRefUnitInherited() * ($entity->getQuantityInherited() / $entity->getUnitInherited()->getCoefficient());
                                }
                        }
                }

                if ($entity instanceof OrderProductInterface) {
                        return $entity->getPrice();
                }

                return null;
        }

        public function getPriceWithTax($entity)
        {
                return $this->applyTax(
                        $this->getPrice($entity),
                        $entity->getTaxRateInherited()->getValue()
                );
        }

        public function getPriceWithTaxAndReduction($entity)
        {
                return $this->getPriceWithTaxAndReductionCatalog(
                        $entity,
                        $this->getPrice($entity),
                        $this->getPriceWithTax($entity)
                );
        }

        public function getPriceByRefUnit($entity)
        {
                if ($entity instanceof ProductPropertyInterface) {
                        if ($entity->getBehaviorPriceInherited() == 'by-piece') {
                                return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityInherited();
                        } elseif ($entity->getBehaviorPriceInherited() == 'by-reference-unit') {
                                return $entity->getPriceByRefUnitInherited();
                        }
                }

                if ($entity instanceof OrderProductInterface) {
                        return ($this->getPrice($entity) * $entity->getUnitInherited()->getCoefficient()) / $entity->getQuantityProduct();
                }

                return null;
        }

        public function getPriceByRefUnitWithTax($entity)
        {
                return $this->applyTax(
                        $this->getPriceByRefUnit($entity),
                        $entity->getTaxRateInherited()->getValue()
                );
        }

        public function getPriceByRefUnitWithTaxAndReduction($entity)
        {
                return $this->getPriceWithTaxAndReductionCatalog(
                        $entity,
                        $this->getPriceByRefUnit($entity),
                        $this->getPriceByRefUnitWithTax($entity)
                );
        }

        public function getTotal($entity)
        {
                if ($entity instanceof OrderProductInterface) {
                        return $entity->getQuantityOrder() * $this->getPrice($entity);
                }
                if ($entity instanceof OrderShopInterface) {
                        $total = 0;
                        foreach ($entity->getOrderProducts() as $orderProduct) {
                                $total += $this->getTotal($orderProduct);
                        }
                        return $total;
                }
                return null;
        }

        public function getTotalWithTax($entity)
        {
                if ($entity instanceof OrderProductInterface) {
                        return $this->applyTax(
                                $this->getTotal($entity),
                                $entity->getTaxRateInherited()->getValue()
                        );
                }
                if ($entity instanceof OrderShopInterface) {
                        $total = 0;
                        foreach ($entity->getOrderProducts() as $orderProduct) {
                                $total += $this->getTotalWithTax($orderProduct);
                        }
                        return $total;
                }

                //C'est bizzare ce truc là
                //if($entity instanceof OrderShopInterface) {
                //        return $this->getTotalOrderProducts($entity->getOrderProducts(), true) ;
                //}
                return null;
        }

        public function getTotalWithTaxAndReduction($entity)
        {
                if ($entity instanceof OrderProductInterface) {
                        return $this->getPriceWithTaxAndReductionCatalog(
                                $entity,
                                $this->getTotal($entity),
                                $this->getTotalWithTax($entity)
                        );
                }

                if ($entity instanceof OrderShopInterface) {
                        return $this->getTotalOrderProductsWithTaxAndReduction($entity->getOrderProducts(), true, true);
                }
        }

        public function getTotalWithReduction($entity)
        {
                if ($entity instanceof OrderProductInterface) {
                        return $this->getPriceWithReductionCatalog(
                                $entity,
                                $this->getTotal($entity),
                                $this->getTotalWithTax($entity)
                        );
                }

                if ($entity instanceof OrderShopInterface) {
                        return $this->getTotalOrderProductsWithReduction($entity->getOrderProducts(), true, true);
                }
        }

        public function getTotalOrderProductsWithReductionCart(OrderShopInterface $order)
        {
                $this->_getTotalOrderProductsWithReductionCartGeneric($order, false);
        }

        public function getTotalOrderProductsWithTaxAndReductionCart(OrderShopInterface $order)
        {
                $this->_getTotalOrderProductsWithReductionCartGeneric($order, true);
        }

        private function _getTotalOrderProductsWithReductionCartGeneric(OrderShopInterface $order, $withTax = true)
        {

                if ($withTax) {
                        $priceToReturn = $this->getTotalOrderProductsWithTaxAndReductionCatalog($order);
                }
                else {
                        $priceToReturn = $this->getTotalOrderProductsWithReductionCatalog($order);
                }
                foreach ($order->getOrderReductionCarts() as $orderReductionCart) {
                        if ($orderReductionCart->getUnit() == 'percent') {

                                $priceToReturn = $this->applyReductionPercent(
                                        $priceToReturn,
                                        $orderReductionCart->getValue
                                );
                        } else if ($orderReductionCart->getUnit() == 'amount') {
                                if ($orderReductionCart->getBehaviorTaxRate() == 'tax-inlcluded') {
                                        $priceToReturn =
                                                $this->applyReductionAmount(
                                                        $priceToReturn,
                                                        $orderReductionCart->getValue()
                                                );
                                }
                        }
                }
        }


        public function getTotalOrderProducts($entity)
        {
                return $this->getSumOrderProductsDispatch($entity);
        }

        public function getTotalOrderProductsWithTax($entity)
        {
                return $this->getSumOrderProductsDispatch($entity, true);
        }

        public function getTotalOrderProductsWithReduction($entity)
        {
                return $this->getTotalOrderProductsWithReductionCatalog($entity);
        }

        public function getTotalOrderProductsWithTaxAndReduction($entity)
        {
                return $this->getTotalOrderProductsWithTaxAndReductionCatalog($entity);
        }

        public function getTotalOrderProductsWithReductionCatalog($entity)
        {
                return $this->getSumOrderProductsDispatch($entity, false, true);
        }

        public function getTotalOrderProductsWithTaxAndReductionCatalog($entity)
        {
                return $this->getSumOrderProductsDispatch($entity, true, true);
        }

        public function getSumOrderProductsDispatch($entity, $withTax = false, $withReductionCatalog = false)
        {
                if ($entity instanceof OrderShopInterface) {
                        return $this->getSumOrderProducts($entity->getOrderProducts(), $withTax, $withReductionCatalog);
                }
                if ($entity instanceof Collection || is_array($entity)) {
                        return $this->getSumOrderProducts($entity, $withTax, $withReductionCatalog);
                }
        }

        public function getSumOrderProducts($orderProducts, $withTax = false, $withReductionCatalog = false)
        {
                $total = 0;
                foreach ($orderProducts as $orderProduct) {
                        if ($withTax && $withReductionCatalog) {
                                $total += $this->getTotalWithTaxAndReduction($orderProduct);
                        } elseif ($withTax) {
                                $total += $this->getTotalWithTax($orderProduct);
                        } elseif ($withReductionCatalog) {
                                $total += $this->getTotalWithReduction($orderProduct);
                        } else {
                                $total += $this->getTotal($orderProduct);
                        }
                }
                return $total;
        }

        public function getPriceWithTaxAndReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null)
        {
                return $this->getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog, true);
        }

        public function getPriceWithReductionCatalog($entity, $price, $priceWithTax, $reductionCatalog = null)
        {
                return $this->getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog, false);
        }

        public function getPriceWithReductionCatalogGeneric($entity, $price, $priceWithTax, $reductionCatalog = null, $withTax = true): ?float
        {
                if ($reductionCatalog) {
                        $reductionCatalogValue = $reductionCatalog->getValue();
                        $reductionCatalogUnit = $reductionCatalog->getUnit();
                        $reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate();
                } else {
                        if ($entity instanceof ProductPropertyInterface) {
                                $reductionCatalog = $entity->getReductionCatalogInherited();

                                if ($reductionCatalog) {
                                        $reductionCatalogValue = $reductionCatalog->getValue();
                                        $reductionCatalogUnit = $reductionCatalog->getUnit();
                                        $reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate();
                                }
                        }

                        if ($entity instanceof OrderProductInterface) {
                                $orderProductReductionCatalog = $entity->getOrderProductReductionCatalog();
                                if ($orderProductReductionCatalog) {
                                        $reductionCatalogValue = $orderProductReductionCatalog->getValue();
                                        $reductionCatalogUnit = $orderProductReductionCatalog->getUnit();
                                        $reductionCatalogBehaviorTaxRate = $orderProductReductionCatalog->getBehaviorTaxRate();
                                }
                        }
                }

                if (isset($reductionCatalogValue) && isset($reductionCatalogUnit) && isset($reductionCatalogBehaviorTaxRate)) {
                        if ($reductionCatalogUnit == 'percent') {
                                $priceWithTax = $this->applyReductionPercent(
                                        $priceWithTax,
                                        $reductionCatalogValue
                                );
                        } elseif ($reductionCatalogUnit == 'amount') {
                                if ($reductionCatalogBehaviorTaxRate == 'tax-excluded') {
                                        $priceWithTax = $this->applyTax(
                                                $this->applyReductionAmount(
                                                        $price,
                                                        $reductionCatalogValue
                                                ),
                                                $entity->getTaxRateInherited()->getValue()
                                        );
                                } elseif ($reductionCatalogBehaviorTaxRate == 'tax-included') {
                                        $priceWithTax = $this->applyReductionAmount(
                                                $priceWithTax,
                                                $reductionCatalogValue
                                        );
                                }
                        }
                }

                if ($withTax) {
                        $priceReturn = $priceWithTax;
                } else {
                        $priceReturn = $this->applyPercentNegative($priceWithTax, $entity->getTaxRateInherited()->getValue());
                }

                return $this->round($priceReturn);
        }

        public function getTotalTaxes($entity)
        {
                if ($entity instanceof OrderProductInterface) {
                        return $this->getTotalWithReduction($entity) * ($entity->getTaxRateInherited()->getValue() / 100);
                }

                if ($entity instanceof OrderShopInterface) {
                        $totalTaxes = 0;
                        foreach ($entity->getOrderProducts() as $orderProduct) {
                                $totalTaxes += $this->getTotalTaxes($orderProduct);
                        }
                        return $totalTaxes;
                }

                return 0;
        }

        public function applyTax($price, $taxRateValue)
        {
                return $this->round($this->applyPercent($price, $taxRateValue));
        }

        public function applyReductionPercent($price, $percentage)
        {
                return $this->applyPercent($price, -$percentage);
        }

        public function applyReductionAmount($price, $amount)
        {
                return $price - $amount;
        }

        public function applyPercent($price, $percentage)
        {
                return $price * ($percentage / 100 + 1);
        }

        public function applyPercentNegative($price, $percentage)
        {
                return $price / ($percentage / 100 + 1);
        }

        public function round($price)
        {
                return round((($price * 100)) / 100, 2);
        }

}