from __future__ import annotations

from typing import Any, Optional


LEVEL_LOW = "LOW"
LEVEL_MEDIUM = "MEDIUM"
LEVEL_HIGH = "HIGH"
LEVEL_VERY_STRONG = "VERY_STRONG"


def normalize_confidence(
    value: Any,
    *,
    decision_probability: Any = None,
    score: Any = None,
) -> str:
    """Normalize confidence into a single 4-level scale.

    Canonical levels:
    - LOW
    - MEDIUM
    - HIGH
    - VERY_STRONG

    Accepts common aliases (e.g., WEAK/STRONG, VERY_HIGH, HIGHSTRONG) and can
    derive a level from numeric probability/score when the label is missing.

    Numeric derivation (0-100):
    - >= 90: VERY_STRONG
    - >= 75: HIGH
    - >= 60: MEDIUM
    - else: LOW
    """

    s = ("" if value is None else str(value)).strip().upper()
    compact = s.replace(" ", "").replace("_", "").replace("-", "")

    if compact in {"VERYSTRONG", "VERYHIGH", "VHIGH", "HIGHSTRONG", "HIGHSRTRONG"}:
        return LEVEL_VERY_STRONG

    if compact in {"HIGH", "STRONG"}:
        return LEVEL_HIGH

    if compact in {"MED", "MEDIUM", "MID"}:
        return LEVEL_MEDIUM

    if compact in {"LOW", "WEAK"}:
        return LEVEL_LOW

    p = _safe_float(decision_probability)
    if p is None:
        p = _safe_float(score)

    if p is None:
        return LEVEL_LOW

    if p >= 90:
        return LEVEL_VERY_STRONG
    if p >= 75:
        return LEVEL_HIGH
    if p >= 60:
        return LEVEL_MEDIUM
    return LEVEL_LOW


def confidence_rank(level: Any) -> int:
    """Rank confidence for sorting/comparisons."""

    s = normalize_confidence(level)
    return {
        LEVEL_LOW: 1,
        LEVEL_MEDIUM: 2,
        LEVEL_HIGH: 3,
        LEVEL_VERY_STRONG: 4,
    }.get(s, 1)


def confidence_at_least(actual: Any, minimum: Any) -> bool:
    return confidence_rank(actual) >= confidence_rank(minimum)


def _safe_float(v: Any) -> Optional[float]:
    try:
        if v is None:
            return None
        if isinstance(v, bool):
            return None
        return float(v)
    except Exception:
        return None
