"""ASR (Spracherkennung) via whisper.cpp — lokal, kostenlos, offline-fähig.

Nimmt eine beliebige Audiodatei (webm/ogg/wav vom Browser), normalisiert sie
per ffmpeg auf 16 kHz Mono WAV und transkribiert sie. Gibt Text + erkannte
Sprache zurück.
"""
from __future__ import annotations

import os
import re
import subprocess
import tempfile
from pathlib import Path
from typing import Tuple

from . import config

_THREADS = str(max(4, os.cpu_count() or 4))   # alle Kerne nutzen (whisper laeuft sequenziell vor dem Dialog)

_LANG_RE = re.compile(r"auto-detected language:\s*([a-z]{2})", re.IGNORECASE)


def _to_wav16k(src: Path) -> Path:
    dst = src.with_suffix(".16k.wav")
    subprocess.run(
        [config.FFMPEG, "-nostdin", "-y", "-i", str(src),
         "-ar", "16000", "-ac", "1", "-f", "wav", str(dst)],
        capture_output=True, text=True, timeout=60,
    )
    return dst


def transcribe(audio_path: str | Path) -> Tuple[str, str]:
    """-> (text, language_code). Leerer Text wenn nichts erkannt."""
    src = Path(audio_path)
    wav = _to_wav16k(src)
    if not wav.exists() or wav.stat().st_size < 200:
        return "", config.CHILD_LANG

    with tempfile.TemporaryDirectory() as td:
        out_base = Path(td) / "out"
        proc = subprocess.run(
            [config.WHISPER_CLI, "-m", config.WHISPER_MODEL,
             "-f", str(wav), "-l", "auto", "-nt", "-otxt", "-of", str(out_base),
             "-t", _THREADS, "-bo", "1", "-bs", "1"],   # auto = de UND sr (Kind spricht beides) — echte Lösung ist S2S
            capture_output=True, text=True, timeout=120,
        )
        txt_file = out_base.with_suffix(".txt")
        text = txt_file.read_text(encoding="utf-8").strip() if txt_file.exists() else ""

    lang_match = _LANG_RE.search(proc.stderr or "")
    lang = lang_match.group(1).lower() if lang_match else config.CHILD_LANG

    # whisper halluziniert auf Stille gern Standardphrasen -> rausfiltern
    cleaned = text.strip()
    low = cleaned.lower()
    if low in {"", "you", "thank you.", "thanks for watching!", "[blank_audio]", "."}:
        cleaned = ""
    return cleaned, lang
