import json
import os
import subprocess
import time
import urllib.request
from pathlib import Path

BASE = Path("/opt/ai-avatar-demo")
ART = BASE / "work" / "gate602_m4a_artifacts"
ART.mkdir(parents=True, exist_ok=True)

LLM_URL = "http://192.168.0.2:4000/v1/chat/completions"
LLM_MODEL = os.environ.get("M4A_LLM_MODEL", "gpt-4o-mini")


def call_litellm(text: str) -> tuple[str, str]:
    models = [LLM_MODEL, "gemma-4-heretic", "gpt-4o-mini"]
    seen = set()
    errors = []
    for model in models:
        if model in seen:
            continue
        seen.add(model)
        payload = {
            "model": model,
            "messages": [
                {"role": "system", "content": "Reply with exactly one short Traditional Chinese sentence. Do not return an empty response."},
                {"role": "user", "content": text},
            ],
            "max_tokens": 2048,
            "temperature": 0.2,
        }
        req = urllib.request.Request(
            LLM_URL,
            data=json.dumps(payload).encode("utf-8"),
            headers={"Content-Type": "application/json"},
            method="POST",
        )
        try:
            with urllib.request.urlopen(req, timeout=60) as resp:
                data = json.loads(resp.read().decode("utf-8"))
            content = data.get("choices", [{}])[0].get("message", {}).get("content", "")
            if content and content.strip():
                return model, content.strip()
            errors.append({"model": model, "error": "empty_content", "payload": data})
        except Exception as exc:
            body = ""
            if hasattr(exc, "read"):
                try:
                    body = exc.read().decode("utf-8", errors="replace")[:1000]
                except Exception:
                    body = ""
            errors.append({"model": model, "error": type(exc).__name__, "detail": str(exc), "body": body})
            print(f"M4A_LLM_MODEL_FAILED={model} {type(exc).__name__}: {exc}", flush=True)
    raise RuntimeError("LiteLLM failed for all tried models: " + json.dumps(errors, ensure_ascii=False)[:3000])


def find_tts_candidates():
    candidates = []
    roots = [BASE / "work", BASE / "services", BASE / "data" / "tts_outputs"]
    patterns = ["*tts*.py", "*qwen*tts*.py", "*gate7m*.py", "*synthesize*.py", "*.wav"]
    for root in roots:
        if not root.exists():
            continue
        for pattern in patterns:
            candidates.extend(str(path) for path in root.rglob(pattern) if ".env" not in path.parts)
    return sorted(set(candidates))


def write_tts_placeholder(ts: int, llm_text: str) -> Path:
    # M4A does not claim TTS synthesis here; the placeholder preserves the bridge artifact contract.
    placeholder = ART / f"m4a_tts_input_{ts}.txt"
    placeholder.write_text(llm_text, encoding="utf-8")
    return placeholder


def main():
    ts = int(time.time())
    stt_text = os.environ.get("M4A_TEST_STT_TEXT", "Mars 測試 M4A：請用一句自然中文回覆。")
    print(f"M4A_STT_TEXT={stt_text}", flush=True)
    print(f"M4A_LLM_MODEL_REQUESTED={LLM_MODEL}", flush=True)

    actual_model, llm_text = call_litellm(stt_text)
    print(f"M4A_LLM_MODEL_USED={actual_model}", flush=True)
    print(f"M4A_LLM_TEXT={llm_text}", flush=True)

    tts_candidates = find_tts_candidates()
    tts_input_path = write_tts_placeholder(ts, llm_text)
    print(f"M4A_TTS_INPUT_TEXT={tts_input_path}", flush=True)

    result = {
        "timestamp": ts,
        "stt_text": stt_text,
        "llm_model_requested": LLM_MODEL,
        "llm_model_used": actual_model,
        "llm_text": llm_text,
        "tts_candidates": tts_candidates[:80],
        "recommended_tts_callable_if_identified": "/opt/ai-avatar-demo/work/gate7m_a_qwen3_tts_customvoice_smoke.py",
        "tts_audio_path": None,
        "tts_status": "TTS_CALLABLE_IDENTIFIED_BUT_NOT_INVOKED_IN_M4A_MINIMAL_SKELETON",
        "livekit_status": "LIVEKIT_BINDING_PENDING; no active LiveKit server port found in recon",
    }
    out_json = ART / f"m4a_minimal_result_{ts}.json"
    out_json.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
    print(f"M4A_RESULT_JSON={out_json}", flush=True)
    print("M4A_MINIMAL_RUNNER_DONE", flush=True)


if __name__ == "__main__":
    main()
