<?php

declare(strict_types=1);

namespace KupShop\KupShopBundle\DiscountFieldDefinition;

use KupShop\KupShopBundle\Util\Contexts;
use KupShop\PricelistBundle\Context\PricelistContext;
use KupShop\PricelistBundle\Entity\Pricelist;
use Query\QueryBuilder;

/**
 * Default product discount field definition (product price, price list price of active price list).
 */
class ProductDiscountFieldDefinition extends AbstractDiscountFieldDefinition
{
    protected function getSpecs(): array
    {
        $specs = [];

        $specs[] = function (QueryBuilder $qb) {
            $qb->joinVariationsOnProducts();
        };

        if ($this->getActivePriceList()) {
            $specs[] = function (QueryBuilder $qb) {
                $qb->joinPriceListsProducts()
                    ->leftJoin('prl', 'currencies', 'c', 'c.id = prl.currency')
                    ->leftJoin('prl_v', 'currencies', 'c_v', 'c_v.id = prl_v.currency');
            };
        }

        return $specs;
    }

    protected function getColumn(): string
    {
        if ($this->getActivePriceList()) {
            // discount should fallback to product discount if enabled on price list
            if ($this->getActivePriceList()?->getUseProductDiscount()) {
                return 'COALESCE(prlv.discount, prlp.discount, p.discount)';
            }

            return 'COALESCE(prlv.discount, prlp.discount, 0)';
        }

        return 'p.discount';
    }

    protected function getPriceColumn(): string
    {
        if ($this->getActivePriceList()) {
            // when fallbacked to default price, I need to convert price to pricelist currency because of price for discount in pricelist currency
            return 'COALESCE(prlv.price*c_v.rate, pv.price, prlp.price*c.rate, p.price)';
        }

        if (findModule(\Modules::PRODUCTS_VARIATIONS)) {
            return 'COALESCE(pv.price, p.price)';
        }

        return 'p.price';
    }

    protected function getPriceForDiscountColumn(): ?string
    {
        return null;
    }

    protected function getActivePriceList(): ?Pricelist
    {
        if (!findModule(\Modules::PRICELISTS)) {
            return null;
        }

        return Contexts::get(PricelistContext::class)->getActive();
    }
}
