"""Utility functions for ZUGFeRD service."""

from decimal import Decimal, ROUND_HALF_UP

UNECE_UNIT_CODES = {
    "C62": "Stück",
    "H87": "Stück",
    "KGM": "Kilogramm",
    "GRM": "Gramm",
    "TNE": "Tonne",
    "MTR": "Meter",
    "KMT": "Kilometer",
    "MTK": "Quadratmeter",
    "LTR": "Liter",
    "MLT": "Milliliter",
    "DAY": "Tag",
    "HUR": "Stunde",
    "MON": "Monat",
    "ANN": "Jahr",
    "SET": "Set",
    "PCE": "Stück",
    "EA": "Stück",
}


def translate_unit_code(code: str) -> str:
    """Map UN/ECE unit code to human-readable German name.

    Args:
        code: UN/ECE unit code (e.g., "C62", "KGM")

    Returns:
        Human-readable German name or original code if not found
    """
    return UNECE_UNIT_CODES.get(code, code)


def amounts_match(actual: float, expected: float, tolerance: float = 0.01) -> bool:
    """Check if two amounts match within tolerance.

    Args:
        actual: Actual value
        expected: Expected value
        tolerance: Allowed difference (default: 0.01 EUR)

    Returns:
        True if |actual - expected| <= tolerance
    """
    # Add small epsilon to handle floating point precision issues
    return abs(actual - expected) <= tolerance + 1e-10


def parse_german_number(num_str: str) -> float:
    """Convert German number format to float.

    German: 1.234,56 (dot = thousands, comma = decimal)
    Result: 1234.56

    Args:
        num_str: German formatted number string

    Returns:
        Float value
    """
    # Remove thousands separator (dots)
    # Replace decimal separator (comma) with dot
    return float(num_str.replace(".", "").replace(",", "."))


def parse_german_date(date_str: str) -> str:
    """Convert German date to ISO format (YYYY-MM-DD).

    German: 04.02.2025
    Result: 2025-02-04

    Args:
        date_str: German formatted date string

    Returns:
        ISO formatted date string
    """
    if "." in date_str and len(date_str.split(".")) == 3:
        day, month, year = date_str.split(".")
        return f"{year}-{month.zfill(2)}-{day.zfill(2)}"
    return date_str


def round_decimal(amount: float, places: int = 2) -> float:
    """Round decimal to specified places using standard rounding.

    Args:
        amount: Amount to round
        places: Decimal places (default: 2)

    Returns:
        Rounded float
    """
    # Use Decimal with ROUND_HALF_UP for standard rounding (not banker's rounding)
    if places > 0:
        quantizer = Decimal(f"1.{'0' * (places - 1)}1" if places > 1 else "0.1")
        return float(Decimal(str(amount)).quantize(quantizer, rounding=ROUND_HALF_UP))
    else:
        return round(amount, places)
