"""Zentrale Konfiguration für den Plappi-MVP.

Alles über Umgebungsvariablen überschreibbar, damit derselbe Code
unverändert auf der VM (Handy-Client) und später auf dem Raspberry Pi läuft.
"""
from __future__ import annotations

import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent          # plappi-mvp/
DATA_DIR = BASE_DIR / "data"
AUDIO_DIR = DATA_DIR / "audio"                              # generierte TTS-Antworten
UPLOAD_DIR = DATA_DIR / "uploads"                           # eingehende Sprach-Clips
WEB_DIR = BASE_DIR / "clients" / "web"
BRAIN_CWD = BASE_DIR / ".brain-cwd"                         # neutrales cwd für die claude-CLI

for _d in (AUDIO_DIR, UPLOAD_DIR, BRAIN_CWD):
    _d.mkdir(parents=True, exist_ok=True)


def _load_dotenv() -> None:
    """Lädt plappi-mvp/.env (gitignored) in os.environ, ohne bestehende Werte zu überschreiben."""
    envf = BASE_DIR / ".env"
    if not envf.exists():
        return
    for line in envf.read_text(encoding="utf-8").splitlines():
        line = line.strip()
        if not line or line.startswith("#") or "=" not in line:
            continue
        k, v = line.split("=", 1)
        os.environ.setdefault(k.strip(), v.strip().strip('"').strip("'"))


_load_dotenv()


def _env(key: str, default: str) -> str:
    return os.environ.get(key, default)


# ── Sprachen ────────────────────────────────────────────────────────────────
# CHILD_LANG = Sprache, in der das Kind stark ist (Plappi spricht überwiegend so).
# TARGET_LANG = Sprache, die gelernt werden soll (Herkunfts-/Zielsprache).
CHILD_LANG = _env("PLAPPI_CHILD_LANG", "de")
TARGET_LANG = _env("PLAPPI_TARGET_LANG", "sr")

LANG_NAMES = {
    "de": "Deutsch", "sr": "Serbisch", "en": "Englisch", "hr": "Kroatisch",
    "tr": "Türkisch", "fr": "Französisch", "es": "Spanisch", "it": "Italienisch",
    "ru": "Russisch", "pl": "Polnisch", "ar": "Arabisch",
}

# ── ASR (whisper.cpp, lokal, kostenlos) ──────────────────────────────────────
WHISPER_CLI = _env("PLAPPI_WHISPER_CLI", "/home/agent/whisper.cpp/build/bin/whisper-cli")
WHISPER_MODEL = _env("PLAPPI_WHISPER_MODEL", "/home/agent/whisper.cpp/models/ggml-small.bin")
FFMPEG = _env("PLAPPI_FFMPEG", "ffmpeg")

# ── Dialog-Gehirn (heute claude-CLI, später private OSS-EU-Inferenz) ──────────
CLAUDE_CLI = _env("PLAPPI_CLAUDE_CLI", "/home/nk/.local/bin/claude")
DIALOG_MODEL = _env("PLAPPI_DIALOG_MODEL", "haiku")         # haiku = schnell/günstig für MVP
DIALOG_TIMEOUT = int(_env("PLAPPI_DIALOG_TIMEOUT", "45"))
HISTORY_TURNS = int(_env("PLAPPI_HISTORY_TURNS", "8"))      # wie viele letzte Turns ins Prompt

# ── TTS (edge-tts, kostenlos, neuronale Stimmen) ─────────────────────────────
# de-AT-IngridNeural = warme österr. Stimme; Multilingual-Stimmen können
# Code-Switching natürlicher (Iteration): de-DE-SeraphinaMultilingualNeural.
PLAPPI_VOICE = _env("PLAPPI_VOICE", "de-AT-IngridNeural")
PLAPPI_TTS_RATE = _env("PLAPPI_TTS_RATE", "-8%")           # etwas langsamer für Kinder
PLAPPI_TTS_PITCH = _env("PLAPPI_TTS_PITCH", "+0Hz")

SERVER_PORT = int(_env("PLAPPI_PORT", "8800"))

# ── ElevenLabs (Realtime/TTS Engine) ─────────────────────────────────────────
ELEVENLABS_API_KEY = _env("ELEVENLABS_API_KEY", "")
ELEVENLABS_VOICE_ID = _env("ELEVENLABS_VOICE_ID", "JBFqnCBsd6RMkjVDRZzb")  # Default-Multilingual-Voice
ELEVENLABS_MODEL = _env("ELEVENLABS_MODEL", "eleven_multilingual_v2")
ELEVENLABS_AGENT_ID = _env("ELEVENLABS_AGENT_ID", "")  # ConvAI Realtime-Agent (Widget)

# ── Wake-Word ("Plappi" → Piep → zuhören) ────────────────────────────────────
# Picovoice Porcupine läuft im Browser (WASM). Access-Key ist client-seitig
# (Picovoice-Modell) → darf an den Client. Ohne Key bleibt die App im
# Button-Modus (Push-to-Talk) — nichts bricht.
PICOVOICE_ACCESS_KEY = _env("PLAPPI_PICOVOICE_KEY", "")
WAKEWORD_LABEL = _env("PLAPPI_WAKEWORD", "Plappi")
# Stand-in: eingebautes Schlüsselwort, bis die custom "Plappi".ppn trainiert ist.
PICOVOICE_BUILTIN_KEYWORD = _env("PLAPPI_PV_BUILTIN", "Bumblebee")
PICOVOICE_KEYWORD_URL = _env("PLAPPI_PV_KEYWORD_URL", "")   # custom .ppn (Plappi) URL
PICOVOICE_MODEL_URL = _env("PLAPPI_PV_MODEL_URL", "")       # porcupine_params .pv (Sprachmodell)


# ── Lern-Engine (Mastery-Tracking + Spaced Repetition) ───────────────────────
# Aus der Forschungs-Spec (plappi-learning-engine, 2026-06-22). Alle Schwellen
# hier als benannte Konstanten für empirisches Pilot-Tuning.
EXPOSURES_FOR_RECEPTIVE = int(_env("PLAPPI_EXP_RECEPTIVE", "3"))
EXPOSURES_FOR_PRODUCTIVE_BASELINE = int(_env("PLAPPI_EXP_PRODUCTIVE", "10"))
WEIGHT_SPONTANEOUS = int(_env("PLAPPI_W_SPONTAN", "4"))
WEIGHT_PROMPTED = int(_env("PLAPPI_W_PROMPTED", "1"))
BOX_DAYS = [1, 3, 7, 15, 30, 60, 120, 240]          # Leitner-Intervalle (Tage)
MAX_EXPOSURES_PER_SESSION = int(_env("PLAPPI_MAX_EXP_SESSION", "3"))
MIN_GAP_SAME_CLUSTER_NEW = int(_env("PLAPPI_MIN_GAP_CLUSTER", "2"))
CONFIRMATION_REVIEW_DAYS = int(_env("PLAPPI_CONFIRM_REVIEW", "14"))
DISTINCT_SESSIONS_FOR_MASTERED = int(_env("PLAPPI_SESSIONS_MASTERED", "3"))
# claude-CLI-Modell für die Transkript-Bewertung (offline, pro Gespräch 1×).
LEARNING_MODEL = _env("PLAPPI_LEARNING_MODEL", "haiku")
LEARNING_TIMEOUT = int(_env("PLAPPI_LEARNING_TIMEOUT", "180"))


def client_config() -> dict:
    """Was der Browser-Client zum Start wissen muss (keine Server-Secrets außer dem
    bewusst client-seitigen Picovoice-Key)."""
    return {
        "wakeword_enabled": bool(PICOVOICE_ACCESS_KEY),
        "wakeword_label": WAKEWORD_LABEL,
        "picovoice_access_key": PICOVOICE_ACCESS_KEY,
        "picovoice_builtin_keyword": PICOVOICE_BUILTIN_KEYWORD,
        "picovoice_keyword_url": PICOVOICE_KEYWORD_URL,
        "picovoice_model_url": PICOVOICE_MODEL_URL,
        "child_lang": CHILD_LANG,
        "target_lang": TARGET_LANG,
    }


def lang_name(code: str) -> str:
    return LANG_NAMES.get(code, code)
