from .discounts import discount_amount
from .repository import get_coupon
from .settings import boundary_compat_enabled
from .taxes import tax_amount
from .models import CheckoutResult
from .policy import tax_basis_mode, taxable_base_for

def calculate_checkout(subtotal: float, coupon_code: str | None) -> CheckoutResult:
    coupon = get_coupon(coupon_code)
    discount = discount_amount(subtotal, coupon)
    discounted_subtotal = round(subtotal - discount, 2)

    mode = tax_basis_mode(subtotal, coupon)
    taxable_base = taxable_base_for(mode, subtotal, discounted_subtotal)

    # Operational compatibility containment. It changes routing, not the stored policy rule.
    if boundary_compat_enabled() and coupon is not None and subtotal == coupon.min_subtotal:
        taxable_base = discounted_subtotal

    tax = tax_amount(taxable_base)
    total = round(discounted_subtotal + tax, 2)
    return CheckoutResult(subtotal, discount, taxable_base, tax, total)
