#!/usr/bin/env python3
"""Quick local STT smoke test for microphone capture quality."""

from __future__ import annotations

import argparse
import sys
import tempfile
import time
from pathlib import Path
from typing import Any

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from app.services.voice_service import (
    listen_push_to_talk,
    probe_audio_input,
    select_stt_backend,
)


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description="STT smoke test (capture + transcript + wav dump)")
    parser.add_argument("--backend", choices=["auto", "whisper", "vosk", "google"], default="whisper")
    parser.add_argument("--whisper-model", default="small")
    parser.add_argument("--whisper-language", choices=["auto", "es", "en"], default="es")
    parser.add_argument("--whisper-beam-size", type=int, default=3)
    parser.add_argument("--whisper-vad-filter", choices=["on", "off"], default="on")
    parser.add_argument("--silence-seconds", type=float, default=1.2)
    parser.add_argument("--max-seconds", type=float, default=8.0)
    parser.add_argument("--mic-device", default=None)
    parser.add_argument("--mic-sample-rate", type=int, default=16000)
    parser.add_argument("--vosk-model-path", default=None)
    return parser


def main() -> int:
    args = build_parser().parse_args()
    selection = select_stt_backend(
        stt_backend=args.backend,
        vosk_model_path=args.vosk_model_path,
        whisper_model=args.whisper_model,
        whisper_language=args.whisper_language,
        whisper_beam_size=args.whisper_beam_size,
        whisper_vad_filter=args.whisper_vad_filter == "on",
        mic_device=args.mic_device,
        mic_sample_rate=max(int(args.mic_sample_rate), 8000),
        debug_audio=True,
    )
    provider = selection.provider
    probe = probe_audio_input(provider, selection.backend)
    print(
        f"[probe] backend={selection.backend} available={probe.available} "
        f"device={probe.device_name} index={probe.device_index} sr={probe.sample_rate} "
        f"channels={probe.channels} dtype={probe.dtype}",
        flush=True,
    )
    if not probe.available:
        print(f"[probe] error={probe.error}", flush=True)
        return 1

    levels: list[tuple[float, int]] = []

    def _on_level(sample: dict[str, Any]) -> None:
        levels.append((float(sample.get("rms") or 0.0), int(sample.get("peak") or 0)))

    started = time.monotonic()

    def _keep_listening() -> bool:
        return (time.monotonic() - started) < float(args.max_seconds)

    print("[capture] speak now...", flush=True)
    transcript = listen_push_to_talk(
        provider,
        keep_listening=_keep_listening,
        timeout=0.0,
        phrase_time_limit=float(args.max_seconds),
        end_silence_seconds=max(float(args.silence_seconds), 0.2),
        level_callback=_on_level,
    )
    elapsed = time.monotonic() - started

    level_rms_avg = (sum(item[0] for item in levels) / len(levels)) if levels else 0.0
    level_peak = max((item[1] for item in levels), default=0)
    capture_seconds = float(getattr(provider, "last_capture_audio_duration_seconds", 0.0) or 0.0)
    stt_seconds = float(getattr(provider, "last_transcription_duration_seconds", 0.0) or 0.0)

    wav_path: Path | None = None
    last_audio = getattr(provider, "last_audio_data", None)
    if last_audio is not None:
        with tempfile.NamedTemporaryFile(prefix="stt_smoke_", suffix=".wav", delete=False) as tmp_file:
            wav_path = Path(tmp_file.name)
            tmp_file.write(last_audio.get_wav_data())

    print(
        f"[metrics] elapsed={elapsed:.2f}s capture={capture_seconds:.2f}s stt={stt_seconds:.2f}s "
        f"rms_avg={level_rms_avg:.1f} peak={level_peak}",
        flush=True,
    )
    if wav_path is not None:
        print(f"[audio] wav={wav_path}", flush=True)
    print(f"[transcript] {transcript or '<empty>'}", flush=True)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
