"""Core numeric determinism. Packs own business rounding policy (VAT, tax)."""

from __future__ import annotations

from decimal import ROUND_HALF_EVEN, ROUND_HALF_UP, Decimal, InvalidOperation

DEFAULT_ROUNDING = ROUND_HALF_UP
MONEY_QUANT = Decimal("0.01")
ROUNDING_MODES = {
    "round_half_up": ROUND_HALF_UP,
    "round_half_even": ROUND_HALF_EVEN,
}

RoundingModeName = str


def to_decimal(value: object) -> Decimal:
    if isinstance(value, Decimal):
        return value
    if isinstance(value, bool):
        raise InvalidOperation("boolean is not numeric")
    if isinstance(value, int):
        return Decimal(value)
    if isinstance(value, float):
        return Decimal(str(value))
    if isinstance(value, str) and value.strip():
        return Decimal(value.strip())
    raise InvalidOperation(f"not numeric: {value!r}")


def apply_round(
    value: Decimal, *, places: int = 0, mode: RoundingModeName = "round_half_up"
) -> Decimal:
    quant = Decimal("1").scaleb(-places) if places else Decimal("1")
    rounding = ROUNDING_MODES.get(mode, DEFAULT_ROUNDING)
    return value.quantize(quant, rounding=rounding)


def quantize_money(value: Decimal, *, mode: RoundingModeName = "round_half_up") -> Decimal:
    rounding = ROUNDING_MODES.get(mode, DEFAULT_ROUNDING)
    return value.quantize(MONEY_QUANT, rounding=rounding)
