<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Pricing\PriceCurrencyInterface;

/**
 *
 *
 */
class Calculator implements PriceCurrencyInterface
{

    /** @var string */
    public const XML_REFILO_CATALOG_PRODUCTS_SALES_RULE_PRICE_ROUNDING = 'refilo_catalog/products/sales_rule_price_rouding';
    /** @var string */
    public const XML_REFILO_CATALOG_PRODUCTS_SALES_RULE_PRICE_ROUNDING_DECIMAL = 'refilo_catalog/products/sales_rule_price_rouding_decimal';
    /** @var string */
    public const XML_REFILO_CATALOG_PRODUCTS_SALES_RULE_PRICE_ROUNDING_STRATEGY = 'refilo_catalog/products/sales_rule_price_rouding_strategy';
    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    private $scopeConfig;
    /**
     * @var \Magento\Framework\Pricing\PriceCurrencyInterface
     */
    private $defaultPriceCurrency;
    /**
     * @var \FiloBlu\Refilo\Model\RoundingStrategyProvider
     */
    private $roundingStrategyProvider;


    /**
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $defaultPriceCurrency
     * @param \FiloBlu\Refilo\Model\RoundingStrategyProvider $roundingStrategyProvider
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        PriceCurrencyInterface $defaultPriceCurrency,
        RoundingStrategyProvider $roundingStrategyProvider
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->defaultPriceCurrency = $defaultPriceCurrency;
        $this->roundingStrategyProvider = $roundingStrategyProvider;
    }

    /**
     * @inheritdoc
     */
    public function round($price)
    {
        if (!$this->scopeConfig->isSetFlag(self::XML_REFILO_CATALOG_PRODUCTS_SALES_RULE_PRICE_ROUNDING)) {
            return $this->roundingStrategyProvider->getDefault()
                ->round($price, PriceCurrencyInterface::DEFAULT_PRECISION);
        }

        $strategy = $this->scopeConfig
            ->getValue(self::XML_REFILO_CATALOG_PRODUCTS_SALES_RULE_PRICE_ROUNDING_STRATEGY);
        $decimals = (int)$this->scopeConfig
            ->getValue(self::XML_REFILO_CATALOG_PRODUCTS_SALES_RULE_PRICE_ROUNDING_DECIMAL);

        return $this->roundingStrategyProvider->getOrDefault($strategy)->round($price, $decimals);
    }

    /**
     * Convert price value
     *
     * @param float $amount
     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
     * @return float
     */
    public function convert($amount, $scope = null, $currency = null)
    {
        return $this->defaultPriceCurrency->convert($amount, $scope, $currency);
    }

    /**
     * Convert and round price value
     *
     * @param float $amount
     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
     * @param int $precision
     * @return float
     */
    public function convertAndRound($amount, $scope = null, $currency = null, $precision = self::DEFAULT_PRECISION)
    {
        return $this->defaultPriceCurrency->convertAndRound($amount, $scope, $currency, $precision);
    }

    /**
     * Format price value
     *
     * @param float $amount
     * @param bool $includeContainer
     * @param int $precision
     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
     * @return string
     */
    public function format(
        $amount,
        $includeContainer = true,
        $precision = self::DEFAULT_PRECISION,
        $scope = null,
        $currency = null
    ) {
        return $this->defaultPriceCurrency->format($amount, $includeContainer, $precision, $scope, $currency);
    }

    /**
     * Convert and format price value
     *
     * @param float $amount
     * @param bool $includeContainer
     * @param int $precision
     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
     * @return string
     */
    public function convertAndFormat(
        $amount,
        $includeContainer = true,
        $precision = self::DEFAULT_PRECISION,
        $scope = null,
        $currency = null
    ) {
        return $this->defaultPriceCurrency->convertAndFormat($amount, $includeContainer, $precision, $scope, $currency);
    }

    /**
     * Get currency model
     *
     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
     * @return \Magento\Framework\Model\AbstractModel
     */
    public function getCurrency($scope = null, $currency = null)
    {
        return $this->defaultPriceCurrency->getCurrency($scope, $currency);
    }

    /**
     * Get currency symbol
     *
     * @param null|string|bool|int|\Magento\Framework\App\ScopeInterface $scope
     * @param \Magento\Framework\Model\AbstractModel|string|null $currency
     * @return string
     */
    public function getCurrencySymbol($scope = null, $currency = null)
    {
        return $this->defaultPriceCurrency->getCurrencySymbol($scope, $currency);
    }
}