"""オフラインで Noul / Choice / Score の意味を体験する最小例。

これは TypeSafe API の代替推論器ではない。API の typed answer shape を
ローカルの決定論的なデータで再現し、ガイドの分岐ロジックを API キーなしで
試すための教材である。
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Mapping, Sequence


@dataclass(frozen=True)
class OfflineNoul:
    noul: float


@dataclass(frozen=True)
class OfflineChoice:
    choice: str
    probabilities: Mapping[str, float]
    confidence: float


@dataclass(frozen=True)
class OfflineScore:
    score: float
    legend: Mapping[int, str]
    probabilities: Mapping[int, float]
    confidence: float


def evaluate_ticket(ticket: str) -> tuple[OfflineNoul, OfflineChoice, OfflineScore]:
    """固定ルールで typed answer の読み出しを練習する。ネットワーク不要。"""
    refund = any(word in ticket for word in ("請求", "返金", "refund"))
    noul = OfflineNoul(0.95 if refund else 0.05)

    route = "billing" if refund else "other"
    route_probabilities = {
        "billing": 0.90 if route == "billing" else 0.05,
        "technical": 0.05,
        "other": 0.90 if route == "other" else 0.05,
    }
    choice = OfflineChoice(
        choice=route,
        probabilities=route_probabilities,
        confidence=0.85,
    )

    levels: Sequence[str] = ("can wait", "this week", "today")
    urgent = any(word in ticket for word in ("今日", "至急", "ASAP"))
    probabilities = {0: 0.03, 1: 0.07, 2: 0.90} if urgent else {0: 0.90, 1: 0.07, 2: 0.03}
    score = OfflineScore(
        score=sum(level * probability for level, probability in probabilities.items()),
        legend=dict(enumerate(levels)),
        probabilities=probabilities,
        confidence=0.82,
    )
    return noul, choice, score


def main() -> None:
    state = "二重請求です。今日中に返金してください。"
    noul, choice, score = evaluate_ticket(state)
    print(f"Noul (yes probability): {noul.noul:.2f}")
    print(f"Choice (route): {choice.choice}")
    print(f"Choice probabilities: {dict(choice.probabilities)}")
    print(f"Score (urgency expected level): {score.score:.2f} / 2.00")
    print(f"Score probabilities: {dict(score.probabilities)}")
    if noul.noul >= 0.8 and choice.confidence >= 0.8:
        print("offline routing: billing queue")


if __name__ == "__main__":
    main()
