<?php

namespace Lc\CaracoleBundle\Solver\Price;

use Lc\CaracoleBundle\Doctrine\Extension\ProductPropertyInterface;
use Lc\CaracoleBundle\Model\Order\OrderProductInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\CaracoleBundle\Model\Product\ProductInterface;

trait PriceSolverTrait
{
    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);
    }

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

    public function applyReductionCatalog(
            $entity,
            $price,
            $priceWithTax,
            $quantity = 1,
            $reductionCatalog = null,
            $withTax = true,
            $round = true
    ): ?float {
        if ($reductionCatalog) {
            $reductionCatalogValue = $reductionCatalog->getValue();
            $reductionCatalogUnit = $reductionCatalog->getUnit();
            $reductionCatalogBehaviorTaxRate = $reductionCatalog->getBehaviorTaxRate();
        } else {
            if ($entity instanceof ProductInterface) {
                $reductionCatalog = $this->productSolver->getReductionCatalogInherited($entity);
            }

            if ($entity instanceof ProductFamilyInterface) {
                $reductionCatalog = $this->productFamilySolver->getReductionCatalogInherited($entity);
            }

            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 * $quantity
                            ),
                            $entity->getTaxRateInherited()->getValue()
                    );
                } elseif ($reductionCatalogBehaviorTaxRate == 'tax-included') {
                    $priceWithTax = $this->applyReductionAmount(
                            $priceWithTax,
                            $reductionCatalogValue * $quantity
                    );
                }
            }
        }

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

}