#!/usr/bin/env python3
"""Synthesize Eve voice (xAI TTS voice_id=eve) for the phone desk.

Writes state/latest_reply.mp3 — same voice as Kitty eve-speak.
Usage: desk_eve_voice.py 'text to speak'
       desk_eve_voice.py --file path.txt
"""
from __future__ import annotations

import json
import os
import sys
import urllib.error
import urllib.request
from pathlib import Path

ROOT = Path(__file__).resolve().parent
STATE = ROOT / "state"
OUT = STATE / "latest_reply.mp3"
TTS_URL = "https://api.x.ai/v1/tts"
AUTH = Path.home() / ".grok/auth.json"
XAI_ENV = Path.home() / ".config/eve/xai.env"
SPEAK_CONF = Path.home() / ".config/eve/speak.conf"


def token() -> str:
    env = os.environ.get("XAI_API_KEY") or os.environ.get("GROK_API_KEY")
    if env:
        return env.strip()
    if XAI_ENV.exists():
        for line in XAI_ENV.read_text(encoding="utf-8", errors="replace").splitlines():
            line = line.strip()
            if not line or line.startswith("#") or "=" not in line:
                continue
            k, v = line.split("=", 1)
            if k.strip() in {"XAI_API_KEY", "GROK_API_KEY"}:
                return v.strip().strip('"').strip("'")
    data = json.loads(AUTH.read_text())
    for v in data.values():
        if isinstance(v, dict) and v.get("key"):
            return str(v["key"])
    raise SystemExit("No XAI API key for Eve TTS")


def speed() -> float:
    if SPEAK_CONF.exists():
        for line in SPEAK_CONF.read_text(encoding="utf-8", errors="replace").splitlines():
            if line.strip().startswith("speed="):
                try:
                    return float(line.split("=", 1)[1].strip())
                except ValueError:
                    pass
    return 1.3


def synthesize(text: str) -> Path:
    text = " ".join(text.split()).strip()
    if not text:
        raise SystemExit("empty text")
    if len(text) > 14000:
        text = text[:13900].rsplit(" ", 1)[0] + "."
    body = json.dumps(
        {
            "text": text,
            "voice_id": "eve",
            "language": "en",
            "speed": speed(),
        }
    ).encode()
    req = urllib.request.Request(
        TTS_URL,
        data=body,
        headers={
            "Authorization": f"Bearer {token()}",
            "Content-Type": "application/json",
        },
        method="POST",
    )
    with urllib.request.urlopen(req, timeout=90) as resp:
        audio = resp.read()
    if len(audio) < 200:
        raise SystemExit("Eve TTS returned empty audio")
    STATE.mkdir(parents=True, exist_ok=True)
    OUT.write_bytes(audio)
    return OUT


def main() -> None:
    args = sys.argv[1:]
    if args and args[0] == "--file":
        text = Path(args[1]).read_text(encoding="utf-8")
    else:
        text = " ".join(args).strip() or sys.stdin.read()
    path = synthesize(text)
    print(json.dumps({"ok": True, "path": str(path), "bytes": path.stat().st_size}))


if __name__ == "__main__":
    try:
        main()
    except urllib.error.HTTPError as e:
        err = e.read().decode("utf-8", "replace")[:400]
        print(f"Eve TTS HTTP {e.code}: {err}", file=sys.stderr)
        sys.exit(1)
