"""Explicit two-decimal money, fixed discounts and snapshotted tax percentages."""
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
from django.core.exceptions import ValidationError

CENT = Decimal("0.01")
MAX_MONEY = Decimal("999999999999.99")


def decimal_value(value, *, maximum=MAX_MONEY):
    if isinstance(value, (float, bool)):
        raise ValidationError("Use exact decimal money, never floating point.")
    try:
        result = Decimal(value)
        if not result.is_finite() or result < 0 or result > maximum or result != result.quantize(CENT):
            raise ValidationError("Supply a nonnegative, bounded decimal with at most two decimal places.")
        return result.quantize(CENT)
    except (InvalidOperation, TypeError, ValueError) as error:
        raise ValidationError("Invalid monetary value.") from error


def calculate(*, quantity, unit_price, discount="0", tax_rate="0"):
    if type(quantity) is not int or not 1 <= quantity <= 1000000:
        raise ValidationError("Quantity must be a positive bounded whole number.")
    price = decimal_value(unit_price)
    discount = decimal_value(discount)
    rate = decimal_value(tax_rate, maximum=Decimal("100"))
    subtotal = decimal_value(price * quantity)
    if discount > subtotal:
        raise ValidationError("Discount exceeds the line value.")
    taxable = subtotal - discount
    tax = (taxable * rate / Decimal("100")).quantize(CENT, rounding=ROUND_HALF_UP)
    total = decimal_value(taxable + tax)
    return dict(unit_price=price, subtotal=subtotal, discount=discount, taxable_amount=taxable,
                tax_rate=rate, tax=tax, total=total)
