"""Démonstration Jev : avis fictifs, thèmes multiples et sentiment global.

Python >= 3.10 ; pip install typesafe-sdk==0.7.0
Définir TYPESAFE_API_KEY, puis : python classer_avis.py > resultats.jsonl
Les seuils illustrent une règle de routage ; ils ne sont pas calibrés.
"""

import json
import os

from typesafe_sdk import Choice, Noul, TypeSafeClient, TypeSafeError

MODEL = "jev-1.13.0"
VERSION_QUESTIONS = "avis-v1"
SEUIL_PRESENT = 0.80
SEUIL_ABSENT = 0.20

THEMES = {
    "produit": "qualité, usage ou conformité du produit à sa description",
    "livraison": "transport, colis, délai ou déroulement de la livraison",
    "service_client": "échanges avec le support ou le service après-vente",
    "paiement": "débit, facturation, paiement ou remboursement",
    "prix": "niveau du prix ou rapport qualité-prix",
}

QUESTIONS = {
    "sentiment": Choice(
        instructions="Quel sentiment global cet avis client exprime-t-il ?",
        criteria={
            "positif": "Appréciation favorable, sans critique explicite.",
            "negatif": "Critique, sans appréciation favorable explicite.",
            "mixte": "Présence d'appréciations favorables ET de critiques.",
            "neutre": "Texte compréhensible, purement factuel, sans opinion.",
            "indetermine": "Texte trop ambigu ou incompréhensible pour conclure.",
        },
    ),
    **{
        theme: Noul(
            instructions=(
                f"L'avis aborde-t-il ce thème : {definition} ? "
                "Une mention positive ou négative compte. "
                "Évalue uniquement ce qui est exprimé dans l'avis."
            )
        )
        for theme, definition in THEMES.items()
    },
}

AVIS = [
    ("avis-001", "Produit très solide, mais livré avec quatre jours de retard."),
    ("avis-002", "Débité deux fois. Le support ne répond pas depuis une semaine."),
    ("avis-003", "Conforme à la description, je suis ravi de mon achat."),
]


def classer(client, identifiant, texte):
    base = {"id": identifiant, "version_questions": VERSION_QUESTIONS}
    if not texte.strip():
        return {**base, "statut": "texte_vide", "a_relire": True}

    try:
        reponse = client.system_one(state={"avis": texte}, questions=QUESTIONS)
    except TypeSafeError as erreur:
        return {
            **base, "statut": "erreur_api", "a_relire": True,
            "erreur": type(erreur).__name__,
        }

    sentiment = reponse.choices["sentiment"]
    probabilites = {t: reponse.nouls[t].noul for t in THEMES}
    presents = [t for t, p in probabilites.items() if p >= SEUIL_PRESENT]
    incertains = [
        t for t, p in probabilites.items() if SEUIL_ABSENT < p < SEUIL_PRESENT
    ]
    a_relire = (
        bool(incertains)
        or not presents
        or sentiment.choice == "indetermine"
        or sentiment.probabilities[sentiment.choice] < SEUIL_PRESENT
    )

    return {
        **base,
        "modele": reponse.model,
        "statut": "a_relire" if a_relire else "proposition",
        "a_relire": a_relire,
        "sentiment": sentiment.choice,
        "sentiment_probabilites": sentiment.probabilities,
        "themes": presents,
        "themes_incertains": incertains,
        "themes_probabilites": probabilites,
        "tokens_entree": reponse.usage.input_tokens,
    }


def main():
    if not os.environ.get("TYPESAFE_API_KEY", "").strip():
        raise SystemExit("Définissez la variable TYPESAFE_API_KEY avant de lancer le script.")
    with TypeSafeClient(model=MODEL, timeout=30.0) as client:
        for identifiant, texte in AVIS:
            print(json.dumps(classer(client, identifiant, texte), ensure_ascii=False))


if __name__ == "__main__":
    main()
