"""
Recuperar_formulariosYpdf.py

Script de prueba para generar PDFs de formularios desde el backend
sin necesidad de pasar por la API Flask.
"""

import sys
import os
from datetime import datetime

# Agregar el directorio raíz al path para importar módulos
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from Consultas_SQL.conexion import get_connection
from fpdf import FPDF
import platform
import requests

import shutil
import zipfile
from pathlib import Path


class PDF(FPDF):
    """
    Clase personalizada para PDF con identidad corporativa IGSA
    """
    def __init__(self):
        super().__init__()
        self.form_id = ""
        
    def header(self):
        """Encabezado de cada página con colores corporativos"""
        self.set_font('Arial', 'B', 16)
        self.set_fill_color(91, 155, 213)
        self.set_text_color(255, 255, 255)
        self.cell(0, 15, 'Información de Formulario', 0, 1, 'C', 1)
        self.ln(3)
        
    def footer(self):
        """Pie de página"""
        self.set_y(-15)
        self.set_font('Arial', 'I', 8)
        self.set_text_color(102, 102, 102)
        self.cell(0, 10, f'Página {self.page_no()}/{{nb}}', 0, 0, 'C')
        
    def seccion_titulo(self, titulo):
        """Crea un título de sección con colores corporativos"""
        self.set_font('Arial', 'B', 13)
        self.set_fill_color(46, 92, 138)
        self.set_text_color(255, 255, 255)
        self.cell(0, 10, titulo, 0, 1, 'L', 1)
        self.ln(2)
        
    def fila_datos(self, etiqueta, valor, bg_color=(231, 243, 248)):
        """Crea una fila de datos con etiqueta y valor"""
        self.set_font('Arial', 'B', 10)
        self.set_fill_color(*bg_color)
        self.set_text_color(46, 92, 138)
        self.cell(60, 10, etiqueta, 1, 0, 'L', 1)
        
        self.set_font('Arial', '', 10)
        self.set_text_color(51, 51, 51)
        self.cell(0, 10, str(valor), 1, 1, 'L')
    
    def fila_pregunta_respuesta(self, pregunta, respuesta):
        """
        Crea una fila con pregunta y respuesta en formato simplificado
        con colores corporativos IGSA
        """
        ancho_pregunta = 70
        ancho_respuesta = self.w - self.l_margin - self.r_margin - ancho_pregunta
        
        y_inicial = self.get_y()
        
        # Dibujar pregunta con fondo celeste claro corporativo
        self.set_xy(self.l_margin, y_inicial)
        self.set_font('Arial', 'B', 10)
        self.set_fill_color(231, 243, 248)
        self.set_text_color(46, 92, 138)
        self.multi_cell(ancho_pregunta, 7, str(pregunta) + ':', 1, 'L', True)
        
        # Dibujar respuesta con fondo blanco
        self.set_xy(self.l_margin + ancho_pregunta, y_inicial)
        self.set_font('Arial', '', 10)
        self.set_fill_color(255, 255, 255)
        self.set_text_color(51, 51, 51)
        self.multi_cell(ancho_respuesta, 7, str(respuesta), 1, 'L', True)


class FormularioPDFService:
    """
    Servicio para generar PDFs de formularios desde la base de datos
    """
    
    @staticmethod
    def obtener_datos_formulario(form_id: str) -> dict:
        """
        Obtiene los datos del formulario desde la base de datos
        
        Args:
            form_id (str): ID del formulario (ej: '1002-1-FormGral')
            
        Returns:
            dict: Diccionario con los datos del formulario o None si no existe
        """
        print(f"🔍 Buscando datos para FormID: {form_id}")
        
        query = """
        SELECT 
            fh.FormID,
            fh.CreatedAt,
            COALESCE(NULLIF(RTRIM(LTRIM(fh.CreatedBy)), ''), 'Sin información') AS CreatedBy,
            COALESCE(NULLIF(RTRIM(LTRIM(qt.FrontES)), ''), 'Sin información') AS FrontES,
            COALESCE(NULLIF(RTRIM(LTRIM(fd.Question)), ''), 'Sin información') AS Question,
            COALESCE(NULLIF(RTRIM(LTRIM(fd.TypeQuestion)), ''), 'Sin información') AS TypeQuestion,
            COALESCE(NULLIF(RTRIM(LTRIM(fd.Answer)), ''), 'Sin información') AS Answer,
            COALESCE(NULLIF(RTRIM(LTRIM(p.Email)), ''), 'Sin información') AS Email,
            COALESCE(NULLIF(RTRIM(LTRIM(p.ContactPhone)), ''), 'Sin información') AS ContactPhone,
            COALESCE(NULLIF(RTRIM(LTRIM(p.FirstName)), ''), 'Sin información') AS FirstName,
            fd.FormLineID
        FROM 
            Q_SpQ_FormsHead fh
        INNER JOIN Q_QuotationType qt ON fh.QuotationTypeID = qt.QuotationTypeID
        LEFT JOIN Q_SpQ_FormsDetail fd ON fh.FormID = fd.FormID
        LEFT JOIN Profiles p ON fh.UserID = p.UserID
        WHERE 
            fh.FormID = ?
        ORDER BY 
            fd.FormLineID
        """
        
        try:
            with get_connection() as conn:
                with conn.cursor() as cursor:
                    cursor.execute(query, (form_id,))
                    rows = cursor.fetchall()
                    
                    if not rows:
                        print(f"❌ No se encontraron datos para FormID: {form_id}")
                        return None
                    
                    print(f"✅ Se encontraron {len(rows)} registros (preguntas)")
                    
                    # Tomar la primera fila para datos del encabezado
                    primera_fila = rows[0]
                    
                    # Estructura de datos del formulario
                    datos = {
                        'FormID': primera_fila[0],
                        'CreatedAt': primera_fila[1],
                        'CreatedBy': primera_fila[2],
                        'FrontES': primera_fila[3],
                        'Email': primera_fila[7],
                        'ContactPhone': primera_fila[8],
                        'FirstName': primera_fila[9],
                        'preguntas': []
                    }
                    
                    # Agregar TODAS las preguntas y respuestas
                    print(f"📝 Procesando {len(rows)} preguntas:")
                    for idx, row in enumerate(rows, 1):
                        pregunta = {
                            'FormLineID': row[10],
                            'Question': row[4],
                            'TypeQuestion': row[5],
                            'Answer': row[6]
                        }
                        datos['preguntas'].append(pregunta)
                        
                        # Log cada 5 preguntas para tracking
                        if idx % 5 == 0:
                            print(f"   ↳ Procesadas {idx}/{len(rows)} preguntas...")
                    
                    print(f"✅ Total de preguntas capturadas: {len(datos['preguntas'])}")
                    
                    return datos
                    
        except Exception as e:
            print(f"❌ Error al consultar la base de datos: {e}")
            import traceback
            traceback.print_exc()
            return None
    
    @staticmethod
    def crear_directorio_reportes(directorio_base='reportes'):
        """
        Crea el directorio donde se guardarán los reportes si no existe
        """
        script_dir = os.path.dirname(os.path.abspath(__file__))
        ruta_reportes = os.path.join(script_dir, directorio_base)
        
        if not os.path.exists(ruta_reportes):
            os.makedirs(ruta_reportes)
            print(f"📁 Directorio creado: {ruta_reportes}")
        else:
            print(f"📁 Usando directorio existente: {ruta_reportes}")
        
        return ruta_reportes
    
    @staticmethod
    def abrir_archivo(ruta_archivo):
        """
        Abre el archivo PDF generado con el visor predeterminado del sistema
        """
        try:
            sistema = platform.system()
            
            if sistema == 'Windows':
                os.startfile(ruta_archivo)
            elif sistema == 'Darwin':  # macOS
                os.system(f'open "{ruta_archivo}"')
            else:  # Linux
                os.system(f'xdg-open "{ruta_archivo}"')
            
            print(f"📄 Archivo abierto automáticamente")
        except Exception as e:
            print(f"⚠️  No se pudo abrir el archivo automáticamente: {e}")
            print(f"   Puedes abrirlo manualmente desde: {ruta_archivo}")
    
    @staticmethod
    def generar_pdf(form_id: str, nombre_archivo=None, abrir_al_finalizar=True):
        """
        Genera un PDF del formulario especificado
        
        Args:
            form_id (str): ID del formulario (ej: '1001-1')
            nombre_archivo (str, optional): Nombre del archivo PDF
            abrir_al_finalizar (bool): Si es True, abre el PDF automáticamente
            
        Returns:
            str: Ruta completa del archivo generado o None si hay error
        """
        
        print("=" * 80)
        print("🚀 INICIANDO GENERACIÓN DE REPORTE PDF")
        print("=" * 80)
        print(f"📋 FormID solicitado: {form_id}")
        print()
        
        # Obtener datos de la base de datos
        datos = FormularioPDFService.obtener_datos_formulario(form_id)
        
        if not datos:
            print("❌ No se pudieron obtener los datos del formulario")
            return None
        
        # Crear directorio de reportes
        directorio_reportes = FormularioPDFService.crear_directorio_reportes('reportes')
        
        # Generar nombre de archivo si no se proporciona
        if nombre_archivo is None:
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            nombre_archivo = f'formulario_{form_id.replace("-", "_")}_{timestamp}.pdf'
        
        # Ruta completa del archivo
        ruta_completa = os.path.join(directorio_reportes, nombre_archivo)
        
        print(f"💾 Nombre del archivo: {nombre_archivo}")
        print(f"📂 Ubicación completa: {ruta_completa}")
        print()
        
        try:
            print("📝 Generando documento PDF...")
            
            pdf = PDF()
            pdf.form_id = form_id
            pdf.alias_nb_pages()
            pdf.add_page()
            
            # Subtítulo descriptivo
            pdf.set_font('Arial', '', 10)
            pdf.set_text_color(102, 102, 102)
            pdf.multi_cell(0, 5, 'Bienvenido. Módulo para Información del formulario, diseñado para el área comercial de IGSA.', 0, 'C')
            pdf.ln(8)
            
            # Información General - Datos de la Oportunidad
            print("   ↳ Agregando información del formulario...")
            pdf.seccion_titulo('Datos de la Oportunidad')
            pdf.fila_datos('Form ID:', datos['FormID'], (231, 243, 248))
            pdf.fila_datos('Fecha de Creación:', str(datos['CreatedAt']), (231, 243, 248))
            pdf.fila_datos('Creado Por:', datos['CreatedBy'], (231, 243, 248))
            pdf.fila_datos('Tipo de Formulario:', datos['FrontES'], (231, 243, 248))
            pdf.ln(5)
            
            # Información del Usuario
            print("   ↳ Agregando información del usuario...")
            pdf.seccion_titulo('Información del Usuario')
            pdf.fila_datos('Nombre:', datos['FirstName'], (231, 243, 248))
            pdf.fila_datos('Email:', datos['Email'], (231, 243, 248))
            pdf.fila_datos('Teléfono:', datos['ContactPhone'], (231, 243, 248))
            pdf.ln(5)
            
            # Detalles del Formulario
            print(f"   ↳ Procesando {len(datos['preguntas'])} preguntas y respuestas...")
            pdf.seccion_titulo('Detalles del Formulario')
            pdf.ln(2)
            
            for idx, pregunta in enumerate(datos['preguntas'], 1):
                if idx % 10 == 0:
                    print(f"      • Procesadas {idx}/{len(datos['preguntas'])} preguntas")
                
                pdf.fila_pregunta_respuesta(pregunta['Question'], pregunta['Answer'])
            
            print(f"      • Procesadas {len(datos['preguntas'])}/{len(datos['preguntas'])} preguntas ✓")
            
            # Pie de página del documento
            print("   ↳ Agregando información de generación...")
            pdf.ln(5)
            pdf.set_font('Arial', 'I', 9)
            pdf.set_text_color(102, 102, 102)
            fecha_gen = datetime.now().strftime('%d/%m/%Y %H:%M:%S')
            pdf.cell(0, 10, f'Reporte generado el {fecha_gen}', 0, 1, 'C')
            
            print()
            
            # Guardar archivo
            print("💾 Guardando archivo PDF...")
            pdf.output(ruta_completa)
            
            if os.path.exists(ruta_completa):
                tamaño_kb = os.path.getsize(ruta_completa) / 1024
                print(f"✅ Archivo guardado exitosamente")
                print(f"📏 Tamaño del archivo: {tamaño_kb:.2f} KB")
            else:
                print(f"❌ ERROR: El archivo no se pudo guardar")
                return None
            
            print()
            print("=" * 80)
            print("✨ PROCESO COMPLETADO EXITOSAMENTE")
            print("=" * 80)
            print(f"📄 Archivo generado: {nombre_archivo}")
            print(f"📂 Ubicación: {directorio_reportes}")
            print(f"🔗 Ruta completa: {ruta_completa}")
            print("=" * 80)
            
            if abrir_al_finalizar:
                print()
                FormularioPDFService.abrir_archivo(ruta_completa)
            
            return ruta_completa
            
        except Exception as e:
            print()
            print("=" * 80)
            print("❌ ERROR INESPERADO")
            print("=" * 80)
            print(f"Tipo de error: {type(e).__name__}")
            print(f"Detalles: {e}")
            print()
            print("Stack trace completo:")
            import traceback
            traceback.print_exc()
            print("=" * 80)
            return None
        
    # ============================================
    # 1. MÉTODOS PARA ARCHIVOS ADJUNTOS
    # ============================================

    @staticmethod
    def obtener_archivos_adjuntos(docs_id: int) -> list:
        """
        Obtiene los archivos adjuntos asociados al DocsID desde Q_SpQ_DocsDetail
        
        Args:
            docs_id (int): ID del documento
            
        Returns:
            list: Lista de diccionarios con información de los archivos
        """
        print(f"🔍 Buscando archivos adjuntos para DocsID: {docs_id}")
        
        query = """
        SELECT 
            DocLineID,
            DocsID,
            DocLine,
            RTRIM(LTRIM(Title)) AS Title,
            RTRIM(LTRIM(Ruta)) AS Ruta
        FROM 
            Q_SpQ_DocsDetail
        WHERE 
            DocsID = ?
        ORDER BY 
            DocLineID
        """
        
        try:
            with get_connection() as conn:
                with conn.cursor() as cursor:
                    cursor.execute(query, (docs_id,))
                    rows = cursor.fetchall()
                    
                    if not rows:
                        print(f"   ℹ️  No se encontraron archivos adjuntos para DocsID: {docs_id}")
                        return []
                    
                    archivos = []
                    for row in rows:
                        archivo = {
                            'DocLineID': row[0],
                            'DocsID': row[1],
                            'DocLine': row[2],
                            'Title': row[3],
                            'Ruta': row[4]
                        }
                        archivos.append(archivo)
                    
                    print(f"✅ Se encontraron {len(archivos)} archivo(s) adjunto(s)")
                    return archivos
                    
        except Exception as e:
            print(f"❌ Error al consultar archivos adjuntos: {e}")
            import traceback
            traceback.print_exc()
            return []
    
    @staticmethod
    def descargar_archivo(ruta_origen: str, directorio_destino: str, nombre_archivo: str = None) -> str:
        """
        Descarga un archivo desde una URL o copia desde una ruta local
        
        Args:
            ruta_origen (str): URL o ruta local del archivo
            directorio_destino (str): Directorio donde se guardará el archivo
            nombre_archivo (str, optional): Nombre personalizado para el archivo
            
        Returns:
            str: Ruta completa del archivo descargado o None si hay error
        """
        import requests
        from urllib.parse import urlparse, unquote
        
        try:
            # Detectar si es una URL o una ruta local
            es_url = ruta_origen.startswith('http://') or ruta_origen.startswith('https://')
            
            if es_url:
                # ============================================
                # DESCARGAR DESDE URL
                # ============================================
                
                # Si no se proporciona nombre, extraerlo de la URL
                if nombre_archivo is None:
                    parsed_url = urlparse(ruta_origen)
                    nombre_archivo = unquote(os.path.basename(parsed_url.path))
                
                # Crear ruta destino
                destino = Path(directorio_destino) / nombre_archivo
                
                # Descargar archivo con requests
                print(f"   🌐 Descargando desde URL...")
                response = requests.get(ruta_origen, timeout=30, stream=True)
                response.raise_for_status()  # Lanza excepción si hay error HTTP
                
                # Guardar archivo
                with open(destino, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                
                # Verificar que se descargó
                if destino.exists():
                    tamaño_kb = destino.stat().st_size / 1024
                    print(f"   ✅ Descargado: {nombre_archivo} ({tamaño_kb:.2f} KB)")
                    return str(destino)
                else:
                    print(f"   ❌ El archivo no se guardó correctamente")
                    return None
                
            else:
                # ============================================
                # COPIAR DESDE RUTA LOCAL
                # ============================================
                origen = Path(ruta_origen)
                
                if not origen.exists():
                    print(f"   ⚠️  Archivo no encontrado: {ruta_origen}")
                    return None
                
                # Usar nombre original si no se proporciona uno personalizado
                if nombre_archivo is None:
                    nombre_archivo = origen.name
                
                # Crear ruta destino
                destino = Path(directorio_destino) / nombre_archivo
                
                # Copiar archivo
                shutil.copy2(origen, destino)
                print(f"   ✅ Copiado: {nombre_archivo}")
                
                return str(destino)
            
        except requests.exceptions.RequestException as e:
            print(f"   ❌ Error de red al descargar: {e}")
            return None
        except Exception as e:
            print(f"   ❌ Error al procesar archivo: {e}")
            import traceback
            traceback.print_exc()
            return None
    
    @staticmethod
    def crear_zip_con_archivos(archivos: list, ruta_zip: str) -> bool:
        """
        Crea un archivo ZIP con todos los archivos descargados
        
        Args:
            archivos (list): Lista de rutas de archivos a incluir en el ZIP
            ruta_zip (str): Ruta donde se guardará el archivo ZIP
            
        Returns:
            bool: True si se creó exitosamente, False si hay error
        """
        try:
            with zipfile.ZipFile(ruta_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
                for archivo in archivos:
                    if archivo and Path(archivo).exists():
                        # Agregar archivo al ZIP con solo el nombre (sin la ruta completa)
                        zipf.write(archivo, Path(archivo).name)
            
            print(f"📦 ZIP creado: {Path(ruta_zip).name}")
            return True
            
        except Exception as e:
            print(f"❌ Error al crear ZIP: {e}")
            return False
    
    @staticmethod
    def generar_pdf_con_adjuntos(form_id: str, nombre_archivo=None, incluir_adjuntos=True, crear_zip=True):
        """
        Genera un PDF del formulario y descarga archivos adjuntos
        
        Args:
            form_id (str): ID del formulario (ej: '1002-1-FormGral')
            nombre_archivo (str, optional): Nombre del archivo PDF
            incluir_adjuntos (bool): Si es True, descarga archivos adjuntos
            crear_zip (bool): Si es True, crea un ZIP con PDF y adjuntos
            
        Returns:
            dict: Diccionario con rutas de archivos generados o None si hay error
        """
        
        print("=" * 80)
        print("🚀 INICIANDO GENERACIÓN DE REPORTE PDF CON ADJUNTOS")
        print("=" * 80)
        print(f"📋 FormID solicitado: {form_id}")
        print(f"📎 Incluir adjuntos: {'Sí' if incluir_adjuntos else 'No'}")
        print(f"📦 Crear ZIP: {'Sí' if crear_zip else 'No'}")
        print()
        
        # Obtener datos de la base de datos
        datos = FormularioPDFService.obtener_datos_formulario(form_id)
        
        if not datos:
            print("❌ No se pudieron obtener los datos del formulario")
            return None
        
        # Extraer DocsID del FormID (ejemplo: '1002-1-FormGral' → DocsID = 1002)
        try:
            docs_id = int(form_id.split('-')[0])
        except:
            print("⚠️  No se pudo extraer DocsID del FormID")
            docs_id = None
        
        # Crear directorio de reportes
        directorio_reportes = FormularioPDFService.crear_directorio_reportes('reportes')
        
        # Crear subdirectorio para este formulario específico
        nombre_carpeta = f'formulario_{form_id.replace("-", "_")}'
        directorio_formulario = os.path.join(directorio_reportes, nombre_carpeta)
        
        if not os.path.exists(directorio_formulario):
            os.makedirs(directorio_formulario)
            print(f"📁 Directorio creado: {nombre_carpeta}")
        
        # Generar nombre de archivo si no se proporciona
        if nombre_archivo is None:
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            nombre_archivo = f'formulario_{form_id.replace("-", "_")}_{timestamp}.pdf'
        
        # Ruta completa del PDF
        ruta_pdf = os.path.join(directorio_formulario, nombre_archivo)
        
        print(f"💾 Generando PDF: {nombre_archivo}")
        print()
        
        # ============================================
        # GENERAR PDF
        # ============================================
        try:
            print("📝 Generando documento PDF...")
            
            pdf = PDF()
            pdf.form_id = form_id
            pdf.alias_nb_pages()
            pdf.add_page()
            
            # Subtítulo descriptivo
            pdf.set_font('Arial', '', 10)
            pdf.set_text_color(102, 102, 102)
            pdf.multi_cell(0, 5, 'Bienvenido. Módulo para Información de formulario, diseñado para el área comercial de IGSA.', 0, 'C')
            pdf.ln(8)
            
            # Información General - Datos de la Oportunidad
            print("   ↳ Agregando información del formulario...")
            pdf.seccion_titulo('Datos de la Oportunidad')
            pdf.fila_datos('Form ID:', datos['FormID'], (231, 243, 248))
            pdf.fila_datos('Fecha de Creación:', str(datos['CreatedAt']), (231, 243, 248))
            pdf.fila_datos('Creado Por:', datos['CreatedBy'], (231, 243, 248))
            pdf.fila_datos('Tipo de Formulario:', datos['FrontES'], (231, 243, 248))
            pdf.ln(5)
            
            # Información del Usuario
            print("   ↳ Agregando información del usuario...")
            pdf.seccion_titulo('Información del Usuario')
            pdf.fila_datos('Nombre:', datos['FirstName'], (231, 243, 248))
            pdf.fila_datos('Email:', datos['Email'], (231, 243, 248))
            pdf.fila_datos('Teléfono:', datos['ContactPhone'], (231, 243, 248))
            pdf.ln(5)
            
            # Detalles del Formulario
            print(f"   ↳ Procesando {len(datos['preguntas'])} preguntas y respuestas...")
            pdf.seccion_titulo('Detalles del Formulario')
            pdf.ln(2)
            
            for idx, pregunta in enumerate(datos['preguntas'], 1):
                if idx % 10 == 0:
                    print(f"      • Procesadas {idx}/{len(datos['preguntas'])} preguntas")
                
                pdf.fila_pregunta_respuesta(pregunta['Question'], pregunta['Answer'])
            
            print(f"      • Procesadas {len(datos['preguntas'])}/{len(datos['preguntas'])} preguntas ✓")
            
            # Pie de página del documento
            print("   ↳ Agregando información de generación...")
            pdf.ln(5)
            pdf.set_font('Arial', 'I', 9)
            pdf.set_text_color(102, 102, 102)
            fecha_gen = datetime.now().strftime('%d/%m/%Y %H:%M:%S')
            pdf.cell(0, 10, f'Reporte generado el {fecha_gen}', 0, 1, 'C')
            
            print()
            
            # Guardar PDF
            print("💾 Guardando archivo PDF...")
            pdf.output(ruta_pdf)
            
            import time
            time.sleep(0.2)
            
            if not os.path.exists(ruta_pdf):
                print(f"❌ ERROR: El archivo no se pudo guardar")
                return None
            
            tamaño_kb = os.path.getsize(ruta_pdf) / 1024
            print(f"✅ PDF guardado exitosamente ({tamaño_kb:.2f} KB)")
            
        except Exception as e:
            print()
            print("❌ ERROR al generar PDF:", e)
            import traceback
            traceback.print_exc()
            return None
        
        # ============================================
        # DESCARGAR ARCHIVOS ADJUNTOS
        # ============================================
        archivos_descargados = [ruta_pdf]
        
        if incluir_adjuntos and docs_id:
            print()
            print("=" * 80)
            print("📎 DESCARGANDO ARCHIVOS ADJUNTOS")
            print("=" * 80)
            
            archivos_adjuntos = FormularioPDFService.obtener_archivos_adjuntos(docs_id)
            
            if archivos_adjuntos:
                print(f"📥 Descargando {len(archivos_adjuntos)} archivo(s)...")
                print()
                
                for idx, archivo in enumerate(archivos_adjuntos, 1):
                    print(f"[{idx}/{len(archivos_adjuntos)}] {archivo['Title']}")
                    
                    ruta_descargada = FormularioPDFService.descargar_archivo(
                        ruta_origen=archivo['Ruta'],
                        directorio_destino=directorio_formulario,
                        nombre_archivo=archivo['Title']
                    )
                    
                    if ruta_descargada:
                        archivos_descargados.append(ruta_descargada)
                
                print()
                print(f"✅ Descargados {len(archivos_descargados) - 1} archivo(s) adjunto(s)")
            else:
                print("   ℹ️  No hay archivos adjuntos para este formulario")
        
        # ============================================
        # CREAR ZIP (OPCIONAL)
        # ============================================
        ruta_zip = None
        
        if crear_zip and len(archivos_descargados) > 1:
            print()
            print("=" * 80)
            print("📦 CREANDO ARCHIVO ZIP")
            print("=" * 80)
            
            nombre_zip = f'paquete_{form_id.replace("-", "_")}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.zip'
            ruta_zip = os.path.join(directorio_reportes, nombre_zip)
            
            if FormularioPDFService.crear_zip_con_archivos(archivos_descargados, ruta_zip):
                tamaño_zip_kb = os.path.getsize(ruta_zip) / 1024
                print(f"✅ ZIP creado exitosamente ({tamaño_zip_kb:.2f} KB)")
            else:
                ruta_zip = None
        
        # ============================================
        # RESUMEN FINAL
        # ============================================
        print()
        print("=" * 80)
        print("✨ PROCESO COMPLETADO EXITOSAMENTE")
        print("=" * 80)
        print(f"📄 PDF generado: {nombre_archivo}")
        print(f"📁 Ubicación: {directorio_formulario}")
        print(f"📎 Archivos adjuntos: {len(archivos_descargados) - 1}")
        if ruta_zip:
            print(f"📦 ZIP creado: {os.path.basename(ruta_zip)}")
        print("=" * 80)
        
        return {
            'pdf': ruta_pdf,
            'adjuntos': archivos_descargados[1:],  # Excluir el PDF
            'zip': ruta_zip,
            'directorio': directorio_formulario
        }