from __future__ import annotations

from decimal import Decimal, InvalidOperation

from jarvis_finance.api.schemas.common import Money, Quantity
from jarvis_finance.dashboard import data as dashboard_data


def decimal_text(value: object | None, places: int | None = None) -> str:
    if value is None or str(value).strip() == "":
        return "0" if places is None else "0." + ("0" * places)
    try:
        d = dashboard_data.d(value)
    except (InvalidOperation, ValueError):
        d = Decimal("0")
    if places is not None:
        quant = Decimal("1").scaleb(-places)
        d = d.quantize(quant)
    return format(d, "f")


def optional_decimal_text(value: object | None, places: int | None = None) -> str | None:
    if value is None or str(value).strip() == "":
        return None
    text = decimal_text(value, places)
    return text


def money_chf(value: object | None, *, display: str | None = None) -> Money | None:
    if value is None or str(value).strip() == "":
        return None
    return Money(amount=decimal_text(value, 2), currency="CHF", display=display or f"CHF {decimal_text(value, 2)}")


def money_chf_required(value: object | None) -> Money:
    return money_chf(value) or Money(amount="0.00", currency="CHF", display="CHF 0.00")


def quantity(value: object | None, unit: str, *, display: str | None = None) -> Quantity:
    amount = decimal_text(value)
    return Quantity(amount=amount, unit=unit, display=display or f"{amount} {unit}".strip())


def user_quality_status(value: object | None) -> str:
    raw = str(value or "").strip().lower()
    if raw in {"ok", "fresh", "aktuell", "resolved", "not_needed"}:
        return "ok"
    if raw in {"critical", "kritisch", "error", "failed", "missing"}:
        return "critical"
    return "warning"


def status_label(value: object | None) -> str:
    raw = str(value or "").strip().lower()
    mapping = {
        "ok": "Aktuell",
        "fresh": "Aktuell",
        "not_needed": "Nicht nötig",
        "missing": "Fehlt",
        "stale": "Veraltet",
        "warning": "Warnung",
        "critical": "Kritisch",
        "incomplete": "Unvollständig",
        "partial": "Teilweise",
    }
    return mapping.get(raw, str(value or "Unbekannt"))
