"""Spracherkennung – Alexa-Style: „Jam“ als Wake-Word + kurze Folge-Session."""

from __future__ import annotations

import re
import threading
from typing import Callable

from jam.game_launcher import normalize_speech
from jam.voice_assistant import (
    in_conversation_session,
    mentions_wake,
    touch_conversation_session,
)

_running = False

# Alexa-Ersatz: auch „Alexa“ wird zu Jam (STT-Fehler)
_WAKE_RE = re.compile(
    r"\b(jam|jem|jahm|germ|yam|alexa)\b",
    re.I,
)


def _should_wake(text: str) -> bool:
    if mentions_wake(text):
        return True
    # Zimmer / raus – auch ohne „Jam“
    try:
        from jam import room

        if room.hears_go_room(text) or room.hears_come_out(text):
            return True
    except Exception:
        pass
    # Folgefrage ohne „Jam“ (wie bei Alexa nach der Antwort)
    if in_conversation_session() and text.strip():
        return True
    return False


def start_listener(on_wake: Callable[[str], None], on_error: Callable[[str], None] | None = None) -> bool:
    global _running
    if _running:
        return True
    try:
        import speech_recognition as sr
    except ImportError:
        if on_error:
            on_error("SpeechRecognition nicht installiert.")
        return False

    def loop() -> None:
        global _running
        rec = sr.Recognizer()
        rec.dynamic_energy_threshold = True
        rec.pause_threshold = 0.65
        try:
            mic = sr.Microphone()
        except (OSError, AttributeError) as e:
            _running = False
            if on_error:
                on_error(f"Mikrofon optional nicht aktiv: {e}")
            return
        _running = True

        with mic:
            rec.adjust_for_ambient_noise(mic, duration=0.6)
            while _running:
                try:
                    audio = rec.listen(mic, timeout=4, phrase_time_limit=11)
                    raw = rec.recognize_google(audio, language="de-DE")
                    text = normalize_speech(raw)
                    if _should_wake(text):
                        touch_conversation_session()
                        on_wake(text)
                except sr.WaitTimeoutError:
                    continue
                except sr.UnknownValueError:
                    continue
                except Exception as e:
                    if on_error and "jam" in str(e).lower():
                        on_error(str(e))
                    continue

    threading.Thread(target=loop, daemon=True).start()
    return True


def stop_listener() -> None:
    global _running
    _running = False
