<?php

namespace KupShop\KupShopBundle\Util\Price;

use KupShop\I18nBundle\Entity\Currency;

class PriceLevelPrice extends ProductPrice
{
    protected $originalPrice;

    protected $pricelevelDiscount;

    protected ?array $priceLevelCacheWithVat = null;

    public function __construct(ProductPrice $productPrice)
    {
        $this->originalPrice = $productPrice;
        $this->vat = $productPrice->getVat();
        $this->currency = $productPrice->getCurrency();
    }

    public function getPriceWithoutDiscount(): Price
    {
        return $this->originalPrice->getPriceWithoutDiscount();
    }

    public function getPriceWithVat($round = true): \Decimal
    {
        if (isset($this->priceLevelCacheWithVat[$round])) {
            return $this->priceLevelCacheWithVat[$round];
        }

        $price = $this->originalPrice->getPriceWithVat(false);

        if ($this->pricelevelDiscount) {
            $discount = toDecimal($this->pricelevelDiscount['discount']);
            switch ($this->pricelevelDiscount['unit']) {
                case 'perc':
                    // check if adding discount is disabled and other discount exists
                    if ($this->pricelevelDiscount['add'] == false && $this->originalPrice->getDiscount() && $this->originalPrice->getDiscount()->isPositive()) {
                        if ($this->originalPrice->getDiscount()->lowerThan($discount)) {
                            // pricelevelDiscount is bigger -> remove other discount
                            $price = $price->removeDiscount($this->originalPrice->getDiscount());
                        } else {
                            // pricelevelDiscount is lower -> add zero discount
                            $discount = \DecimalConstants::zero();
                        }
                    }
                    $price = $price->addDiscount($discount);
                    break;
                case 'price':
                    $price = $price->sub($discount->addVat($this->originalPrice->getVat()));
                    break;
                case 'final_price':
                    $price = toDecimal($this->pricelevelDiscount['discount'])->addVat($this->getVat());
                    break;
            }
        }

        if ($round) {
            $price = $this->round($price);
        }

        return $this->priceLevelCacheWithVat[$round] = $price;
    }

    public function getCurrency(): Currency
    {
        return $this->originalPrice->getCurrency();
    }

    public function addDiscount(\Decimal $discount)
    {
        return $this->originalPrice->addDiscount($discount);
    }

    public function getPricelevelDiscount()
    {
        return $this->pricelevelDiscount;
    }

    public function setPricelevelDiscount(array $pricelevelDiscount)
    {
        $this->pricelevelDiscount = $pricelevelDiscount;

        // Recalc
        $this->setValue($this->getPriceWithoutVat(false));
    }

    /**
     * @return ProductPrice
     */
    public function getOriginalPrice()
    {
        return $this->originalPrice;
    }

    public function setOriginalPrice(ProductPrice $originalPrice): self
    {
        $this->originalPrice = $originalPrice;

        // recalc
        $this->setValue($this->getPriceWithoutVat(false));

        return $this;
    }

    protected function clearPriceCache()
    {
        parent::clearPriceCache();
        $this->priceLevelCacheWithVat = null;
    }
}
