<?php

namespace KupShop\OrderDiscountBundle\Triggers;

use KupShop\I18nBundle\Util\PriceConverter;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Query\JsonOperator;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
use Query\Operator;

class PriceRangeTrigger extends AbstractTrigger
{
    protected static $type = 'price_range';
    protected static $position = 30;
    protected $adminTemplate = 'triggers/price_range.tpl';

    protected $priceConverter;
    protected $currencyContext;

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

    public function getDiscountFilterSpec(PurchaseState $purchaseState)
    {
        $totalPrice = $purchaseState->getProductsTotalPrice();

        $totalPriceWithVat = $this->priceConverter->convert(
            $totalPrice->getCurrency(), $this->currencyContext->getDefault(), $totalPrice->getPriceWithVat()
        )->asFloat();

        $totalPriceWithoutVat = $this->priceConverter->convert(
            $totalPrice->getCurrency(), $this->currencyContext->getDefault(), $totalPrice->getPriceWithoutVat()
        )->asFloat();

        $min = JsonOperator::value('odt.data', 'min', true);
        $max = JsonOperator::value('odt.data', 'max', true);
        $rate = 1;
        if (findModule(\Modules::CURRENCIES)) {
            $currency = JsonOperator::value('odt.data', 'unit');
            $rate = "COALESCE((SELECT rate from currencies WHERE id = {$currency}), 1)";
        }

        $withVat = Operator::andX(
            Operator::not(JsonOperator::contains('odt.data', 'withVat', '0')),
            Operator::not(
                Operator::andX(
                    "{$min} IS NULL OR {$totalPriceWithVat} >= {$min} * {$rate}",
                    "{$max} IS NULL OR {$totalPriceWithVat} <= {$max} * {$rate}"
                )
            )
        );

        $withoutVat = Operator::andX(
            JsonOperator::contains('odt.data', 'withVat', '0'),
            Operator::not(
                Operator::andX(
                    "{$min} IS NULL OR {$totalPriceWithoutVat} >= {$min} * {$rate}",
                    "{$max} IS NULL OR {$totalPriceWithoutVat} <= {$max} * {$rate}"
                )
            )
        );

        return Operator::andX(
            Operator::equals(['odt.type' => static::getType()]),
            Operator::orX(
                $withVat,
                $withoutVat
            )
        );
    }

    public function getErrorMessage(PurchaseState $purchaseState, array $data): string
    {
        $error_message = '';

        if (!empty($data['min'])) {
            $totalPrice = $purchaseState->getTotalPriceForDiscounts()->getPriceWithVat();
            $minPrice = toDecimal($data['min']);
            $currency = $data['unit'] ?? $this->currencyContext->getDefaultId();
            $minPrice = $this->priceConverter->convert($currency, $purchaseState->getTotalPriceForDiscounts()->getCurrency(), $minPrice);
            $payForDiscount = $minPrice->sub($totalPrice);
            if ($payForDiscount->isPositive()) {
                $error_message = sprintf(
                    translate_shop('discount_price', 'order'),
                    printPrice($payForDiscount),
                    printPrice($minPrice)
                );
            }
        }

        return $error_message;
    }
}
