<?php

namespace KupShop\OrderingBundle\Feed\Wrapper;

use KupShop\FeedsBundle\Wrapper\BaseWrapper;
use KupShop\FeedsBundle\Wrapper\CurrencyWrapper;
use KupShop\I18nBundle\Util\PriceConverter;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Price\TotalPrice;

class TotalPriceWrapper extends BaseWrapper
{
    protected static $objectType = TotalPrice::class;

    /** @var TotalPrice */
    protected $object;

    /** @var CurrencyWrapper */
    protected $currencyWrapper;

    /** @var CurrencyContext */
    protected $currencyContext;

    /** @var PriceConverter */
    protected $priceConverter;

    public function __construct(CurrencyWrapper $currencyWrapper, CurrencyContext $currencyContext)
    {
        $this->currencyWrapper = $currencyWrapper;
        $this->currencyContext = $currencyContext;
    }

    /**
     * @required
     *
     * @private
     */
    public function setPriceConverter(?PriceConverter $priceConverter = null): void
    {
        $this->priceConverter = $priceConverter;
    }

    /** Cena s DPH */
    public function field_withVat(): float
    {
        return $this->convertToActiveCurrency($this->object->getPriceWithVat())->asFloat();
    }

    /** Cena bez DPH */
    public function field_withoutVat(): float
    {
        return $this->convertToActiveCurrency($this->object->getPriceWithoutVat())->asFloat();
    }

    /** Hodnota DPH */
    public function field_vatValue(): float
    {
        return $this->convertToActiveCurrency($this->object->getPriceWithVat()->sub($this->object->getPriceWithoutVat()))->asFloat();
    }

    /** Měna */
    public function field_currency(): CurrencyWrapper
    {
        return $this->currencyWrapper->setObject($this->currencyContext->getActive());
    }

    /**
     * Naformátuje cenu (price).
     *
     * Druhý parametr (decimal_char) - oddělovač desetinné části.
     * Třetí parametr (decimal_places) - počet číslic za desetinnou čárkou.
     * Čtvrtý parametr (thousands_sep) - oddělovač tisíců.
     *
     * @param string $decimal_char
     * @param int    $decimal_places
     * @param string $thousands_sep
     *
     * @return string
     */
    public function format($price, $decimal_char = ',', $decimal_places = 2, $thousands_sep = ' ')
    {
        return number_format($price, $decimal_places, $decimal_char, $thousands_sep);
    }

    /**
     * Zaokrouhlí cenu dle konvencí e-shopu.
     *
     * @return float
     */
    public function round($price)
    {
        $price = roundPrice($price);

        return $price->asFloat();
    }

    /**
     * Zkonvertuje cenu (price) do měny (currency) dle aktuálního kurzu.
     *
     * @module CURRENCIES
     *
     * @return float
     */
    public function convert($price, $currency = 'CZK')
    {
        try {
            return $this->priceConverter->convert($this->object->getCurrency(), $currency, $price)->asFloat();
        } catch (\Throwable $e) {
            return $price;
        }
    }

    /** @private */
    protected function convertToActiveCurrency(\Decimal $value): \Decimal
    {
        $currency = $this->currencyContext->getActive();

        if ($this->object->getCurrency()->getId() != $currency->getId()) {
            $converted = $value->mul($this->object->getCurrency()->getRate());
            $converted = $converted->div($currency->getRate());

            return $converted;
        }

        return $value;
    }
}
