from flask import Blueprint, jsonify, request, session
from ..services import quote_reception_services
from ..services.quote_reception_services import OpportunityAndCostingDTO
import json

# Definición del nuevo Blueprint
router = Blueprint('quote_reception', __name__)

@router.route('/costing/<int:costing_num>', methods=['GET'])
def get_reception_costing_controller(costing_num: int):
    """
    Controlador para obtener datos unificados de la cotización (Costeo y CRM).
    Ruta final: /api/reception/costing/<int:costing_num>
    """
    try:
        # Llama al nuevo método del servicio unificado
        data_dto = quote_reception_services.Quote_Reception_Service.get_unified_data_by_costing_num(costing_num)
        
        if data_dto:
            # Convierte el DTO a diccionario y lo retorna como JSON
            print(f'Datos unificados de Costeo/CRM (Num {costing_num}) recuperados: {data_dto.to_dict()}')
            return jsonify(data_dto.to_dict())
        else:
            # Retorna 404 si la cotización no se encuentra
            return jsonify({"error": f"Cotización con número {costing_num} no encontrada"}), 404
            
    except Exception as e:
        print(f"Error en el controlador quote_reception/costing: {e}")
        return jsonify({"error": "Ocurrió un error interno en el servidor"}), 500
    
@router.route('/taxes', methods=['GET'])
def get_taxes_controller():
    """
    Controlador para obtener la lista de impuestos.
    Ruta final: /api/reception/taxes
    """
    try:
        taxes = quote_reception_services.Quote_Reception_Service.get_taxes()
        return jsonify(taxes)
    except Exception as e:
        print(f"Error en el controlador quote_reception/taxes: {e}")
        return jsonify({"error": "Ocurrió un error interno en el servidor"}), 500

@router.route('/currencies', methods=['GET'])
def get_currencies_controller():
    """
    Controlador para obtener la lista de monedas.
    Ruta final: /api/reception/currencies
    """
    try:
        currencies = quote_reception_services.Quote_Reception_Service.get_currencies()
        return jsonify(currencies)
    except Exception as e:
        print(f"Error en el controlador quote_reception/currencies: {e}")
        return jsonify({"error": "Ocurrió un error interno en el servidor"}), 500
    
@router.route('/costing-details/<int:costing_num>', methods=['GET'])
def get_costing_details_controller(costing_num: int):
    """
    Controlador para obtener las líneas de costeo.
    Ruta final: /api/reception/costing-details/<int:costing_num>
    """
    try:
        details = quote_reception_services.Quote_Reception_Service.get_costing_details(costing_num)
        return jsonify(details)
    except Exception as e:
        print(f"Error en el controlador quote_reception/costing-details: {e}")
        return jsonify({"error": "Ocurrió un error interno en el servidor"}), 500
    
@router.route('/create-quotation', methods=['POST'])
def create_quotation_controller():
    """
    Controlador para crear una nueva cotización.
    Ruta final: /api/reception/create-quotation
    """
    try:
        data = request.get_json()
        result = quote_reception_services.Quote_Reception_Service.create_quotation(data)
        
        if result.get('success'):
            return jsonify(result), 201
        else:
            return jsonify(result), 400
            
    except Exception as e:
        print(f"Error en el controlador create-quotation: {e}")
        return jsonify({"success": False, "error": "Ocurrió un error interno en el servidor"}), 500
    
# En quote_reception_controller.py

@router.route('/preview-quotation', methods=['POST', 'OPTIONS'])
def preview_quotation_controller():
    """
    Controlador para generar vista previa de la cotización antes de crearla.
    Ruta final: /api/reception/preview-quotation
    """
    # Manejar preflight request (CORS)
    if request.method == 'OPTIONS':
        response = jsonify({'status': 'ok'})
        response.headers.add('Access-Control-Allow-Origin', '*')
        response.headers.add('Access-Control-Allow-Headers', 'Content-Type,X-Auth-Token')
        response.headers.add('Access-Control-Allow-Methods', 'POST')
        return response, 200
    
    try:
        # Obtener datos
        data = request.get_json()
        
        # ✅ NUEVO: Si no vienen datos completos o solo viene el token, cargar desde archivo temporal
        if not data or len(data) <= 1:  # Solo tiene token o está vacío
            print("⚠️ Datos incompletos recibidos, intentando cargar desde archivo temporal...")
            
            token = None
            if data:
                token = data.get('token') or request.headers.get('X-Auth-Token')
            else:
                token = request.headers.get('X-Auth-Token')
            
            if token:
                # Buscar archivo temporal
                import os
                import json
                from flask import current_app
                
                output_dir = os.path.join(current_app.root_path, "static", "pdf", "Ventas", "Cotiz")
                temp_data_file = os.path.join(output_dir, f"temp_data_{token}.json")
                
                print(f"🔍 Buscando archivo: {temp_data_file}")
                
                if os.path.exists(temp_data_file):
                    with open(temp_data_file, 'r', encoding='utf-8') as f:
                        data = json.load(f)
                    print(f"✅ Datos cargados desde archivo temporal")
                    print(f"📦 Datos cargados: {list(data.keys())}")
                    
                    # Limpiar archivo temporal después de leerlo
                    try:
                        os.remove(temp_data_file)
                        print(f"🗑️ Archivo temporal eliminado")
                    except Exception as e:
                        print(f"⚠️ No se pudo eliminar archivo temporal: {e}")
                else:
                    print(f"❌ Archivo temporal no encontrado: {temp_data_file}")
                    error_html = f"""
                    <!DOCTYPE html>
                    <html>
                    <body>
                        <h1>❌ Error: No se encontraron datos de cotización</h1>
                        <p>Token: {token}</p>
                        <p>Archivo buscado: {temp_data_file}</p>
                    </body>
                    </html>
                    """
                    return error_html, 400, {'Content-Type': 'text/html; charset=utf-8'}
            else:
                error_html = """
                <!DOCTYPE html>
                <html>
                <body>
                    <h1>❌ Error: No se recibió token</h1>
                </body>
                </html>
                """
                return error_html, 400, {'Content-Type': 'text/html; charset=utf-8'}
        
        # Si llegamos aquí, data tiene contenido
        if not data:
            error_html = """
            <!DOCTYPE html>
            <html>
            <body>
                <h1>❌ Error: No se pudieron cargar los datos</h1>
            </body>
            </html>
            """
            return error_html, 400, {'Content-Type': 'text/html; charset=utf-8'}
        
        # Verificar token
        token = data.get('token') or request.headers.get('X-Auth-Token')
        
        print(f"📋 Generando vista previa para cotización")
        print(f"🎫 Token recibido: {token}")
        print(f"📦 Datos recibidos: {list(data.keys())}")
        
        # ✅ IMPORTANTE: Si solo viene el token, necesitamos obtener los datos completos
        # desde el JavaScript que hace la llamada desde el botón "Confirmar"
        
        # Llamar al servicio para generar la vista previa
        preview_html = quote_reception_services.Quote_Reception_Service.generate_quotation_preview(data)
        
        if preview_html:
            print(f"✅ HTML generado: {len(preview_html)} caracteres")
            return preview_html, 200, {'Content-Type': 'text/html; charset=utf-8'}
        else:
            error_html = """
            <!DOCTYPE html>
            <html>
            <body>
                <h1>❌ No se pudo generar la vista previa</h1>
                <p>El servicio no retornó contenido HTML</p>
            </body>
            </html>
            """
            return error_html, 500, {'Content-Type': 'text/html; charset=utf-8'}
            
    except Exception as e:
        print(f"❌ Error en preview-quotation: {e}")
        import traceback
        traceback.print_exc()
        
        error_html = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Error</title>
            <style>
                body {{
                    font-family: Arial, sans-serif;
                    padding: 40px;
                    background-color: #f5f5f5;
                }}
                .error {{
                    background-color: #fee;
                    border: 2px solid #f00;
                    padding: 20px;
                    border-radius: 8px;
                    max-width: 800px;
                    margin: 0 auto;
                }}
                pre {{
                    background-color: #333;
                    color: #fff;
                    padding: 15px;
                    overflow-x: auto;
                    border-radius: 4px;
                }}
            </style>
        </head>
        <body>
            <div class="error">
                <h1>❌ Error al generar vista previa</h1>
                <p><strong>Mensaje:</strong> {str(e)}</p>
                <pre>{traceback.format_exc()}</pre>
            </div>
        </body>
        </html>
        """
        return error_html, 500, {'Content-Type': 'text/html; charset=utf-8'}

@router.route('/generate-pdf/<quote_id>', methods=['POST'])
def generate_quotation_pdf_controller(quote_id):
    """
    Genera el PDF de la cotización, lo sube a FTP en estructura de carpetas y envía por email
    Ruta final: /api/reception/generate-pdf/<quote_id>
    """
    try:
        import os
        import subprocess
        import uuid
        import shutil
        import ftplib
        import json
        from flask import current_app, request
        from werkzeug.datastructures import FileStorage
        from App.Subir_Archivo import subir_archivo_ftp_desde_request
        from App.Utilities_module.MailManagement import enviar_correo_universal
        from datetime import datetime
        from Consultas_SQL.conexion import get_connection
        
        print("=" * 80)
        print("🚀 INICIANDO GENERACIÓN DE PDF CON EMAIL")
        print("=" * 80)
        
        # Obtener datos de la cotización
        data = request.get_json()
        
        # data que obtenemos.
        print("🧠 Datos recibidos para genera PDF")
        print(json.dumps(data, indent=2, ensure_ascii=False))
        
        # === Correo del usuario que creó la solicitud ===
        
        user_email = None
        
        try:
            user_id = session.get('user_id')          # del login
            session_email = session.get('email')      # fallback si no está en Profiles

            if user_id:
                from Consultas_SQL.conexion import get_connection
                with get_connection() as conn:
                    with conn.cursor() as cursor:
                        # INTENTO A: si Profiles tiene columna UserID
                        cursor.execute("SELECT Email FROM Profiles WHERE UserID = ?", user_id)
                        row = cursor.fetchone()

                        if not row or not row[0]:
                            # INTENTO B: si Profiles se liga vía ProfileID en Users
                            cursor.execute("""
                                SELECT P.Email
                                FROM Users U
                                JOIN Profiles P ON P.ProfileID = U.ProfileID
                                WHERE U.UserID = ?
                            """, user_id)
                            row = cursor.fetchone()

                if row and row[0]:
                    user_email = row[0]

            # Si no encontramos en Profiles, usa el email de la sesión como último recurso
            if not user_email and session_email:
                user_email = session_email

            print(f"📧 Email del creador detectado: {user_email or 'No disponible'}")

        except Exception as e:
            print(f"⚠️ No se pudo resolver el email del creador: {e}")
                
        
        # Generar token único
        token = str(uuid.uuid4())
        
        # Construir URL de vista previa
        base_url = request.host_url.rstrip('/')
        preview_url = f"{base_url}/api/reception/preview-quotation"
        
        # Generar token único
        token = str(uuid.uuid4())

        # Construir URL de vista previa
        base_url = request.host_url.rstrip('/')
        preview_url = f"{base_url}/api/reception/preview-quotation"
        
        # Ruta temporal para el PDF
        base_dir = current_app.root_path
        output_dir = os.path.join(base_dir, "static", "pdf", "Ventas", "Cotiz")
        os.makedirs(output_dir, exist_ok=True)

        # ✅ NUEVO: Guardar datos temporalmente para que Puppeteer pueda accederlos
        import json
        temp_data_file = os.path.join(output_dir, f"temp_data_{token}.json")
        with open(temp_data_file, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        print(f"💾 Datos temporales guardados: {temp_data_file}")
        

        
        # Obtener número de costeo BASE (sin versión)
        costing_num = data.get('CostingID', quote_id).split('-')[0]

        # ===== PASO 1: OBTENER VERSIÓN DESDE LA BASE DE DATOS =====
        print(f"\n📊 Obteniendo versión de cotización para: {costing_num}")
        try:
            with get_connection() as conn:
                with conn.cursor() as cursor:
                    cursor.execute("""
                        SELECT MAX(Version) FROM Q_QuotationHead WHERE QuotationNum = ?
                    """, costing_num)
                    version_result = cursor.fetchone()
                    version = 1 if not version_result[0] else version_result[0] + 1
            
            print(f"📊 Versión calculada desde BD: {version}")
            
        except Exception as e:
            print(f"⚠️ Error al obtener versión, usando versión 1: {str(e)}")
            version = 1

        # ===== PASO 2: CONSTRUIR EL QUOTE_ID CORRECTO CON LA VERSIÓN REAL =====
        # ✅ ESTO GARANTIZA QUE LA CARPETA Y EL PDF TENGAN LA MISMA VERSIÓN
        quote_id_correcto = f"{costing_num}-{version}"
        print(f"✅ QuoteID construido: {quote_id_correcto}")

        # Variables para la estructura de carpetas
        costing_num_base = str(costing_num)      # Ejemplo: "1021"
        quote_id_folder = quote_id_correcto      # Ejemplo: "1021-1" (con versión correcta)

        print(f"📁 Carpeta base: {costing_num_base}")
        print(f"📁 Carpeta versión: {quote_id_folder}")

        # Nombre del archivo PDF con versión
        output_filename = f"cotizacion_{costing_num}_V{version}_{token}.pdf"
        output_path = os.path.join(output_dir, output_filename)

        print(f"📄 Nombre del PDF: cotizacion_{costing_num}_V{version}.pdf")

        # ===== EJECUTAR PUPPETEER (sin cambios) =====
        # Ruta al script de Puppeteer
        script_path = os.path.join(
            base_dir, "puppeteer_pdf", "Ventas", "Cotiz", "PreviewCotizacion.js"
        )

        print(f"📂 Base dir: {base_dir}")
        print(f"📄 Script path: {script_path}")
        print(f"📄 Script exists: {os.path.exists(script_path)}")

        if not os.path.exists(script_path):
            error_msg = f"Script de Puppeteer no encontrado en: {script_path}"
            print(f"❌ {error_msg}")
            return jsonify({"success": False, "error": error_msg}), 500

        print(f"✅ Script encontrado: {script_path}")

        # Buscar Node.js
        print("\n🔍 Buscando Node.js...")
        node_path = shutil.which("node")

        if not node_path:
            print("⚠️ Node.js no encontrado con shutil.which, buscando manualmente...")
            possible_paths = [
                r"C:\Program Files\nodejs\node.exe",
                r"C:\Program Files (x86)\nodejs\node.exe",
                os.path.expanduser(r"~\AppData\Roaming\npm\node.exe"),
            ]
            
            for path in possible_paths:
                if os.path.exists(path):
                    node_path = path
                    print(f"  ✅ Encontrado: {path}")
                    break

        if not node_path or not os.path.exists(node_path):
            error_msg = "Node.js no encontrado. Instala Node.js desde https://nodejs.org"
            print(f"❌ {error_msg}")
            return jsonify({"success": False, "error": error_msg}), 500

        print(f"\n✅ Usando Node.js desde: {node_path}")
        print(f"\n🌐 URL de vista previa: {preview_url}")
        print(f"💾 Ruta de salida: {output_path}")
        print(f"🎫 Token: {token}")

        print("\n🚀 Ejecutando Puppeteer...")

        # Ejecutar Puppeteer
        process = subprocess.Popen(
            [node_path, script_path, preview_url, output_path, token],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            encoding='utf-8',
            errors='ignore',
            cwd=os.path.dirname(script_path)
        )

        try:
            stdout, stderr = process.communicate(timeout=90)
            return_code = process.returncode
            
            if stdout:
                print(f"\n📋 Puppeteer stdout:\n{stdout}")
            
            if stderr:
                print(f"\n⚠️ Puppeteer stderr:\n{stderr}")
            
            if return_code != 0:
                error_msg = stderr if stderr else "Error desconocido al generar PDF"
                print(f"\n❌ Puppeteer falló con código {return_code}")
                return jsonify({"success": False, "error": f"Error al generar PDF: {error_msg}"}), 500
            
            if not os.path.exists(output_path):
                print(f"❌ PDF no generado en: {output_path}")
                return jsonify({"success": False, "error": "El PDF no fue generado correctamente"}), 500
            
            print(f"✅ PDF generado exitosamente: {output_path}")
            print(f"📦 Tamaño del archivo: {os.path.getsize(output_path)} bytes")
            
        except subprocess.TimeoutExpired:
            process.kill()
            print("❌ Timeout: Puppeteer tardó más de 90 segundos")
            return jsonify({"success": False, "error": "Timeout: La generación del PDF tardó demasiado"}), 500

        # ===== FASE 6: VERIFICACIÓN Y CREACIÓN DE ESTRUCTURA DE CARPETAS EN FTP =====
        print("\n🗂️ Verificando/Creando estructura de carpetas en FTP...")
        print(f"📊 Estructura a crear: /Cotizaciones_Generales/{costing_num_base}/{quote_id_folder}/")

        host_ftp = os.getenv('FTP_HOST')
        usuario_ftp = os.getenv('FTP_USER')
        contraseña_ftp = os.getenv('FTP_PASS')

        # ✅ ESTRUCTURA CORREGIDA: Usa el quote_id_folder construido con la versión correcta
        # Estructura: /file/Ventas/Cotizaciones_Generales/1021/1021-1/
        carpetas_estructura = ['file', 'Ventas', 'Cotizaciones_Generales', costing_num_base, quote_id_folder]

        print(f"📁 Carpetas a crear/verificar: {' -> '.join(carpetas_estructura)}")

        try:
            ftp = ftplib.FTP(host_ftp)
            ftp.login(usuario_ftp, contraseña_ftp)
            print("✅ Conectado a FTP")
            
            # Navegar a la ruta base
            current_path = '/domains/sycelephant.com/public_html'
            ftp.cwd(current_path)
            print(f"📂 Ruta inicial: {current_path}")
            
            # Bandera para saber cuándo empezar a crear carpetas
            puede_crear = False
            
            for carpeta in carpetas_estructura:
                try:
                    # Intentar entrar a la carpeta
                    ftp.cwd(carpeta)
                    print(f"  ✅ Carpeta existente: {carpeta}")
                    
                    # Una vez que llegamos a "Ventas", activamos la creación
                    if carpeta == 'Ventas':
                        puede_crear = True
                        
                except ftplib.error_perm:
                    # La carpeta NO existe
                    
                    if not puede_crear:
                        # AÚN NO hemos llegado a Ventas, NO podemos crear
                        error_msg = f"Error: La carpeta requerida '{carpeta}' no existe en el servidor FTP. Ruta: {ftp.pwd()}/{carpeta}"
                        print(f"  ❌ {error_msg}")
                        ftp.quit()
                        return jsonify({
                            "success": False,
                            "error": error_msg,
                            "carpeta_faltante": carpeta
                        }), 500
                    else:
                        # YA pasamos Ventas, SÍ podemos crear
                        print(f"  📁 Creando carpeta: {carpeta}")
                        try:
                            ftp.mkd(carpeta)
                            ftp.cwd(carpeta)
                            print(f"  ✅ Carpeta creada: {carpeta}")
                        except Exception as e:
                            error_msg = f"Error al crear carpeta '{carpeta}': {str(e)}"
                            print(f"  ❌ {error_msg}")
                            ftp.quit()
                            return jsonify({"success": False, "error": error_msg}), 500
            
            ruta_final_ftp = ftp.pwd()
            print(f"✅ Estructura de carpetas FTP verificada/creada exitosamente")
            print(f"📂 Ruta final en FTP: {ruta_final_ftp}")
            
            ftp.quit()
            
        except Exception as e:
            error_msg = f"Error al trabajar con FTP: {str(e)}"
            print(f"❌ {error_msg}")
            return jsonify({"success": False, "error": error_msg}), 500

        # ===== SUBIR ARCHIVO A FTP =====
        print("\n📤 Subiendo PDF a FTP...")

        # ✅ CAMBIO: Usar quote_id en lugar de V{version}
        ruta_ftp_completa = f"/domains/sycelephant.com/public_html/file/Ventas/Cotizaciones_Generales/{costing_num_base}/{quote_id_folder}/"
        carpeta_relativa = f"/Ventas/Cotizaciones_Generales/{costing_num_base}/{quote_id_folder}/"

        with open(output_path, 'rb') as f:
            pdf_file = FileStorage(
                stream=f,
                filename=f"cotizacion_{costing_num}_{version}.pdf",  # Nombre del archivo mantiene V{version}
                name="QuotationPDF"
            )
            
            item = f"cotizacion_{costing_num}_V{version}"
            
            resultado_ftp = subir_archivo_ftp_desde_request(
                pdf_file, 
                item, 
                ruta_ftp_completa, 
                carpeta_relativa
            )
            
            if not resultado_ftp["exito"]:
                print(f"❌ Error al subir a FTP: {resultado_ftp['mensaje']}")
                print("⚠️ Intentando método alternativo sin estructura de carpetas...")
                
                # Método alternativo: subir a ruta base
                ruta_ftp_simple = "/domains/sycelephant.com/public_html/file/Ventas/"
                carpeta_simple = "/Ventas/"
                
                with open(output_path, 'rb') as f2:
                    pdf_file2 = FileStorage(
                        stream=f2,
                        filename=f"cotizacion_{costing_num}_{version}.pdf",
                        name="QuotationPDF"
                    )
                    
                    resultado_ftp = subir_archivo_ftp_desde_request(
                        pdf_file2, 
                        item, 
                        ruta_ftp_simple, 
                        carpeta_simple
                    )
                    
                    if not resultado_ftp["exito"]:
                        return jsonify({"success": False, "error": resultado_ftp["mensaje"]}), 400
            
            pdf_url = resultado_ftp["url_web"]
            print(f"✅ PDF subido exitosamente: {pdf_url}")
                
        # ===== ENVIAR EMAIL =====
        print("\n📧 Preparando envío de email...")

        try:
            # ✅ Calcular valores numéricos ANTES de formatear
            precio_lista = float(data.get('SalePrice', 0))
            precio_oferta = float(data.get('Amount', 0))
            precio_total = float(data.get('TotalAmount', 0))
            descuento_porcentaje = float(data.get('DiscountPercent', 0))

            # ✅ Calcular montos derivados
            monto_descuento = precio_lista - precio_oferta
            monto_impuesto = precio_total - precio_oferta

            # ✅ Obtener información completa del impuesto
            impuesto_info = {}
            try:
                with get_connection() as conn:
                    with conn.cursor() as cursor:
                        cursor.execute("""
                            SELECT TaxCode, FrontES, TaxAmount 
                            FROM Q_TaxRate 
                            WHERE TaxCode = ?
                        """, data.get('TaxCode'))
                        tax_row = cursor.fetchone()
                        
                        if tax_row:
                            impuesto_info = {
                                'codigo': tax_row[0],
                                'nombre': tax_row[1],
                                'porcentaje': float(tax_row[2]) * 100  # 0.16 -> 16
                            }
                        else:
                            impuesto_info = {
                                'codigo': data.get('TaxCode', 'N/A'),
                                'nombre': data.get('TaxCode', 'N/A'),
                                'porcentaje': 0
                            }
            except Exception as e:
                print(f"⚠️ Error al obtener info del impuesto: {e}")
                impuesto_info = {
                    'codigo': data.get('TaxCode', 'N/A'),
                    'nombre': data.get('TaxCode', 'N/A'),
                    'porcentaje': 0
                }
                
            print("\n👤 Obteniendo información del vendedor...")
            
            
            # ✅ OBTENER NOMBRE DE LA MONEDA (agregar ANTES de template_data)
            moneda_codigo = data.get('CurrencyCode', 'USD')
            moneda_nombre = moneda_codigo  # Por defecto

            try:
                with get_connection() as conn:
                    with conn.cursor() as cursor:
                        cursor.execute("""
                            SELECT FrontES FROM Q_Currency WHERE CurrencyCode = ?
                        """, moneda_codigo)
                        moneda_result = cursor.fetchone()
                        if moneda_result and moneda_result[0]:
                            moneda_nombre = moneda_result[0]
                
                print(f"💱 Moneda para email: {moneda_codigo} -> {moneda_nombre}")
            except Exception as e:
                print(f"⚠️ No se pudo obtener nombre de moneda: {e}")

            vendedor_info = quote_reception_services.Quote_Reception_Service.get_seller_info(data.get('CostingID'))
            vendedor_email = vendedor_info.get('email')
            vendedor_nombre = vendedor_info.get('nombre')
            vendedor_telefono = vendedor_info.get('telefono')

            print(f"✅ Vendedor encontrado: {vendedor_nombre}")
            print(f"✅ Email vendedor: {vendedor_email}")
            print(f"✅ Teléfono vendedor: {vendedor_telefono}")

            template_data = {
                'quotation_id': quote_id,
                'version': version,
                'costing_id': data.get('CostingID'),
                'caso_costeo': data.get('CaseCost', 'N/A'),
                'cliente_nombre': data.get('CRM_ContactName', 'Cliente'),
                'tipo_contacto': data.get('CRM_ContactType', 'N/A'),
                'oportunidad_crm': data.get('CRM_OpportunityNumber', 'N/A'),
                'cliente_email': data.get('CRM_ContactEmail', 'N/A'),
                'cliente_telefono': data.get('CRM_ContactNumber', 'N/A'),
                'cliente_ciudad': data.get('CRM_ContactCity', 'N/A'),
                'cliente_estado': data.get('CRM_ContactState', 'N/A'),
                'cliente_pais': data.get('CRM_ContactCountry', 'N/A'),
                'vendedor_asignado': vendedor_info.get('nombre'),
                
                # ✅ VALORES FINANCIEROS NUMÉRICOS (sin formatear)
                'precio_lista': precio_lista,
                'precio_oferta': precio_oferta,
                'precio_total': precio_total,
                'descuento_porcentaje': descuento_porcentaje,
                'monto_descuento': monto_descuento,
                'monto_impuesto': monto_impuesto,
                
                # ✅ INFORMACIÓN DEL IMPUESTO
                'impuesto_codigo': impuesto_info['codigo'],
                'impuesto_nombre': impuesto_info['nombre'],
                'impuesto_porcentaje': impuesto_info['porcentaje'],
                
                'moneda': moneda_nombre,  # "moneda"
                 'moneda_codigo': moneda_codigo,  # "MX"
                'factor_sobrecosto': data.get('OvercostFactor', 1),
                'total_lineas': len(data.get('QuotationLines', [])),
                'pdf_url': pdf_url,
                'fecha_generacion': datetime.now().strftime('%d/%m/%Y %H:%M')
            }
            
            archivos_adjuntos = [
                {
                    'tipo': 'local',
                    'ruta': output_path,
                    'nombre': f"Cotizacion_{costing_num}_V{version}.pdf",
                    'mimetype': 'application/pdf'
                }
            ]
            
            destinatarios_to = ['jesuscadena27@hotmail.com']

            # Agregar email del creador
            if user_email:
                destinatarios_to.append(user_email)
                print(f"✅ Email del creador agregado a destinatarios: {user_email}")
            else:
                print("⚠️ No se agregó email del creador (no disponible)")

            # ✅ Agregar email del vendedor
            if vendedor_email and vendedor_email not in destinatarios_to:
                destinatarios_to.append(vendedor_email)
                print(f"✅ Email del vendedor agregado a destinatarios: {vendedor_email}")
            elif vendedor_email:
                print(f"ℹ️ Email del vendedor ya está en la lista: {vendedor_email}")
            else:
                print("⚠️ No se agregó email del vendedor (no disponible)")

            print(f"📧 Destinatarios TO finales: {destinatarios_to}")
            
                         
            resultado_email = enviar_correo_universal(
                template_path='Emails/Ventas/Cotiz/RecepcionCotizacionMail.html',
                asunto=f'📋 Nueva Cotización {costing_num} - V{version} - {data.get("CRM_ContactName", "Cliente")}',
                mail_list_id=2001,
                template_data=template_data,
                archivos_adjuntos=archivos_adjuntos,
                destinatarios_adicionales={
                    'TO': destinatarios_to,
                    'CC': ['jescad27@gmail.com']
                }
            )
            
            email_info = {
                'email_enviado': resultado_email['success'],
                'email_mensaje': resultado_email['mensaje'],
                'email_destinatarios': resultado_email['destinatarios']['total_destinatarios']
            }
            
            if resultado_email['success']:
                print(f"✅ Email enviado correctamente")
                print(f"   Destinatarios: {resultado_email['destinatarios']['total_destinatarios']}")
                print(f"✅ Email del creador agregado a destinatarios: {user_email}")
            else:
                print(f"⚠️ Advertencia: No se pudo enviar email - {resultado_email['mensaje']}")
            
        except Exception as e:
            print(f"❌ Error al enviar email: {str(e)}")
            import traceback
            traceback.print_exc()
            email_info = {
                'email_enviado': False,
                'email_mensaje': f'Error al enviar email: {str(e)}',
                'email_destinatarios': 0
            }
        
        # Al final del controlador, ANTES de limpiar
        import time

        # Esperar un momento para que Puppeteer libere el archivo
        time.sleep(1)

        # Limpiar archivo temporal
        try:
            if os.path.exists(output_path):
                print(f"🔍 Intentando eliminar: {output_path}")
                print(f"🔍 Archivo existe: {os.path.exists(output_path)}")
                print(f"🔍 Permisos: {oct(os.stat(output_path).st_mode)[-3:]}")
                
                os.remove(output_path)
                print(f"✅ Archivo temporal eliminado: {output_path}")
            else:
                print(f"⚠️ Archivo no existe: {output_path}")
        except PermissionError as e:
            print(f"❌ Error de permisos al eliminar: {e}")
            print(f"💡 El archivo podría estar siendo usado por otro proceso")
        except Exception as e:
            print(f"❌ Error al eliminar archivo temporal: {str(e)}")
            import traceback
            traceback.print_exc()
            
            
        # ✅ NUEVO: Limpiar archivo temporal de datos JSON (por si quedó)
        try:
            temp_data_file = os.path.join(output_dir, f"temp_data_{token}.json")
            if os.path.exists(temp_data_file):
                os.remove(temp_data_file)
                print(f"🗑️ Archivo temporal JSON eliminado: {temp_data_file}")
        except Exception as e:
            print(f"⚠️ No se pudo eliminar archivo temporal JSON: {str(e)}")
                    
                    
        
        print("=" * 80)
        print("✅ PROCESO COMPLETADO EXITOSAMENTE")
        print("=" * 80)
        
        return jsonify({
            "success": True,
            "pdf_url": pdf_url,
            "pdf_ruta_ftp": carpeta_relativa,
            "version": version,
            "message": "PDF generado, subido y enviado por email exitosamente",
            **email_info
        }), 200
                
    except Exception as e:
        print(f"\n❌ ERROR CRÍTICO: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({"success": False, "error": str(e)}), 500