from datetime import datetime, timedelta
from sqlmodel import Session, create_engine
from app.models import EventData, Service, ServiceType, AvailabilityRule
from app.crud.assistant import filter_services
import json
from uuid import UUID
from app.services.vector_service import VectorService
from app.services.assistant_service import AssistantService
import asyncio
import time  # Añadido para medir tiempos

def test_with_real_data():
    # Configurar la conexión a la base de datos SQLite
    db_path = r'C:\Users\ensan\OneDrive\Documentos\EnginyeriaInformatica-UB\TFG\GITHUB\TFG\tfg_db.sqlite'
    DATABASE_URL = f"sqlite:///{db_path}"
    engine = create_engine(DATABASE_URL)
    
    with Session(engine) as session:
        # Crear datos de prueba
        event_data = EventData(
            name="Test Event",  # Nombre del evento
            tipus="Boda",      # Tipo de evento
            num_invitats=50,   # Número de invitados
            pressupost=5000.0, # Presupuesto en euros
            data_inici=datetime(2025, 7, 18, 12, 0, 0),  # Fecha de inicio
            data_fi=datetime(2025, 7, 18, 20, 0, 0),  # Fecha de fin
            espai_propi_id=None,  # ID del espacio propio (opcional)
            espai_propi={}  # Datos del espacio propio (opcional)
        )
        
        # Tipos de servicios a filtrar
        services_to_filter = ["catering", "musica", "fotografia", "mobiliario", "decoracion"]
        
        # Llamar al método
        result = filter_services(session, event_data, services_to_filter, True)
        
        # Imprimir resultados de forma legible
        print("\nResultados del filtrado:")
        print("=" * 50)
        for tipo, servicios in result.items():
            print(f"\n{tipo.upper()}:")
            print("-" * 30)
            if servicios:
                for servicio in servicios:
                    print(f"Nombre: {servicio.get('name', 'N/A')}")
                    print(f"Precio: {servicio.get('price', 'N/A')}€")
                    print(f"Descripción: {servicio.get('description', 'N/A')}")
                    print("-" * 30)
            else:
                print("No se encontraron servicios")
        
        # Guardar resultados en un archivo JSON
        with open('filter_results.json', 'w', encoding='utf-8') as f:
            json.dump(result, f, ensure_ascii=False, indent=2, default=str)
        print("\nResultados guardados en 'filter_results.json'")

    # Mensaje de ejemplo del usuario
    mensaje_usuario = "Planeamos una boda para 50 invitados y queremos que todo esté perfectamente organizado. Ofreceremos un menú de tapas catalanas para todos los asistentes, con platos tradicionales elaborados con ingredientes de proximidad, todo dentro de un presupuesto de 5000 €. Crearemos un ambiente acogedor y elegante con decoración basada en velas y detalles florales. Contrataremos un DJ especializado en música electrónica para animar a los 50 invitados hasta las 20:00. Además, dispondremos de un equipo profesional de fotografía y vídeo para capturar cada momento especial y preparar un vídeo resumen de 3 minutos. El mobiliario será sostenible y de estilo rústico, con elementos reciclados y detalles DIY que aportarán personalidad y ayudarán a optimizar los costes."

    # Instanciar el servicio de vectorización
    vector_service = VectorService()

    # Obtener los servicios más relevantes por tipo
    relevantes = vector_service.get_relevant_services(
        session=session,
        message=mensaje_usuario,
        filtered_services=result,
        k=3,  # Por ejemplo, los 3 más relevantes por tipo
        event_data=event_data
    )

    print("\nServicios más relevantes por tipo (vectorización):")
    print("=" * 50)
    for servicio in relevantes:
        print(f"ID: {servicio['id']}")
        print(f"Tipo: {servicio['category']}")
        print(f"Nombre: {servicio['name']}")
        print(f"Precio: {servicio['price']}€")
        print(f"Score: {servicio['relevance_score']:.4f}")
        print(f"Descripción: {servicio['description']}")
        print("-" * 30)

    # --- NUEVO: Llamada a la recomendación final con IA ---
    assistant_service = AssistantService()

    async def test_final_recommendation():
        prompt_message = mensaje_usuario
        recommendation, selected_services = await assistant_service.final_recommendation(
            session=session,
            event=event_data,
            services=relevantes,
            message=prompt_message,
            history=None
        )
        print("\n=== Recomendación final de la IA ===")
        print(recommendation)
        print("\nServicios seleccionados por la IA:")
        for s in selected_services:
            print(s)

    asyncio.run(test_final_recommendation())

def test_complete_assistant_flow():
    start_time = time.time()
    print("\nIniciando test completo del asistente...")
    
    # Configurar la conexión a la base de datos SQLite
    db_path = r'C:\Users\ensan\OneDrive\Documentos\EnginyeriaInformatica-UB\TFG\GITHUB\TFG\tfg_db.sqlite'
    DATABASE_URL = f"sqlite:///{db_path}"
    engine = create_engine(DATABASE_URL)
    
    with Session(engine) as session:
        # Crear datos de prueba
        event_data = EventData(
            name="Test Event",
            tipus="Boda",
            num_invitats=50,
            pressupost=8000.0,
            data_inici="2025-07-18T12:00:00",
            data_fi="2025-07-18T20:00:00",
            espai_propi_id=None,
            espai_propi={}
        )
        
        # Tipos de servicios a filtrar
        services_to_filter = ["catering", "musica", "fotografia", "mobiliario", "decoracion"]
        
        # Mensaje inicial del usuario
        initial_message = "Planeamos una boda para 50 invitados y queremos que todo esté perfectamente organizado. Ofreceremos un menú de tapas catalanas para todos los asistentes, con platos tradicionales elaborados con ingredientes de proximidad, todo dentro de un presupuesto de 8000 €. Crearemos un ambiente acogedor y elegante con decoración basada en velas y detalles florales. Contrataremos un DJ especializado en música electrónica para animar a los 50 invitados hasta las 20:00. Además, dispondremos de un equipo profesional de fotografía y vídeo para capturar cada momento especial y preparar un vídeo resumen de 3 minutos. El mobiliario será sostenible y de estilo rústico, con elementos reciclados y detalles DIY que aportarán personalidad y ayudarán a optimizar los costes."

        # Instanciar los servicios necesarios
        assistant_service = AssistantService()
        bedrock_service = assistant_service.bedrock_service
        vector_service = assistant_service.vector_service

        # Simular el flujo completo
        async def test_flow():
            # 1. Verificar si se necesita más información
            print("\n1. Verificando información necesaria...")
            check_start = time.time()
            needs_info, info_message = await assistant_service.check_info_needed(
                event=event_data,
                services=services_to_filter,
                message=initial_message,
                history=None
            )
            print(f"Tiempo de verificación: {time.time() - check_start:.2f} segundos")
            print(f"¿Necesita más información?: {needs_info}")
            print(f"Mensaje: {info_message}")
            
            if needs_info:
                # Simular respuesta del usuario a la pregunta
                follow_up_message = "Sí, queremos un DJ que toque música electrónica y house, y preferimos un catering tipo buffet con tapas catalanas."
                
                print("\n2. Verificando información adicional...")
                check_start = time.time()
                needs_info, info_message = await assistant_service.check_info_needed(
                    event=event_data,
                    services=services_to_filter,
                    message=follow_up_message,
                    history=[{"text": initial_message, "type": "user"}, {"text": info_message, "type": "assistant"}]
                )
                print(f"Tiempo de verificación adicional: {time.time() - check_start:.2f} segundos")
                print(f"¿Necesita más información?: {needs_info}")
                print(f"Mensaje: {info_message}")
            
            if not needs_info:
                # 2. Filtrado de servicios
                try:
                    print("\n3. Filtrando servicios...")
                    filter_start = time.time()
                    filtered_services = await assistant_service.filter_services(
                        session=session,
                        event=event_data,
                        services=services_to_filter,
                        get_filtered=True
                    )
                    print(f"Tiempo de filtrado: {time.time() - filter_start:.2f} segundos")
                    
                    print("\nServicios filtrados:")
                    for tipo, servicios in filtered_services.items():
                        print(f"\n{tipo.upper()}:")
                        for servicio in servicios:
                            print(f"- {servicio.get('name', 'N/A')} ({servicio.get('price', 'N/A')}€)")
                    
                    # 3. Vectorización y matching semántico
                    print("\n4. Realizando vectorización y matching...")
                    vector_start = time.time()
                    relevant_services = await assistant_service.vectorize_and_match(
                        session=session,
                        user_message=initial_message,
                        services=filtered_services,
                        event_data=event_data
                    )
                    print(f"Tiempo de vectorización: {time.time() - vector_start:.2f} segundos")
                    
                    print("\nServicios relevantes:")
                    for servicio in relevant_services:
                        print(f"- {servicio['category']}: {servicio['name']} (Score: {servicio['relevance_score']:.4f})")
                    
                    # 4. Recomendación final
                    print("\n5. Generando recomendación final...")
                    rec_start = time.time()
                    recommendation, selected_services = await assistant_service.final_recommendation(
                        session=session,
                        event=event_data,
                        services=relevant_services,
                        message=initial_message,
                        history=None
                    )
                    print(f"Tiempo de recomendación: {time.time() - rec_start:.2f} segundos")
                    
                    print("\nRecomendación final:")
                    print(recommendation)
                    print("\nServicios seleccionados:")
                    for s in selected_services:
                        print(f"- {s['category']}: {s['id']}")
                        
                except Exception as e:
                    print(f"\nError en el proceso: {str(e)}")

        # Ejecutar el test
        asyncio.run(test_flow())
        print(f"\nTiempo total de ejecución: {time.time() - start_time:.2f} segundos")

if __name__ == "__main__":
    test_complete_assistant_flow() 