import asyncio
from src.ApiKeys.openai_apikey import OpenAICredencial
from src.ApiKeys.openai_apikey_mmr import OpenAICredencialRepo
from src.ConexionSql.Postgres_conexion import PostgresConexion
from entrypoint.init_db import db_credencial
from src.ConexionApis.OpenAi_conexion import OpenAICliente
from src.Llms.Modelos.Openai_model import ModeloOpenAI
from src.Llms.Agente import AgenteAI
from src.Llms.Memory.postgres_MemoryConv import MemoryConvPostgres
from fastmcp.client.transports import StreamableHttpTransport
from fastmcp.client import Client
from src.Llms.MCPs.McpClient import MCPClient  # ya tienes esta clase
from src.Llms.MCPs.McpClient_Registry import ClientRegistry  # o ajusta según tu estructura
from src.Credenciales.ollama_credencial import OllamaCredencial
from src.ConexionApis.Ollama_cliente import OllamaCliente
from src.Llms.Modelos.Ollama_model import ModeloOllama
from src.Llms.MCPs.McpServer import MCPServerRunner

import asyncio


async def main():

    # # Usar Credencial openai

    conexion_admin = PostgresConexion(db_credencial)
    repo = OpenAICredencialRepo(conexion_admin)
    credencial_openai = repo.get_by_id("OPAK20250513-61b29978b7604031014")
    if credencial_openai is None:
        raise ValueError("No se encontró la credencial OpenAI con el ID proporcionado.")
    cliente = OpenAICliente(credencial_openai)


    # # Llamamos a los servidores para iniciarlos

    # venv_python = r"E:\Fitz_Studio\.venv\Scripts\python.exe"

    # # runner_math = MCPServerRunner(
    # #     r"E:\Fitz_Studio\src\Llms\MCPs\McpServers\server_math.py",
    # #     python_path=venv_python
    # # )
    # # runner_tools = MCPServerRunner(
    # #     r"E:\Fitz_Studio\src\Llms\MCPs\McpServers\server_utils.py",
    # #     python_path=venv_python
    # # )
    # runner_files = MCPServerRunner(
    #     r"E:\Fitz_Studio\src\Llms\MCPs\McpServers\server_files.py",
    #     python_path=venv_python
    # )


    # # await runner_math.start()
    # # await runner_tools.start()
    # await runner_files.start()

    # # Esperamos un poco para asegurarnos de que los servidores estén listos
    # await asyncio.sleep(2) 




    # Usar Credencial ollama
    # credencial_ollama = OllamaCredencial(titulo="Ollama")

    # cliente = OllamaCliente(credencial_ollama)

    # modelo = ModeloOllama(
    #     cliente=cliente,
    #     model="llama3.1:8b")
    


    # # crea el modelo (openai)

    modelo = ModeloOpenAI(
        cliente=cliente,
        model="gpt-4o",
        temperature=1
    )

    # Le otorga memoria 

    memoria = MemoryConvPostgres(
        credencial=db_credencial,
        nombre_tabla="memoria_conversacion_pruebas",
        k=10
    )


    # Cargamos las herramientas

    # herramientas = MCPClient.from_http(
    #     name="tools",
    #     url="http://127.0.0.1:4300/tools/"
    # )

    # math = MCPClient.from_http(
    #     name="math",
    #     url="http://127.0.0.1:4200/math/"
    # )

    archivos = MCPClient.from_http(
        name="files",
        url="http://127.0.0.1:4201/fs"
    )


    # Las añadimos al registro de herramientas

    registry = ClientRegistry()


    # registry.add("tools", herramientas)
    # registry.add("math", math)
    registry.add("files", archivos)


    # --- INICIALIZACIÓN DEL AGENTE ---
    agente2 = AgenteAI(
        modelo=modelo,
        nombre="Asistente Inteligente",
        descripcion="",
        system_prompt="",
        # system_prompt = """
        #     Eres un asistente general. No tienes acceso a herramientas externas ni herramientas MCP. No debes mencionar herramientas MCP, servidores ni bloques de código.
        #     Responde de forma clara y amigable a cualquier pregunta general del usuario.
        #     """.strip(),
        rol="asistente",
        objetivos=[
            # "Resolver tareas del usuario",
            # "Usar herramientas MCP si es útil",
            # "Responder de forma clara y útil"
        ],

        max_iterations=0,
        memoria=memoria,
        
        mcp=registry  # ← ✅ Integración del cliente MCP
    )


    # --- FUNCIÓN DE EJECUCIÓN ---
    async def probar_interaccion_stream():
        print("🧠 Agente iniciado. Escribe 'salir' para terminar.\n")

        while True:
            prompt = input("\n📝 Escribe tu pregunta: ")
            if prompt.strip().lower() in ("salir", "exit", "quit"):
                print("\n👋 Hasta pronto.")
                break

            print("\n💬 Respuesta en streaming:\n")
            respuesta_gen = await agente2.interactuar_en_bucle(
                prompt=prompt,
                stream=True
            )

            async for token in respuesta_gen:
                print(token, end="", flush=True)


    await probar_interaccion_stream()




# Ejecutar
if __name__ == "__main__":
    asyncio.run(main())

