from __future__ import annotations

from typing import Any

from app.features.personalized_reco.content_repository.types import Locale, normalize_locale


CONTEXT_KEYS: tuple[str, ...] = ("family", "work", "relationship", "friends", "health")
NEED_KEYS: tuple[str, ...] = (
    "emotional_support",
    "parenting_pressure",
    "self_worth",
    "anxiety_relief",
    "rest_balance",
)


def _normalize_discrete_score(v: Any, *, default: float = 0.5) -> float:
    """
    将 suitability 的离散值规范化为 0/0.5/1。

    非法值一律兜底 default（默认 0.5）。
    """

    try:
        if v in (0, 0.0):
            return 0.0
        if v in (0.5,):
            return 0.5
        if v in (1, 1.0):
            return 1.0
        # 允许字符串形式的 "0"/"0.5"/"1"
        if isinstance(v, str):
            s = v.strip()
            if s == "0":
                return 0.0
            if s == "0.5":
                return 0.5
            if s == "1":
                return 1.0
    except Exception:
        return default
    return default


def normalize_suitability(raw: Any, *, keys: tuple[str, ...]) -> dict[str, float]:
    """
    解析 suitability JSON，缺失时补齐全 0.5。

    raw 期望为 dict；否则视为缺失。
    """

    data: dict[str, Any] = raw if isinstance(raw, dict) else {}
    return {k: _normalize_discrete_score(data.get(k), default=0.5) for k in keys}


def normalize_review_confidence(raw: Any) -> float:
    """
    review_confidence 缺失/NULL 时兜底 0.7。
    """

    try:
        if raw is None:
            return 0.7
        v = float(raw)
        if 0.0 <= v <= 1.0:
            return v
    except Exception:
        pass
    return 0.7


def normalize_personalization_power(raw: Any) -> float:
    """
    DB 约定存 0/5/10，读取层输出 0/0.5/1。
    """

    try:
        if raw is None:
            return 0.0
        v = int(raw)
        if v == 0:
            return 0.0
        if v == 5:
            return 0.5
        if v == 10:
            return 1.0
    except Exception:
        pass
    return 0.0


_RISK_FLAG_MAP: dict[str, str] = {
    "block_stage_unknown": "unsafe_for_stage_unknown",
    "block_stage_parenting": "unsafe_for_stage_parenting",
    "block_emotion_low": "unsafe_for_emotion_low",
    "block_health_sensitive": "block_health_medical",
}


def normalize_risk_flags(raw_flags: list[str] | None) -> list[str]:
    """
    risk_flags 旧→新映射、去重、稳定排序（字典序）。
    """

    flags = raw_flags or []
    mapped: set[str] = set()
    for f in flags:
        if not f:
            continue
        name = _RISK_FLAG_MAP.get(f, f)
        mapped.add(name)
    return sorted(mapped)


def pick_text(*, text_en: str | None, text_tc: str | None, locale: str) -> str | None:
    """
    按 locale 选择输出文案文本。

    当前仅支持 EN/TC，且不允许语言回退：
    - locale=en*：必须使用 text_en
    - locale=tc/zh-TW/zh-HK：必须使用 text_tc
    """

    loc: Locale = normalize_locale(locale)
    if loc == "en":
        return text_en if text_en else None
    # loc == "tc"
    return text_tc if text_tc else None

