#!/usr/bin/env python3
import sys
import os
import json
import subprocess
import tempfile
import uuid

VOSK_PATH = "/tmp/whisper_env/lib/python3.13/site-packages"
MODEL_PATH = "/home/open/.cache/vosk/vosk-model-small-es-0.42"
CLAUDE_BIN = "/home/open/.local/bin/claude"
EDGE_TTS_BIN = "/home/open/.local/bin/edge-tts"
TTS_VOICE = "es-ES-XimenaNeural"
TMP_DIR = "/var/www/html/Carlos_proyect/cita_previa/tmp"

sys.path.insert(0, VOSK_PATH)

SYSTEM_PROMPT = """Eres Luna, la recepcionista virtual de este taller mecánico. Eres amable, eficiente y concisa.

SERVICIOS DISPONIBLES:
- Revisión general (1 hora)
- Cambio de aceite y filtros (30 min)
- Frenos (1 hora)
- Neumáticos (45 min)
- Diagnosis electrónica (1 hora)
- Climatización (2 horas)

HORARIO: Lunes a Viernes 8:00-14:00 y 16:00-19:00. Sábados 9:00-13:00. Domingos cerrado.

Para reservar necesitas: nombre, teléfono, servicio, fecha y hora. El vehículo es opcional.

Cuando tengas TODOS los datos de la reserva, incluye al final de tu respuesta exactamente este bloque (sin espacios extra):
[CITA:{"nombre":"...","telefono":"...","servicio":"...","fecha":"YYYY-MM-DD","hora":"HH:MM","vehiculo":"..."}]

Responde siempre en español. Máximo 2-3 frases por turno. No repitas información ya confirmada."""


def transcribir(audio_path):
    from vosk import Model, KaldiRecognizer
    import wave

    wav_path = audio_path.rsplit(".", 1)[0] + "_conv.wav"
    subprocess.run([
        "ffmpeg", "-y", "-i", audio_path,
        "-ar", "16000", "-ac", "1", "-f", "wav", wav_path
    ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    model = Model(MODEL_PATH)
    wf = wave.open(wav_path, "rb")
    rec = KaldiRecognizer(model, wf.getframerate())

    resultado = []
    while True:
        data = wf.readframes(4000)
        if len(data) == 0:
            break
        if rec.AcceptWaveform(data):
            r = json.loads(rec.Result())
            if r.get("text"):
                resultado.append(r["text"])

    r = json.loads(rec.FinalResult())
    if r.get("text"):
        resultado.append(r["text"])

    wf.close()
    if os.path.exists(wav_path):
        os.remove(wav_path)

    return " ".join(resultado).strip()


def llamar_claude(historial, mensaje_usuario):
    conversacion = ""
    for turno in historial:
        if turno["rol"] == "usuario":
            conversacion += f"Cliente: {turno['texto']}\n"
        else:
            conversacion += f"Luna: {turno['texto']}\n"

    prompt = f"{SYSTEM_PROMPT}\n\n"
    if conversacion:
        prompt += f"Conversación hasta ahora:\n{conversacion}\n"
    prompt += f"Cliente: {mensaje_usuario}\nLuna:"

    resultado = subprocess.run(
        [CLAUDE_BIN, "-p", prompt, "--output-format", "text"],
        capture_output=True, text=True, timeout=30,
        env={**os.environ, "HOME": "/home/open"}
    )
    return resultado.stdout.strip()


def generar_tts(texto, output_path):
    texto_limpio = texto
    if "[CITA:" in texto:
        texto_limpio = texto[:texto.index("[CITA:")].strip()

    subprocess.run([
        EDGE_TTS_BIN,
        "--voice", TTS_VOICE,
        "--text", texto_limpio,
        "--write-media", output_path
    ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)


def extraer_cita(texto):
    if "[CITA:" not in texto:
        return None
    try:
        inicio = texto.index("[CITA:") + 6
        fin = texto.index("]", inicio)
        return json.loads(texto[inicio:fin])
    except Exception:
        return None


def main():
    data = json.loads(sys.stdin.read())
    audio_path = data.get("audio_path", "")
    historial = data.get("historial", [])

    transcript = transcribir(audio_path)
    if not transcript:
        transcript = "..."

    respuesta = llamar_claude(historial, transcript)

    tts_filename = f"resp_{uuid.uuid4().hex[:8]}.mp3"
    tts_path = os.path.join(TMP_DIR, tts_filename)
    generar_tts(respuesta, tts_path)

    cita = extraer_cita(respuesta)
    respuesta_limpia = respuesta
    if "[CITA:" in respuesta:
        respuesta_limpia = respuesta[:respuesta.index("[CITA:")].strip()

    print(json.dumps({
        "transcript": transcript,
        "respuesta": respuesta_limpia,
        "tts_url": f"/cita_previa/tmp/{tts_filename}",
        "cita": cita
    }, ensure_ascii=False))


if __name__ == "__main__":
    main()
