#!/usr/bin/env python3
import speech_recognition as sr
import re
import tts
import subprocess
import os
from asterisk.agi import AGI
import anthropic
import json

agi = AGI()

class CallHandler:
    def __init__(self):
        self.audio_path = "/var/lib/asterisk/sounds/grabacion_usuario.wav"
        self.tab_id = self.get_tab_id()

    def get_tab_id(self):
        # Obtener el tab_id desde una variable de entorno AGI
        # Asegúrate de pasar esta variable desde el Dialplan
        tab_id = agi.env.get('TAB_ID', None)
        if not tab_id:
            agi.verbose("TAB_ID no fue proporcionado. Utilizando 'default_tab_id'.", 1)
            return 'default_tab_id'
        return tab_id

    def grabar_llamada(self):
        callerid = agi.env.get('agi_callerid', '')
        uniqueid = agi.env.get('agi_uniqueid', '')

        # Registrar la información de la llamada
        agi.verbose(f"CallerID: {callerid}", 1)
        agi.verbose(f"UniqueID: {uniqueid}", 1)

        # Iniciar la grabación
        agi.verbose("Iniciando grabación...", 1)
        try:
            result = agi.record_file(
                filename='/var/lib/asterisk/sounds/grabacion_usuario',
                format='wav',
                timeout=4000,  # Puedes ajustar el tiempo de espera según tus necesidades
                offset=0,
                beep=True,
                silence=0,
                escape_digits='#'
            )
        except Exception as e:
            agi.verbose(f"Error al grabar: {e}", 1)
        else:
            agi.verbose(f"Grabación completada. Resultado: {result}", 1)
            self.detectar_audio()

    def detectar_audio(self):
        recognizer = sr.Recognizer()

        with sr.AudioFile(self.audio_path) as source:
            audio_data = recognizer.record(source)
            try:
                text = recognizer.recognize_google(audio_data, language="es-ES")
                agi.verbose(f"La pregunta es: {text}", 1)

                # Llamar a la función consultar_claude con el texto reconocido
                respuesta = self.consultar_claude(text)
                ext = self.determine_extension(respuesta)

                cleaned_text = re.sub(r'^(?:\*+|\d+)', '', respuesta).strip()
                cleaned_text = cleaned_text.replace('%', '')

                # Reproducir la respuesta generada por Claude
                try:
                    tts.convert_text_to_speech(cleaned_text)
                    agi.stream_file('resp_claude')
                except Exception as e:
                    agi.verbose(f"Error al convertir texto a voz: {e}", 1)

                if ext is not None and ext != '':
                    try:
                        resultado_dial = agi.execute("EXEC Dial", f"Local/{str(ext)}@from-internal,20")
                        agi.verbose(f"Resultado del Dial: {resultado_dial}", 1)
                    except Exception as e:
                        agi.verbose(f"Error ejecutando Dial en AGI: {e}", 1)
                else:
                    agi.verbose("La variable ext no tiene un valor válido.", 1)
                    agi.stream_file('algomas')
                    # Volver a grabar si es necesario
                    self.grabar_llamada()
            except sr.RequestError as e:
                agi.verbose(f"Error al conectarse con el servicio de reconocimiento de voz: {e}", 1)
            except sr.UnknownValueError:
                agi.verbose("No se pudo entender el audio", 1)
                agi.stream_file('no_entendi')
                self.grabar_llamada()

    def determine_extension(self, input_str):
        # Definir la ruta al archivo de condiciones basado en tab_id
        conditions_file = f"/home/Flow_IA/IVR/tab_{self.tab_id}_conditions.json"

        if not os.path.exists(conditions_file):
            agi.verbose(f"No se encontró el archivo de condiciones para la pestaña {self.tab_id}", 1)
            return None

        try:
            with open(conditions_file, 'r', encoding='utf-8') as f:
                conditions_data = json.load(f)

            # Iterar sobre todas las condiciones de node3
            for node_cond in conditions_data.get('node3_conditions', []):
                for cond in node_cond.get('conditions', []):
                    condition_str = cond.get('condition_string', '').strip().lower()
                    target_id = cond.get('target_node_id', '').strip()
                    if input_str.lower() == condition_str:
                        agi.verbose(f"Condición encontrada: {condition_str} -> Extensión: {target_id}", 1)
                        return target_id

        except Exception as e:
            agi.verbose(f"Error al leer o procesar el archivo de condiciones: {e}", 1)

        # Si no se encuentra ninguna condición que coincida
        agi.verbose("No se encontró una condición que coincida con la entrada del usuario.", 1)
        return None

    def consultar_claude(self, text):
        # Leer extensiones (este comando parece específico para tu configuración)
        command = """grep -E '^\[|^callerid=' /etc/asterisk/pjsip.endpoint.conf | awk '{
            if ($0 ~ /^\[/) {
                gsub(/[\[\]]/, "", $1);
                ext = $1;
            } else if ($0 ~ /^callerid=/) {
                split($0, arr, "=");
                callerid = arr[2];
                printf "Extension: " ext ", CallerID: " callerid "; ";
            }
        }'"""

        result = subprocess.run(command, shell=True, capture_output=True, text=True)
        output = result.stdout.strip()

        # Crear el cliente Anthropic pasando la API key
        client = anthropic.Anthropic(api_key='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')

        message = client.messages.create(
            model="claude-3-5-haiku-20241022",
            #model = "claude-3-5-sonnet-20241022",
            max_tokens=200,
            temperature=0,
            system=(
                "Vas a ser un agente de telefonía con las siguientes condiciones: "
                f'"{output}"'
            ),
            messages=[
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": text
                        }
                    ]
                }
            ]
        )

        # Asumiendo que `message.content` es una lista de mensajes
        respuesta_claude = "".join([msg.get('text', '') for msg in message.content])
        respuesta_claude = respuesta_claude.replace('%', '')
        agi.verbose(f"Respuesta de Claude: {respuesta_claude}", 1)
        return respuesta_claude

if __name__ == "__main__":
    agi.answer()
    agi.stream_file('saludo_claude')
    call_handler = CallHandler()
    call_handler.grabar_llamada()