from typing import List
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
from app.crud import assistant as crud_assistant
from app.crud import event_service as crud_event_service
from app.models import EventData
from datetime import timedelta


class VectorService:
    def __init__(self, session = None):
 
        # Ejemplo de pruebas iniciales para el vector service

        self.services = {
            "Espai": {
                "Masia del Sola": {"espai_type": "Masia", "capacitat_min": 6, "capacitat_max": 100, "price": 100, "description": "Masia con jardín, parking y producto casolano", "caracteristicas": ["jardín", "parking", "producto de calidad", "interior", "exterior"]},
                "Urbisol": {" espai_type": "Masia", "capacitat_min": 10, "capacitat_max": 150, "price": 130, "description": "Masía moderna con piscina y área de eventos", "caracteristicas": ["piscina", "moderno", "zona eventos"]},
                "La Torre Roja": {" espai_type": "Castillo", "capacitat_min": 20, "capacitat_max": 300, "price": 500, "description": "Castillo medieval ideal para bodas temáticas", "caracteristicas": ["histórico", "temático", "vistas panorámicas"]},
                "El Jardí de les Flors": {" espai_type": "Jardín", "capacitat_min": 5, "capacitat_max": 80, "price": 200, "description": "Espacio floral perfecto para ceremonias íntimas", "caracteristicas": ["floral", "intimidad", "romántico"]},
                "Mas de la Serra": {" espai_type": "Masia", "capacitat_min": 15, "capacitat_max": 120, "price": 170, "description": "Masía rústica rodeada de naturaleza", "caracteristicas": ["rústico", "naturaleza", "acogedor"]},
                "Can Miró": {" espai_type": "Casa Rural", "capacitat_min": 8, "capacitat_max": 60, "price": 90, "description": "Casa rural con encanto tradicional", "caracteristicas": ["tradicional", "chimenea", "terraza"]},
                "Finca del Sol": {" espai_type": "Finca", "capacitat_min": 20, "capacitat_max": 200, "price": 300, "description": "Finca con amplios exteriores para grandes celebraciones", "caracteristicas": ["grandes espacios", "exterior", "privacidad"]},
                "El Molino Viejo": {" espai_type": "Molino", "capacitat_min": 10, "capacitat_max": 70, "price": 150, "description": "Antiguo molino restaurado", "caracteristicas": ["histórico", "restaurado", "acogedor"]},
                "Villa Roma": {" espai_type": "Villa", "capacitat_min": 12, "capacitat_max": 90, "price": 220, "description": "Villa mediterránea moderna", "caracteristicas": ["moderno", "piscina", "costa"]},
                "Can Figueres": {" espai_type": "Masia", "capacitat_min": 18, "capacitat_max": 140, "price": 180, "description": "Masía señorial para eventos premium", "caracteristicas": ["premium", "jardines", "historia"]},
                "Jardines del Eden": {" espai_type": "Jardín", "capacitat_min": 5, "capacitat_max": 60, "price": 250, "description": "Jardín tropical para ceremonias", "caracteristicas": ["tropical", "romántico", "único"]},
                "La Hacienda": {" espai_type": "Hacienda", "capacitat_min": 25, "capacitat_max": 400, "price": 600, "description": "Hacienda andaluza tradicional", "caracteristicas": ["andaluz", "grandes salones", "patio"]},
                "El Prado Verde": {" espai_type": "Finca", "capacitat_min": 10, "capacitat_max": 200, "price": 280, "description": "Finca verde para eventos corporativos", "caracteristicas": ["corporativo", "flexible", "natural"]},
                "La Cúpula": {" espai_type": "Espacio Singular", "capacitat_min": 30, "capacitat_max": 350, "price": 700, "description": "Espacio singular con cúpula de cristal", "caracteristicas": ["cúpula", "cristal", "espectacular"]},
                "Castell d'Or": {" espai_type": "Castillo", "capacitat_min": 50, "capacitat_max": 500, "price": 900, "description": "Castillo dorado para bodas de lujo", "caracteristicas": ["lujo", "historia", "exclusivo"]},
                "Can Puig": {" espai_type": "Masia", "capacitat_min": 14, "capacitat_max": 110, "price": 160, "description": "Masía acogedora entre viñedos", "caracteristicas": ["viñedos", "acogedor", "tradicional"]},
                "Villa Azul": {" espai_type": "Villa", "capacitat_min": 20, "capacitat_max": 180, "price": 320, "description": "Villa azul junto al mar", "caracteristicas": ["mar", "piscina", "privacidad"]},
                "El Bosque Encantado": {" espai_type": "Bosque", "capacitat_min": 10, "capacitat_max": 100, "price": 270, "description": "Espacio en bosque natural para bodas mágicas", "caracteristicas": ["natural", "mágico", "bosque"]},
                "Palacio del Río": {" espai_type": "Palacio", "capacitat_min": 40, "capacitat_max": 600, "price": 1200, "description": "Palacio clásico junto al río", "caracteristicas": ["clásico", "río", "glamour"]},
                "Can Gaspar": {" espai_type": "Masia", "capacitat_min": 16, "capacitat_max": 130, "price": 190, "description": "Masía tradicional catalana", "caracteristicas": ["tradicional", "interior", "exterior"]}
            },
            "Catering": {
                "Delicious Catering": {"catering_type": "Buffet", "price_per_person": 50, "min_guests": 20, "max_guests": 200, "menu_options": ["Internacional", "Vegetariana", "Vegana"], "description": "Buffet de alta calidad con opciones internacionales, vegetarianas y veganas."},
                "Gourmet Events": {"catering_type": "Servicio en mesa", "price_per_person": 70, "min_guests": 30, "max_guests": 150, "menu_options": ["Gourmet", "Mariscos"], "description": "Servicio de catering gourmet especializado en mariscos y platos de alta cocina."},
                "Urban Bites": {"catering_type": "Finger Food","price_per_person": 35, "min_guests": 15, "max_guests": 100, "menu_options": ["Tapas", "Street Food"], "description": "Propuesta informal y moderna de tapas y street food para eventos."},
                "Tradition Catering": {"catering_type": "Buffet","price_per_person": 45, "min_guests": 25, "max_guests": 250, "menu_options": ["Mediterránea", "Casera"], "description": "Cocina mediterránea tradicional servida en buffet."},
                "Green Leaf": {"catering_type": "Servicio en mesa", "price_per_person": 55, "min_guests": 20, "max_guests": 120, "menu_options": ["Vegana", "Vegetariana"], "description": "Catering 100% vegetal, sostenible y delicioso."},
                "Fiesta Food": {"catering_type": "Buffet","price_per_person": 40, "min_guests": 30, "max_guests": 300, "menu_options": ["Tex-Mex", "Internacional"], "description": "Buffet festivo con comida internacional y tex-mex."},
                "Sabor del Sur": {"catering_type": "Servicio en mesa","price_per_person": 60,"min_guests": 40,"max_guests": 200,"menu_options": ["Andaluza", "Mediterránea"],"description": "Sabores auténticos del sur de España servidos en mesa."},
                "Exquisite Bites": {"catering_type": "Finger Food","price_per_person": 38,"min_guests": 10,"max_guests": 80,"menu_options": ["Tapas gourmet", "Street Food"],"description": "Pequeños bocados gourmet para eventos exclusivos."},
                "Veggie Delight": {"catering_type": "Buffet","price_per_person": 48,"min_guests": 20,"max_guests": 180,"menu_options": ["Vegetariana", "Vegana"],"description": "Buffet 100% vegetariano y vegano."},
                "Chef's Table": {"catering_type": "Servicio en mesa","price_per_person": 80,"min_guests": 50,"max_guests": 120,"menu_options": ["Alta cocina", "Maridajes"],"description": "Experiencia culinaria de alta cocina en tu evento."},
                "Mar i Terra": {"catering_type": "Buffet","price_per_person": 60,"min_guests": 20,"max_guests": 200,"menu_options": ["Mariscos", "Mediterránea"],"description": "Especialidad en mariscos y cocina mediterránea."},
                "Sweet Moments": {"catering_type": "Finger Food", "price_per_person": 30, "min_guests": 15, "max_guests": 100, "menu_options": ["Postres", "Cupcakes"], "description": "Dulces artesanales para eventos inolvidables."},
                "Organic Feast": {"catering_type": "Buffet", "price_per_person": 52, "min_guests": 25, "max_guests": 180, "menu_options": ["Ecológica", "Sostenible"], "description": "Buffet orgánico y sostenible de alta calidad."},
                "La Paella Real": {"catering_type": "Servicio en mesa","price_per_person": 65,"min_guests": 30,"max_guests": 150,"menu_options": ["Paellas", "Mediterránea"],"description": "Auténticas paellas y platos mediterráneos servidos en tu evento."},
                "Puro Sabor": {"catering_type": "Buffet", "price_per_person": 42, "min_guests": 20, "max_guests": 250, "menu_options": ["Latina", "Internacional"], "description": "Cocina latina e internacional para eventos dinámicos."},
                "Fusion Gourmet": {"catering_type": "Servicio en mesa", "price_per_person": 75, "min_guests": 40, "max_guests": 120, "menu_options": ["Fusión", "Internacional"], "description": "Propuesta innovadora de cocina de fusión."},
                "Rustic Kitchen": {"catering_type": "Buffet", "price_per_person": 47, "min_guests": 30, "max_guests": 220, "menu_options": ["Tradicional", "Mediterránea"], "description": "Buffet rústico con platos tradicionales y de temporada."},
                "Asian Flavors": {"catering_type": "Finger Food", "price_per_person": 40, "min_guests": 20, "max_guests": 90, "menu_options": ["Asiática", "Internacional"], "description": "Pequeñas delicias de la cocina asiática."},
                "Luxury Banquet": {"catering_type": "Servicio en mesa", "price_per_person": 90, "min_guests": 60, "max_guests": 200, "menu_options": ["Alta cocina", "Gourmet"], "description": "Banquetes de lujo para eventos premium."},
                "Taco Time": {"catering_type": "Buffet", "price_per_person": 35, "min_guests": 20, "max_guests": 150, "menu_options": ["Mexicana", "Street Food"], "description": "Tacos y comida mexicana para fiestas divertidas."},
                "Gourmet Catering": {"catering_type": "Gourmet", "price_per_person": 50, "min_guests": 10, "max_guests": 200, "menu_options": ["vegetariano", "carnívoro", "vegano", "sin gluten"], "description": "Gourmet Catering"},
                "La Cuina de Maria": {"catering_type": "Casero", "price_per_person": 35, "min_guests": 20, "max_guests": 150, "menu_options": ["casero", "típico local", "sin gluten"], "description": "La Cuina de Maria"},
                "Chef Gourmet": {"catering_type": "Alta Cocina", "price_per_person": 75, "min_guests": 15, "max_guests": 100, "menu_options": ["gourmet", "fusión", "vegano"], "description": "Chef Gourmet"},
                "Sabor a Ti": {"catering_type": "Internacional", "price_per_person": 55, "min_guests": 30, "max_guests": 250, "menu_options": ["internacional", "vegetariano", "sin gluten"], "description": "Sabor a Ti"},
                "Delicious Catering": {"catering_type": "Buffet", "price_per_person": 40, "min_guests": 50, "max_guests": 500, "menu_options": ["buffet libre", "barbacoa", "ensaladas"], "description": "Delicious Catering"},
                "EcoFriendly Food": {"catering_type": "Orgánico", "price_per_person": 60, "min_guests": 10, "max_guests": 120, "menu_options": ["orgánico", "vegano", "vegetariano"], "description": "EcoFriendly Food"},
                "Paellas Gigantes": {"catering_type": "Especializado", "price_per_person": 45, "min_guests": 40, "max_guests": 400, "menu_options": ["paellas", "fideuá", "arroces"], "description": "Paellas Gigantes"},
                "Tapas y Más": {"catering_type": "Tapas", "price_per_person": 35, "min_guests": 20, "max_guests": 180, "menu_options": ["tapas españolas", "pinchos", "montaditos"], "description": "Tapas y Más"},
                "Sweet Events": {"catering_type": "Repostería", "price_per_person": 25, "min_guests": 30, "max_guests": 300, "menu_options": ["postres", "pasteles", "mesas dulces"], "description": "Sweet Events"},
                "Vegan Delights": {"catering_type": "Vegano", "price_per_person": 50, "min_guests": 15, "max_guests": 100, "menu_options": ["vegano", "plant based"], "description": "Vegan Delights"},
                "Carnes Premium": {"catering_type": "Asados", "price_per_person": 65, "min_guests": 25, "max_guests": 200, "menu_options": ["carnes a la brasa", "asados argentinos"], "description": "Carnes Premium"},
                "Mediterranean Taste": {"catering_type": "Mediterráneo", "price_per_person": 55, "min_guests": 30, "max_guests": 250, "menu_options": ["ensaladas", "pescados", "cocina mediterránea"], "description": "Mediterranean Taste"},
                "Asia Fusion": {"catering_type": "Asiático", "price_per_person": 60, "min_guests": 20, "max_guests": 150, "menu_options": ["sushi", "wok", "currys"], "description": "Asia Fusion"},
                "La Brasería": {"catering_type": "Barbacoa", "price_per_person": 45, "min_guests": 30, "max_guests": 300, "menu_options": ["barbacoa", "costillas", "hamburguesas"], "description": "La Brasería"},
                "Luxury Banquets": {"catering_type": "Banquetes", "price_per_person": 90, "min_guests": 50, "max_guests": 500, "menu_options": ["cócteles", "banquetes de lujo"], "description": "Luxury Banquets"},
                "Fast Catering": {"catering_type": "Rápido", "price_per_person": 20, "min_guests": 20, "max_guests": 300, "menu_options": ["bocadillos", "snacks"], "description": "Fast Catering"},
                "Casa Rural Catering": {"catering_type": "Casero", "price_per_person": 30, "min_guests": 10, "max_guests": 100, "menu_options": ["comida tradicional", "productos locales"], "description": "Casa Rural Catering"},
                "Fiesta Mexicana": {"catering_type": "Mexicano", "price_per_person": 40, "min_guests": 25, "max_guests": 250, "menu_options": ["tacos", "nachos", "enchiladas"], "description": "Fiesta Mexicana"},
                "Brunch & Co": {"catering_type": "Brunch", "price_per_person": 35, "min_guests": 20, "max_guests": 150, "menu_options": ["brunch", "desayunos gourmet"], "description": "Brunch & Co"},
                "Sabores del Mundo": {"catering_type": "Internacional", "price_per_person": 65, "min_guests": 30, "max_guests": 400, "menu_options": ["fusión", "cocina mundial"], "description": "Sabores del Mundo"},
            },
            "Mobiliari": {
                "Sillas Elegantes": {"mobiliari_type": "Silla", "materials": ["Madera", "Cuero"], "price": 10, "description": "Sillas de alta calidad para eventos elegantes.", "colors": ["Negro", "Blanco"]},
                "Mesas Imperiales": {"mobiliari_type": "Mesa", "materials": ["Madera maciza"], "price": 25, "description": "Mesas largas para banquetes y eventos.", "colors": ["Madera natural", "Blanco"]},
                "Sofás Chill Out": {"mobiliari_type": "Sofá", "materials": ["Tela", "Espuma"], "price": 50, "description": "Sofás cómodos para zonas lounge.", "colors": ["Beige", "Gris"]},
                "Taburetes Modernos": {"mobiliari_type": "Taburete", "materials": ["Metal", "Cuero sintético"], "price": 15, "description": "Taburetes altos para barras y cócteles.", "colors": ["Negro", "Rojo"]},
                "Taburetes Modernos": {"mobiliari_type": "Taburete", "materials": ["Metal", "Cuero sintético"], "price": 15, "description": "Taburetes altos para barras y cócteles.", "colors": ["Negro", "Rojo"]},
                "Barras de Bar": {"mobiliari_type": "Barra", "materials": ["Madera", "Cristal"], "price": 120, "description": "Barras móviles para eventos.", "colors": ["Madera", "Transparente"]},
                "Carpas Blancas": {"mobiliari_type": "Carpa", "materials": ["Tela", "Aluminio"], "price": 200, "description": "Carpas para exteriores con resistencia al clima.", "colors": ["Blanco"]},
                "Toldos para Bodas": {"mobiliari_type": "Toldo", "materials": ["Tela impermeable"], "price": 180, "description": "Toldos románticos para ceremonias.", "colors": ["Blanco", "Beige"]},
                "Puffs Chill Out": {"mobiliari_type": "Puff", "materials": ["Tela", "Espuma"], "price": 20, "description": "Puffs coloridos para zonas informales.", "colors": ["Azul", "Verde", "Rosa"]},
                "Escenarios Modulares": {"mobiliari_type": "Escenario", "materials": ["Metal", "Madera"], "price": 300, "description": "Escenarios desmontables para conciertos y ceremonias.", "colors": ["Negro"]},
                "Tartanas Vintage": {"mobiliari_type": "Tartana", "materials": ["Madera", "Hierro"], "price": 150, "description": "Tartanas de estilo vintage para decoración.", "colors": ["Madera", "Verde"]},
            },
            "Decoració": {
                "Centros de Mesa Florales": {"decoracio_type": "Centro de Mesa", "themes": ["Romántico", "Bohemio"], "price": 30, "description": "Arreglos florales frescos para mesas."},
                "Arcos de Boda": {"decoracio_type": "Arco", "themes": ["Clásico", "Rústico"], "price": 100, "description": "Arcos decorativos para ceremonias de boda."},
                "Guirnaldas de Luces": {"decoracio_type": "Iluminación", "themes": ["Vintage", "Fiesta"], "price": 50, "description": "Guirnaldas de luces LED para ambientar eventos."},
                "Alfombras Rojas": {"decoracio_type": "Alfombra", "themes": ["Gala", "Formal"], "price": 80, "description": "Alfombras elegantes para entradas y ceremonias."},
                "Photocalls Temáticos": {"decoracio_type": "Photocall", "themes": ["Hollywood", "Vintage"], "price": 200, "description": "Fondos personalizables para fotos en eventos."},
                "Cortinas de Luces": {"decoracio_type": "Iluminación", "themes": ["Romántico", "Navideño"], "price": 70, "description": "Cortinas de luces LED para paredes o fondos."},
                "Farolillos Colgantes": {"decoracio_type": "Iluminación", "themes": ["Bohemio", "Asiático"], "price": 60, "description": "Farolillos de papel y luz para decoraciones aéreas."},
                "Velas Aromáticas": {"decoracio_type": "Velas", "themes": ["Romántico", "Relajante"], "price": 40, "description": "Velas decorativas para ambientes íntimos."},
                "Caminos de Mesa de Encaje": {"decoracio_type": "Camino de Mesa", "themes": ["Vintage", "Romántico"], "price": 20, "description": "Caminos de encaje elegantes para mesas de banquete."},
                "Señalización de Madera": {"decoracio_type": "Señalización", "themes": ["Rústico", "Bohemio"], "price": 35, "description": "Carteles de madera personalizados para eventos."},
            },
            "Musica": {
                "DJ Destor": {"musica_type": "DJ", "genres": ["Electrónica", "House", "Techno"], "price": 400, "description": "DJ con experiencia internacional y mezclas en vivo."},
                "Jazz Quartet Barcelona": {"musica_type": "Grupo", "genres": ["Jazz", "Swing"], "price": 700, "description": "Cuarteto profesional especializado en jazz ambiental."},
                "Orquesta Fiesta Show": {"musica_type": "Orquesta", "genres": ["Pop", "Rock", "Latino"], "price": 1200, "description": "Orquesta versátil con animación en vivo y repertorio variado."},
                "Violinista Clásica": {"musica_type": "Instrumental", "genres": ["Clásica", "Romántica"], "price": 300, "description": "Música de violín para ceremonias y eventos elegantes."},
                "DJ Urban Beat": {"musica_type": "DJ", "genres": ["Reggaetón", "Trap", "Hip-Hop"], "price": 500, "description": "DJ urbano con estilo moderno y mezclas de moda."},
                "Grupo Flamenco Alma": {"musica_type": "Grupo", "genres": ["Flamenco"], "price": 800, "description": "Grupo de flamenco auténtico con cante, guitarra y baile."},
                "Banda Tributo Queen": {"musica_type": "Banda Tributo", "genres": ["Rock Clásico"], "price": 1500, "description": "Tributo profesional al legendario grupo Queen."},
                "Duo Acústico Light": {"musica_type": "Dúo", "genres": ["Pop", "Acústico"], "price": 400, "description": "Dúo de guitarra y voz para ambientación suave."},
                "Mariachi Fiesta Mexicana": {"musica_type": "Mariachi", "genres": ["Tradicional", "Ranchera"], "price": 1000, "description": "Auténtico mariachi para celebraciones mexicanas."},
                "Cantautor Intimista": {"musica_type": "Solista", "genres": ["Indie", "Pop"], "price": 350, "description": "Solista con repertorio personalizado y canciones propias."},
                "DJ Electro Sunset": {"musica_type": "DJ", "genres": ["Deep House", "Chill"], "price": 450, "description": "Sesiones electrónicas ideales para puestas de sol."},
                "Banda Funky Fresh": {"musica_type": "Banda", "genres": ["Funk", "Soul"], "price": 1300, "description": "Banda enérgica con ritmos funky para bailar toda la noche."},
                "Guitarrista Flamenco": {"musica_type": "Instrumental", "genres": ["Flamenco", "Clásica"], "price": 320, "description": "Guitarrista solista para ambientaciones auténticas."},
                "Coro Gospel Voices": {"musica_type": "Coro", "genres": ["Gospel", "Espiritual"], "price": 950, "description": "Coro gospel con gran potencia vocal y energía espiritual."},
                "DJ RetroMix": {"musica_type": "DJ", "genres": ["80s", "90s", "Disco"], "price": 480, "description": "Set retro para fiestas nostálgicas con hits del pasado."},
                "String Duo Elegant": {"musica_type": "Dúo", "genres": ["Clásica", "Instrumental"], "price": 600, "description": "Violín y chelo en directo para eventos de alta categoría."},
                "Banda de Covers Infinity": {"musica_type": "Banda", "genres": ["Pop", "Rock", "Dance"], "price": 1100, "description": "Covers enérgicos y divertidos de grandes éxitos."},
                "Saxofonista Sunset": {"musica_type": "Solista", "genres": ["Jazz", "Ambient"], "price": 370, "description": "Saxofonista con repertorio lounge para momentos especiales."},
                "DJ Wedding Mix": {"musica_type": "DJ", "genres": ["Comercial", "Dance"], "price": 550, "description": "Especialista en bodas y eventos sociales."},
                "Tuna Universitaria": {"musica_type": "Grupo", "genres": ["Tradicional", "Popular"], "price": 400, "description": "Grupo universitario con repertorio tradicional español."},
            },
            "Fotografia": {
                "StudioFlash": {"fotografia_type": "Estudio", "specialties": ["Retrato", "Bodas"], "price": 800, "description": "Estudio profesional especializado en sesiones de retrato y bodas."},
                "PhotoDreams": {"fotografia_type": "Exterior", "specialties": ["Paisaje", "Eventos"], "price": 650, "description": "Fotografía exterior con estilo natural y artístico."},
                "WeddingClick": {"fotografia_type": "Bodas", "specialties": ["Bodas", "Eventos"], "price": 1200, "description": "Especialistas en capturar momentos únicos en bodas."},
                "InstaFocus": {"fotografia_type": "Social", "specialties": ["Eventos", "Redes Sociales"], "price": 500, "description": "Fotos dinámicas y modernas ideales para redes sociales."},
                "Vintage Memories": {"fotografia_type": "Analógica", "specialties": ["Retrato", "Artística"], "price": 900, "description": "Fotografía analógica con estilo clásico y nostálgico."},
                "Urban Lens": {"fotografia_type": "Urbana", "specialties": ["Street Photography", "Moda"], "price": 700, "description": "Fotografía urbana contemporánea y moda callejera."},
                "Magic Moments": {"fotografia_type": "Eventos", "specialties": ["Cumpleaños", "Eventos corporativos"], "price": 750, "description": "Capturamos cada momento especial con creatividad."},
                "DreamWeddings": {"fotografia_type": "Bodas", "specialties": ["Ceremonias", "Recepciones"], "price": 1300, "description": "Especializados en bodas románticas y emotivas."},
                "GlamShot": {"fotografia_type": "Moda", "specialties": ["Editorial", "Desfiles"], "price": 1400, "description": "Producciones de moda con estilo editorial internacional."},
                "KidsWorld": {"fotografia_type": "Infantil", "specialties": ["Niños", "Familias"], "price": 600, "description": "Sesiones infantiles y familiares llenas de diversión."},
                "EventCapture": {"fotografia_type": "Eventos", "specialties": ["Corporativos", "Sociales"], "price": 800, "description": "Fotografía de eventos profesional para empresas y particulares."},
                "NaturePix": {"fotografia_type": "Naturaleza", "specialties": ["Paisaje", "Vida Salvaje"], "price": 700, "description": "Especialistas en capturar la belleza natural."},
                "Golden Hour": {"fotografia_type": "Exterior", "specialties": ["Parejas", "Retrato"], "price": 850, "description": "Sesiones al atardecer con luz natural dorada."},
                "Snap & Go": {"fotografia_type": "Eventos rápidos", "specialties": ["Express", "Social Media"], "price": 400, "description": "Cobertura de eventos rápidos para redes sociales."},
                "Luxury Weddings": {"fotografia_type": "Bodas", "specialties": ["Luxury", "Destination Weddings"], "price": 2000, "description": "Fotografía de bodas de lujo y destinos exclusivos."},
                "FoodieShots": {"fotografia_type": "Gastronómica", "specialties": ["Restaurantes", "Chef Profiles"], "price": 750, "description": "Especializados en fotografía gastronómica profesional."},
                "Art Portraits": {"fotografia_type": "Artística", "specialties": ["Fine Art", "Conceptual"], "price": 1100, "description": "Retratos artísticos con un enfoque conceptual."},
                "Corporate Shots": {"fotografia_type": "Corporativa", "specialties": ["Retratos Corporativos", "Eventos empresariales"], "price": 900, "description": "Fotografía profesional para empresas y ejecutivos."},
                "DroneView": {"fotografia_type": "Aérea", "specialties": ["Eventos", "Promocionales"], "price": 1000, "description": "Fotografía aérea y drones para eventos y marketing."},
                "Pet Portraits": {"fotografia_type": "Mascotas", "specialties": ["Retrato Animal", "Mascotas"], "price": 500, "description": "Retratos entrañables de mascotas en estudio o exteriores."},
            }
        }
        # Inicializar el modelo de embeddings
        self.model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
        
        # Crear descripciones textuales para los servicios
        self.service_texts = []
        self.service_data = []
        
        self.session = session
        # SERVICE REPRESENTAN LOS SERVICIOS CARGADOS TEMPORALMENTE SI TUVIERAMOS MUCHOS
        # EN VEZ DE CARGAR TODOS LOS SERVICIOS, CARGARIAMOS LOS SERVICIOS FILTRADOS CADA VEZ
        if self.session:
            self.services = crud_assistant.filter_services(self.session, None, self.services, False)
        
            # Recorrer cada categoría y servicio
            for category, services in self.services.items():
                    for service in services:
                        description = self.build_service_description(self.session, service, category)
                    # Crear una descripción textual del servicio
                    
                    # Guardar la descripción y los datos originales
                    self.service_texts.append(description)
                    self.service_data.append({
                            'id': service['id'],
                        'category': category,
                            'name': service['name'],
                            'description': description
                    })
            
            # Crear embeddings para las descripciones textuales
            self.embeddings = self.model.encode(self.service_texts)
            
            # Crear índice FAISS
            self.dimension = self.embeddings.shape[1]  # Dimensión de los embeddings
            self.index = faiss.IndexFlatL2(self.dimension)
            self.index.add(np.array(self.embeddings).astype('float32'))
    
    def calcular_precio_servicio(self, session, service, category, event_data):
        # Determinar cantidad
        cantidad = 1
        if category == "mobiliari-decoracio":
            if not service['mobiliari_decoracio']:
                return None
            cantidad = crud_event_service.calcular_cantidad_por_tipo(service['mobiliari_decoracio']['tipologia'], event_data.num_invitats)
        elif category == "catering":
            cantidad = event_data.num_invitats

        # Fechas del evento
        data_I = event_data.data_inici
        data_F = event_data.data_fi

        # Verificar disponibilidad (si aplica)
        time_total = (data_F - data_I).total_seconds() / 3600
        time_change = time_total // 4
        dispo, rango = crud_event_service.calcular_disponibilidad_reducida(session, service, category, event_data, time_change)
        if not dispo:
            return None
        # Ajustar fechas según rango si es necesario (igual que en el filtrado)
        if rango == 0:
            data_I = data_I + timedelta(hours=time_change)
            data_F = data_F - timedelta(hours=time_change)
        elif rango == 1:
            data_I = data_I + timedelta(hours=time_change*2)
        elif rango == 2:
            data_F = data_F - timedelta(hours=time_change*2)

        # Calcular precio
        price = crud_event_service._get_service_price(
            session=session,
            service_id=service['id'],
            data_inicio=data_I,
            data_fin=data_F
        )
        price_final = price * cantidad
        return price_final

    def dict_to_text(self, d: dict) -> str:
        if not d:
            return ""
        parts = []
        for k, v in d.items():
            if isinstance(v, list):
                parts.append(f"{k}: {' '.join(str(x) for x in v)}")
            elif isinstance(v, dict):
                # Si quieres, puedes hacer recursión aquí
                parts.append(f"{k}: {self.dict_to_text(v)}")
            else:
                parts.append(f"{k}: {v}")
        return " ".join(parts)

    def build_service_description(self, session, service: dict, category: str, event_data) -> str:
        
        desc = f"Nombre: {service.get('name', '')}, Descripción: {service.get('description', '')}, "
        if 'address' in service and service['address']:
            desc += f"Dirección: {self.dict_to_text(service['address'])}, "
        if 'service_include' in service and service['service_include']:
            desc += f"Incluye: {self.dict_to_text(service['service_include'])}, "

        # Acceso a los atributos específicos dentro de service[category]
        specific = service.get(category, {})
        if 'caracteristicas' in specific and specific['caracteristicas']:
            desc += f"Características: {', '.join(specific['caracteristicas'])}, "
        
        if category == "espai":
            desc += f"Tipo de espacio: {specific.get('espai_type', '')}, "
        
        elif category == "catering":
            desc += f"Tipo de entrega: {specific.get('tipo_entrega', '')}, Tipo de catering: {specific.get('tipo_catering', '')}, "
            if 'alergenos' in specific and specific['alergenos']:
                desc += f"Alérgenos: {', '.join(specific['alergenos'])}, "
            if 'menu' in specific and specific['menu']:
                menu = specific['menu']
                desc += f"Menú: Tipo: {menu.get('type_menu', '')}, Nombre: {menu.get('nombre', '')}, Descripción: {menu.get('descripcion', '')}, Platos: {', '.join(menu.get('platos', []))}, Opciones especiales: {', '.join(menu.get('opciones_especiales', []))}, "
            if 'articulo' in specific and specific['articulo']:
                articulo = specific['articulo']
                desc += f"Artículo: Tipo: {articulo.get('type_articulo', '')}, Nombre: {articulo.get('nombre', '')}, Descripción: {articulo.get('descripcion', '')}, Opciones especiales: {', '.join(articulo.get('opciones_especiales', []))}, "
        
        elif category in ["mobiliario", "decoracion"]:
            desc += f"Tipo de servicio: {specific.get('service_type', '')}, Tipología: {specific.get('tipologia', '')}, "
            if 'is_rental' in specific:
                desc += f"Alquiler: {specific['is_rental']}, "
            if 'subtipologia' in specific and specific['subtipologia']:
                desc += f"Subtipología: {specific['subtipologia']}, "
            if 'color' in specific and specific['color']:
                desc += f"Colores: {', '.join(specific['color'])}, "
            if 'material' in specific and specific['material']:
                desc += f"Materiales: {', '.join(specific['material'])}, "
            if 'forma' in specific and specific['forma']:
                desc += f"Forma: {specific['forma']}, "
            if 'modality' in specific and specific['modality']:
                desc += f"Modalidad: {specific['modality']}, "
            if 'style' in specific and specific['style']:
                desc += f"Estilo: {specific['style']}, "
            if 'size' in specific and specific['size']:
                desc += f"Tamaño: {specific['size']}, "
            if 'complement' in specific and specific['complement']:
                desc += f"Complementos: {specific['complement']}, "
        
        elif category == "musica":
            desc += f"Tipo de música: {specific.get('musica_type', '')}, Canciones: {specific.get('canciones', '')}, "
            if 'generos' in specific and specific['generos']:
                desc += f"Géneros: {', '.join(specific['generos'])}, "
            if 'instrumentos' in specific and specific['instrumentos']:
                desc += f"Instrumentos: {', '.join(specific['instrumentos'])}, "
            if 'raider' in specific and specific['raider']:
                raider = specific['raider']
                if 'num_integrantes' in raider:
                    desc += f"Integrantes: {raider['num_integrantes']}, "
                if 'solicitar_cancion_nueva' in raider:
                    desc += f"Solicitar canción nueva: {raider['solicitar_cancion_nueva']}, "
                if 'equipo_propio' in raider:
                    desc += f"Equipo propio: {raider['equipo_propio']}, "
                if 'condiciones' in raider and raider['condiciones']:
                    desc += f"Condiciones: {', '.join(raider['condiciones'])}, "
        
        elif category == "fotografia":
            desc += f"Tipo de fotografía: {specific.get('fotografia_type', '')}, "
            if 'servicio_especial_type' in specific and specific['servicio_especial_type']:
                desc += f"Servicio especial: {specific['servicio_especial_type']}, "
            if 'raider' in specific and specific['raider']:
                raider = specific['raider']
                if 'num_integrantes' in raider:
                    desc += f"Integrantes: {raider['num_integrantes']}, "
                if 'condiciones' in raider and raider['condiciones']:
                    desc += f"Condiciones: {', '.join(raider['condiciones'])}, "
        return desc.strip(', ')

    def get_relevant_services(self, session, message: str, filtered_services: dict = None, k: int = 8, event_data: EventData = None) -> List[dict]:
        """
        Encuentra los servicios más relevantes basados en la consulta del usuario.
        
        Args:
            message: Mensaje del usuario
            filtered_services: Diccionario con los servicios ya filtrados por tipo
            k: Número inicial de servicios a buscar por tipo de servicio (se filtrará después)
            
        Returns:
            Lista de servicios relevantes
        """
        if not isinstance(message, str):
            if hasattr(message, "__str__"):
                message = str(message)
            else:
                raise ValueError("El mensaje debe ser un string o convertible a string")

        if not filtered_services:
            return []

        relevant_services = []
        message_embedding = self.model.encode([message])
        for category, services in filtered_services.items():
            category_relevants = []
            for service in services:
                description = self.build_service_description(session, service, category, event_data)
                price = self.calcular_precio_servicio(session, service, category, event_data)
                if price is None:
                    continue
                service_embedding = self.model.encode([description])
                similarity = 1.0 / (1.0 + np.linalg.norm(service_embedding - message_embedding))
                category_relevants.append({
                    'id': str(service['id']),
                    'category': category,
                    'name': service['name'],
                    'price': price,
                    'description': description,
                    'relevance_score': float(similarity)
                })
            # Ordenar y tomar los k mejores de la categoría
            category_relevants.sort(key=lambda x: x['relevance_score'], reverse=True)
            relevant_services.extend(category_relevants[:k])
        return relevant_services 