<?php

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Marketing;

use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Marketing\Model\AbandonedCartRule;

final readonly class AbandonedCartRuleSelector
{
    public function __construct(
        private AbandonedCartRuleMatcher $ruleMatcher,
    ) {
    }

    /**
     * @param iterable<AbandonedCartRule> $rules
     */
    public function selectMostAdvantageous(iterable $rules, Cart $cart): ?AbandonedCartRule
    {
        $selectedRule = null;
        $selectedBenefitTTC = -1;

        foreach ($rules as $rule) {
            if (!$rule->isEnabled() || !$this->ruleMatcher->matches($rule, $cart)) {
                continue;
            }

            $benefitTTC = $this->estimateBenefitTTC($rule, $cart);
            if (
                $benefitTTC > $selectedBenefitTTC
                || (
                    $benefitTTC === $selectedBenefitTTC
                    && $selectedRule instanceof AbandonedCartRule
                    && $rule->getPosition() < $selectedRule->getPosition()
                )
            ) {
                $selectedRule = $rule;
                $selectedBenefitTTC = $benefitTTC;
            }
        }

        return $selectedRule;
    }

    public function estimateBenefitTTC(AbandonedCartRule $rule, Cart $cart): int
    {
        if (
            !$rule->createsCoupon()
            || ($rule->isCouponOnlyWithoutExistingDiscount() && $cart->hasExistingDiscount())
        ) {
            return 0;
        }

        $subtotalTTC = $this->ruleMatcher->calculateSubtotalTTC($cart);

        return match ($rule->getDiscountType()) {
            AbandonedCartRule::DISCOUNT_FIXED => min(
                $subtotalTTC,
                max(0, $rule->getDiscountAmountTTC() ?? 0),
            ),
            AbandonedCartRule::DISCOUNT_PERCENT => min(
                $subtotalTTC,
                (int) round(
                    $subtotalTTC * max(0.0, $rule->getDiscountPercent() ?? 0.0) / 100,
                    0,
                    \PHP_ROUND_HALF_UP,
                ),
            ),
            AbandonedCartRule::DISCOUNT_FREE_SHIPPING => max(0, $cart->getShippingTTC() ?? 0),
            default => 0,
        };
    }
}
