"""Configuration du STT-server — via variables d'environnement (12-factor / k8s)."""

from __future__ import annotations

import os


class Settings:
    # LiteLLM (s01) — joint en IP directe depuis le cluster (cf. open-webui).
    litellm_url: str = os.getenv(
        "STT_LITELLM_URL", "http://192.168.10.1:4000/v1/chat/completions"
    )
    litellm_key: str = os.getenv("STT_LITELLM_KEY", "lm-studio")
    # Modèle par défaut + alias LiteLLM autorisés (le client peut en demander un par requête)
    model: str = os.getenv("STT_MODEL", "hermes-default")
    allowed_models: list[str] = [
        m.strip()
        for m in os.getenv(
            "STT_ALLOWED_MODELS",
            "hermes-default,qwen3-8b,claude-sonnet-4-6,claude-opus-4-7",
        ).split(",")
        if m.strip()
    ]

    system_prompt: str = os.getenv(
        "STT_SYSTEM_PROMPT",
        "Tu es Hermes, l'assistant vocal du homelab Funk. "
        "Réponds toujours en français, de façon concise (2-3 phrases maximum), "
        "sans markdown ni listes. "
        "Pour toute question sur Funk (cluster, machines, services, matériel, configuration), "
        "appuie-toi EXCLUSIVEMENT sur la documentation fournie ci-dessous. "
        "Règle stricte : si la doc ne mentionne pas explicitement l'élément demandé, réponds "
        "« la doc Funk ne le précise pas » — n'affirme JAMAIS un oui ni un non par déduction, "
        "et n'invente aucun détail (modèle, marque, nombre, nom).",
    )
    max_tokens: int = int(os.getenv("STT_MAX_TOKENS", "200"))
    temperature: float = float(os.getenv("STT_TEMPERATURE", "0.7"))
    # Timeout PAR tentative vers LiteLLM (brain fait jusqu'à 2 tentatives). Une réponse vocale
    # avec /no_think tient en quelques secondes → 30s suffit, et borne l'attente d'un blip backend.
    request_timeout: float = float(os.getenv("STT_REQUEST_TIMEOUT", "30"))
    # Qwen3 est un modèle « thinking » → ajoute `/no_think` pour désactiver le raisonnement
    # (sinon content vide / timeout). Inoffensif pour les modèles non-Qwen.
    disable_thinking: bool = os.getenv("STT_DISABLE_THINKING", "true").lower() == "true"

    # Mémoire long-terme (Qdrant) — dégrade proprement si Qdrant/embeddings injoignables
    memory_longterm: bool = os.getenv("STT_MEMORY_LONGTERM", "true").lower() == "true"
    qdrant_url: str = os.getenv("STT_QDRANT_URL", "http://192.168.10.1:6333")
    qdrant_collection: str = os.getenv("STT_QDRANT_COLLECTION", "stt-memory")
    # Embeddings : instance dédiée nomic-embed-text sur llama-server gpu-01 (:1238, dim 768).
    embed_url: str = os.getenv("STT_EMBED_URL", "http://192.168.10.20:1238/v1/embeddings")
    embed_model: str = os.getenv("STT_EMBED_MODEL", "nomic-embed-text")
    memory_top_k: int = int(os.getenv("STT_MEMORY_TOPK", "3"))
    # Le recall (embed + recherche) est sur le chemin de réponse : timeout SERRÉ pour qu'un
    # embed lent/mort dégrade vite (souvenirs vides) au lieu d'ajouter des secondes au client.
    # Le store tourne en tâche de fond (après la réponse) → timeout plus large toléré.
    memory_recall_timeout: float = float(os.getenv("STT_MEMORY_RECALL_TIMEOUT", "4"))
    memory_store_timeout: float = float(os.getenv("STT_MEMORY_STORE_TIMEOUT", "20"))

    # RAG documentaire : ancre les réponses dans la doc Funk (collection `funk-docs`,
    # même embedder nomic :1238 que la mémoire → le vecteur de requête est réutilisé).
    # Sans ça, le modèle répond de connaissances générales (hallucine sur le homelab).
    docs_rag: bool = os.getenv("STT_DOCS_RAG", "true").lower() == "true"
    docs_collection: str = os.getenv("STT_DOCS_COLLECTION", "funk-docs")
    docs_top_k: int = int(os.getenv("STT_DOCS_TOPK", "6"))
    # nomic étale les scores plus bas → seuil permissif (aligné sur rag-query).
    docs_min_score: float = float(os.getenv("STT_DOCS_MIN_SCORE", "0.45"))
    # Sur le chemin de réponse (1 recherche Qdrant, vecteur déjà calculé) → timeout serré.
    docs_timeout: float = float(os.getenv("STT_DOCS_TIMEOUT", "4"))

    # Contextes présélectionnables (visualiseur + presets live). Le contexte « funk »
    # garde le system_prompt grounding-strict ci-dessus ; les autres injectent des
    # données live. URLs surchargeables selon la résolution réseau in-cluster.
    default_context: str = os.getenv("STT_DEFAULT_CONTEXT", "funk")
    sources_timeout: float = float(os.getenv("STT_SOURCES_TIMEOUT", "4"))
    ghostfolio_url: str = os.getenv("STT_GHOSTFOLIO_URL", "http://ghostfolio.lab.local")
    # Jeton « Security token » du compte Ghostfolio (vide → données indisponibles).
    ghostfolio_token: str = os.getenv("STT_GHOSTFOLIO_TOKEN", "")
    prometheus_url: str = os.getenv("STT_PROMETHEUS_URL", "http://prometheus.lab.local")
    alertmanager_url: str = os.getenv("STT_ALERTMANAGER_URL", "http://alertmanager.lab.local")

    # Boucle d'outils (contexte « asa ») — function calling local (Qwen3-8B). Le modèle
    # appelle des outils de lecture (doc, santé hôtes, état cluster, PromQL) jusqu'à pouvoir
    # répondre, borné par tool_max_iters (puis réponse forcée sans outils).
    tool_max_iters: int = int(os.getenv("STT_TOOL_MAX_ITERS", "4"))
    tool_max_tokens: int = int(os.getenv("STT_TOOL_MAX_TOKENS", "512"))
    # Température basse pour le tool-use (sélection d'outil + arguments déterministes).
    tool_temperature: float = float(os.getenv("STT_TOOL_TEMPERATURE", "0.2"))
    # Recherche web (outil web_search) — SearXNG self-host in-cluster (namespace ai), API JSON.
    searxng_url: str = os.getenv("STT_SEARXNG_URL", "http://searxng:8080")
    web_search_results: int = int(os.getenv("STT_WEB_SEARCH_RESULTS", "5"))
    web_search_timeout: float = float(os.getenv("STT_WEB_SEARCH_TIMEOUT", "8"))

    # Actions via Hermes (contexte « agent ») — OPT-IN, désactivé par défaut.
    # Le contexte « agent » n'est exposé que si actions_enabled ET un jeton est présent.
    actions_enabled: bool = os.getenv("STT_ACTIONS_ENABLED", "false").lower() == "true"
    hermes_exec_url: str = os.getenv("STT_HERMES_EXEC_URL", "http://192.168.10.1:9096")
    hermes_exec_token: str = os.getenv("STT_HERMES_EXEC_TOKEN", "")
    hermes_exec_timeout: float = float(os.getenv("STT_HERMES_EXEC_TIMEOUT", "130"))


settings = Settings()
