from flask import render_template, redirect, url_for, flash, request, current_app, session, jsonify
from datetime import datetime
from app.forms import InvoiceUploadForm
from app.models import InvoiceLead
from app.services import send_lead_notification_email, send_savings_report_email
from werkzeug.utils import secure_filename
import os
import json
import logging
from functools import wraps
from flask_login import login_required, current_user
from flask_wtf.csrf import CSRFProtect, generate_csrf
from . import commercial_invoice_bp
from app.extensions import db

# Decorador para verificar que el usuario tiene el rol de comercial o es administrador
def comercial_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not current_user.is_authenticated:
            flash('Debes iniciar sesión para acceder a esta página.', 'warning')
            return redirect(url_for('auth.login', next=request.path))
        
        # Permitir acceso a Super Admin/Administrador y Comercial
        if not hasattr(current_user, 'has_role') or (
            not (current_user.has_role('Super Admin') or current_user.has_role('Super Administrador')) and 
            not current_user.has_role('Comercial')
        ):
            flash('Acceso restringido. Solo personal comercial autorizado puede acceder.', 'danger')
            return redirect(url_for('public.home'))
            
        return f(*args, **kwargs)
    return decorated_function

# Comprobar dependencias disponibles
DEPENDENCIAS_COMPLETAS = True
# Variable para controlar disponibilidad del LLM
LLM_AVAILABLE = False

try:
    # Importar dependencias principales
    from app.services.tariff_detector import TariffDetector, OCR_AVAILABLE
    from app.services.energy_calculator import EnergyCalculator, PANDAS_AVAILABLE
    from app.services.tariff_comparison import TariffComparison
    
    # Intentar importar cliente LLM para DeepSeek
    try:
        from app.services.llm_multi_provider import extract_with_llm
        LLM_AVAILABLE = True
        logging.info("Cliente LLM multi-proveedor cargado correctamente")
    except ImportError as e:
        logging.warning(f"Cliente LLM no disponible: {e}")
        LLM_AVAILABLE = False
    
    if not OCR_AVAILABLE:
        logging.warning("Módulos OCR no disponibles. La detección automática será limitada.")
        
    if not PANDAS_AVAILABLE:
        logging.warning("pandas/numpy no disponibles. Análisis de datos limitado.")
        
    # Si alguna dependencia falta, ajustar comportamiento
    DEPENDENCIAS_COMPLETAS = OCR_AVAILABLE and PANDAS_AVAILABLE
    
except ImportError as e:
    logging.error(f"Error al importar dependencias críticas: {str(e)}")
    DEPENDENCIAS_COMPLETAS = False
    # Definir clases ficticias para evitar errores
    TariffDetector = type('TariffDetector', (), {})
    EnergyCalculator = type('EnergyCalculator', (), {})

# Helper para verificar extensiones permitidas
def allowed_file(filename, allowed_extensions=None):
    """Verifica si el archivo es un tipo permitido"""
    if allowed_extensions is None:
        allowed_extensions = ['pdf', 'jpg', 'jpeg', 'png']
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in allowed_extensions

def calculate_annual_consumption(energy_consumption, billing_days):
    """Calcula el consumo anual estimado basado en el consumo del período de facturación"""
    if not energy_consumption or billing_days <= 0:
        return 0
    
    total_consumption = sum(v for v in energy_consumption.values() if v is not None) if isinstance(energy_consumption, dict) else 0
    if total_consumption <= 0:
        return 0
    
    # Extrapolate to annual consumption
    return (total_consumption * 365) / billing_days

@commercial_invoice_bp.route('/estudio-gratuito', methods=['GET', 'POST'])
@login_required
@comercial_required
def estudio_gratuito():
    """Procesa las solicitudes de estudio de facturas (comercial)"""
    current_app.logger.info(f"[COM] Request method: {request.method}")
    
    # Limpiar datos antiguos de la sesión cuando se carga la página
    if request.method == 'GET':
        # Conservar solo datos necesarios para manejo de usuario/sesión
        keys_to_keep = ['_fresh', '_user_id', 'csrf_token']
        keys_to_remove = [key for key in list(session.keys()) if key not in keys_to_keep]
        for key in keys_to_remove:
            session.pop(key, None)
        current_app.logger.info("[COM] Datos antiguos eliminados de la sesión")
    
    form = InvoiceUploadForm()
    detection_available = DEPENDENCIAS_COMPLETAS
    
    if form.validate_on_submit():
        current_app.logger.info(f"[COM] Form data: {request.form}")
        current_app.logger.info(f"[COM] Request files: {request.files}")
        
        # Limpiar datos de sesión anteriores al procesar un nuevo archivo
        keys_to_keep = ['_fresh', '_user_id', 'csrf_token']
        keys_to_remove = [key for key in list(session.keys()) if key not in keys_to_keep]
        for key in keys_to_remove:
            session.pop(key, None)
        current_app.logger.info("[COM] Datos antiguos eliminados de la sesión al iniciar nuevo procesamiento")
        
        # Verificar que tengamos al menos un archivo (factura PDF o foto)
        if 'invoice_file' not in request.files and 'invoice_photo' not in request.files:
            flash('No se seleccionó ningún archivo.', 'error')
            return redirect(request.url)
            
        # Determinar qué archivo usar (priorizar PDF si ambos están presentes)
        if 'invoice_file' in request.files and request.files['invoice_file'].filename:
            file = request.files['invoice_file']
            file_type = "pdf"
            current_app.logger.info(f"[COM] Procesando archivo PDF: {file.filename}")
        elif 'invoice_photo' in request.files and request.files['invoice_photo'].filename:
            file = request.files['invoice_photo']
            file_type = "photo"
            current_app.logger.info(f"[COM] Procesando foto de factura: {file.filename}")
        else:
            flash('Ningún archivo seleccionado.', 'error')
            current_app.logger.warning("[COM] No se encontró nombre de archivo válido.")
            return redirect(request.url)

        # Verificar extensión del archivo según tipo
        allowed_extensions = ['pdf'] if file_type == "pdf" else ['jpg', 'jpeg', 'png']
        if file and allowed_file(file.filename, allowed_extensions):
            filename = secure_filename(file.filename)
            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            new_filename = f"{timestamp}_{filename}"
            
            # Guardar archivo en el sistema de archivos local
            uploads_dir = os.path.join(current_app.instance_path, 'uploads')
            
            # Crear el directorio si no existe
            if not os.path.exists(uploads_dir):
                os.makedirs(uploads_dir)
                
            file_path = os.path.join(uploads_dir, new_filename)
            file.save(file_path)
            
            # Para fotos, debemos convertirlas a PDF si queremos usar OCR
            if file_type == "photo":
                try:
                    from PIL import Image
                    import tempfile
                    
                    # Convertir la imagen a PDF para procesamiento
                    img = Image.open(file_path)
                    pdf_path = f"{file_path.rsplit('.', 1)[0]}.pdf"
                    
                    # Si la imagen está en RGB, convertirla a modo RGB para guardar como PDF
                    if img.mode != "RGB":
                        img = img.convert("RGB")
                    
                    img.save(pdf_path, "PDF")
                    current_app.logger.info(f"[COM] Imagen convertida a PDF: {pdf_path}")
                    
                    # Usar el PDF para detección
                    ocr_file_path = pdf_path
                except Exception as e:
                    current_app.logger.error(f"[COM] Error al convertir imagen a PDF: {str(e)}")
                    ocr_file_path = file_path  # Usar la imagen original como fallback
            else:
                ocr_file_path = file_path
            
            try:
                # Crear el lead en la base de datos
                full_name = f"{form.name.data} {form.surname.data}"
                lead = InvoiceLead(
                    name=full_name,
                    email=form.email.data,
                    phone=form.phone.data,  # Ahora es obligatorio
                    cups=None,  # Ya no solicitamos CUPS en el formulario inicial
                    file_path=file_path,
                    message=form.message.data if form.message.data else None,
                    rgpd_consent=form.rgpd_consent.data,
                    status='pending',
                    channel='commercial',  # Canal comercial
                    created_by_user_id=current_user.id  # Usuario comercial que creó el lead
                )
                db.session.add(lead)
                db.session.commit()
                
                # Comprobar si tenemos todas las dependencias para la detección automática
                if detection_available:
                    try:
                        # Inicializar detector de peaje y procesar archivo
                        current_app.logger.info(f"[COM] Iniciando análisis de factura: {ocr_file_path}")
                        
                        # 1. Primero extraer el texto completo del PDF para ambos métodos
                        detector = TariffDetector()
                        extracted_text = detector._extract_text_from_pdf(ocr_file_path)
                        
                        # 2. Intentar extracción con LLM si está disponible
                        llm_result = None
                        if LLM_AVAILABLE:
                            current_app.logger.info("[COM] Intentando extracción con DeepSeek LLM...")
                            llm_result = extract_with_llm(extracted_text)
                            current_app.logger.info(f"[COM] Extracción LLM completada: {llm_result is not None}")
                        
                        # 3. Obtener resultado con detector regex tradicional
                        current_app.logger.info("[COM] Procesando con extractor regex tradicional...")
                        regex_result = detector.detect_from_text(extracted_text)
                        
                        # 4. Combinar resultados (LLM tiene prioridad, regex para completar datos faltantes)
                        if llm_result:
                            current_app.logger.info("[COM] Usando resultado LLM como base")
                            detection_result = llm_result
                            # Completar datos faltantes con regex
                            for key, value in regex_result.items():
                                if detection_result.get(key) in (None, "", {}):
                                    detection_result[key] = value
                                    current_app.logger.info(f"[COM] Completando campo '{key}' con datos regex")
                        else:
                            current_app.logger.info("[COM] Usando solo resultado regex")
                            detection_result = regex_result
                        
                        # Registrar en log los resultados obtenidos
                        current_app.logger.info(f"[COM] Datos extraídos: {list(detection_result.keys())}")
                        current_app.logger.info(f"[COM] CUPS detectado: {detection_result.get('cups', 'No detectado')}")
                        current_app.logger.info(f"[COM] Tarifa detectada: {detection_result.get('tariff', 'No detectada')}")
                        current_app.logger.info(f"[COM] Cliente: {detection_result.get('client_name', 'No detectado')}")
                        current_app.logger.info(f"[COM] Dirección: {detection_result.get('supply_address', 'No detectada')}")
                        current_app.logger.info(f"[COM] Periodos potencia: {detection_result.get('power_periods', {})}")
                        current_app.logger.info(f"[COM] Consumos energía: {detection_result.get('energy_consumption', {})}")
                        current_app.logger.info(f"[COM] Método usado: {'LLM+Regex' if llm_result else 'Solo Regex'}")
                        
                        # Guardar archivo con resultado combinado para diagnóstico
                        try:
                            with open('llm_extraction_results_commercial.json', 'w', encoding='utf-8') as f:
                                import json
                                json.dump({"llm": llm_result, "regex": regex_result, "final": detection_result}, f, indent=2, ensure_ascii=False)
                        except Exception as e:
                            current_app.logger.warning(f"[COM] No se pudo guardar archivo de diagnóstico: {e}")
                        
                        # Guardar los resultados en la sesión para procesamiento posterior
                        # Si se detectó un CUPS, actualizar el lead en la base de datos
                        if detection_result.get('cups'):
                            lead.cups = detection_result['cups']
                            db.session.commit()

                        # Guardar los resultados esenciales en la sesión para el siguiente paso
                        session['lead_id'] = lead.id
                        
                        # Mapear los campos de fechas del periodo de facturación
                        if 'billing_start' in detection_result and detection_result['billing_start']:
                            detection_result['billing_start_date'] = detection_result['billing_start']
                        if 'billing_end' in detection_result and detection_result['billing_end']:
                            detection_result['billing_end_date'] = detection_result['billing_end']
                        
                        # Reducir tamaño guardando solo datos esenciales
                        if 'original_text' in detection_result:
                            detection_result['original_text_preview'] = detection_result['original_text'][:100] + '...'
                            del detection_result['original_text']
                            current_app.logger.info("[COM] Texto original reducido para evitar exceder el tamaño de sesión")
                        session['detection_result'] = detection_result
                        
                        # Almacenar datos completos asociados al lead
                        lead.details = detection_result
                        db.session.commit()
                        
                        # Redirigir a la página de confirmación
                        return redirect(url_for('commercial_invoice.confirm_tariff'))
                    
                    except Exception as e:
                        current_app.logger.error(f"[COM] Error en la detección de peaje: {str(e)}")
                        detection_available = False  # Desactivar la detección si falla
                
                # Flujo alternativo cuando la detección automática no está disponible
                if not detection_available:
                    mock_detection = {
                        'tariff': '2.0TD',
                        'power_contracted': None,
                        'reliable_detection': False,
                        'original_text': ''
                    }
                    session['lead_id'] = lead.id
                    session['detection_result'] = mock_detection
                    lead.status = 'needs_review'
                    db.session.commit()
                    flash('Gracias por tu factura. Por favor, confirma el tipo de peaje para continuar.', 'info')
                    return redirect(url_for('commercial_invoice.confirm_tariff'))
                
            except Exception as e:
                current_app.logger.error(f"[COM] Error al procesar el lead: {str(e)}")
                flash('Error al procesar tu solicitud. Por favor, inténtalo de nuevo más tarde.', 'error')
        else:
            flash('Tipo de archivo no permitido. Por favor, sube un archivo PDF.', 'error')
            
    current_app.logger.info("[COM] Renderizando plantilla estudio_gratuito.html")
    return render_template('commercial_invoice/estudio_gratuito.html', title="Comparador Gratuito (Comercial)", form=form)


@commercial_invoice_bp.route('/confirmar-peaje', methods=['GET', 'POST'])
@login_required
@comercial_required
def confirm_tariff():
    """Permite al usuario confirmar los datos extraídos de la factura (comercial)"""
    current_app.logger.info("[COM] ========== Entrando a confirm_tariff ==========")
    current_app.logger.info(f"[COM] Datos en sesión: {list(session.keys())}")
    
    # Verificar que estamos utilizando los datos de la sesión correctos
    lead_id = session.get('lead_id')
    if lead_id:
        current_app.logger.info(f"[COM] Lead ID en sesión: {lead_id}")
        lead = InvoiceLead.query.get(lead_id)
        if lead:
            current_app.logger.info(f"[COM] Lead encontrado: {lead.id} - {lead.name} - {lead.file_path}")
    
    if 'detection_result' not in session:
        current_app.logger.error("[COM] No se encontró detection_result en la sesión")
        flash('Se produjo un error en el procesamiento. Por favor, intenta de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    detection = session.get('detection_result', {})
    
    # Validar que los datos corresponden al lead actual
    lead_id = session.get('lead_id')
    lead = None
    if lead_id:
        lead = InvoiceLead.query.get(lead_id)
        if lead:
            file_name = os.path.basename(lead.file_path) if lead.file_path else "(sin archivo)"
            current_app.logger.info(f"[COM] Validando datos para lead ID={lead_id}, archivo={file_name}")
            detected_cups = detection.get('cups', 'No disponible')
            if lead.cups and lead.cups != detected_cups and detected_cups != 'No disponible':
                current_app.logger.warning(f"[COM] DISCREPANCIA: CUPS del lead ({lead.cups}) != CUPS detectado ({detected_cups})")
    
    current_app.logger.info(f"[COM] Datos detectados: {list(detection.keys())}")
    current_app.logger.info(f"[COM] CUPS: {detection.get('cups', 'No disponible')}")
    current_app.logger.info(f"[COM] Tarifa: {detection.get('tariff', 'No disponible')}")
    current_app.logger.info(f"[COM] Cliente: {detection.get('client_name', 'No disponible')}")
    current_app.logger.info(f"[COM] Potencia contratada: {detection.get('power_contracted', 'No disponible')}")
    current_app.logger.info(f"[COM] Periodos potencia: {detection.get('power_periods', {})}")
    current_app.logger.info(f"[COM] Consumos energía: {detection.get('energy_consumption', {})}")
    current_app.logger.info(f"[COM] Energía reactiva: {detection.get('reactive_energy', {})}")
    current_app.logger.info(f"[COM] Precios energía reactiva: {detection.get('reactive_energy_prices', {})}")
    
    if request.method == 'POST':
        current_app.logger.info("[COM] Procesando confirmación de datos de factura")
        
        # Actualizar datos generales
        detection['client_name'] = request.form.get('client_name', detection.get('client_name', ''))
        detection['cups'] = request.form.get('cups', detection.get('cups', ''))
        detection['supply_address'] = request.form.get('supply_address', detection.get('supply_address', ''))
        detection['provider_name'] = request.form.get('provider_name', detection.get('provider_name', ''))
        detection['invoice_date'] = request.form.get('invoice_date', detection.get('invoice_date', ''))
        detection['billing_start_date'] = request.form.get('billing_start_date', detection.get('billing_start_date', ''))
        detection['billing_end_date'] = request.form.get('billing_end_date', detection.get('billing_end_date', ''))
        detection['billing_days'] = request.form.get('billing_days', detection.get('billing_days', ''))
        
        # Procesar consumo anual estimado
        annual_consumption = request.form.get('annual_consumption')
        if annual_consumption:
            try:
                detection['annual_consumption'] = float(annual_consumption)
                current_app.logger.info(f"[COM] Consumo anual actualizado: {detection['annual_consumption']} kWh")
            except (ValueError, TypeError):
                current_app.logger.warning(f"[COM] Valor de consumo anual inválido: {annual_consumption}")
                detection['annual_consumption'] = detection.get('annual_consumption', 0)

        # Actualizar el peaje seleccionado por el usuario
        selected_tariff = request.form.get('tariff_type')
        if selected_tariff in ['2.0TD', '3.0TD', '6.1TD']:
            detection['tariff'] = selected_tariff
            detection['reliable_detection'] = True
        else:
            current_app.logger.warning(f"[COM] Tipo de peaje no válido seleccionado: {selected_tariff}")
            flash('Tipo de peaje no válido. Se usará el detectado.', 'warning')

        # Función auxiliar para procesar valores numéricos
        def safe_float(value_str):
            if not value_str:
                return None
            try:
                return float(value_str.replace(',', '.'))
            except (ValueError, TypeError):
                return None

        # Procesar periodos de potencia, consumo, precios y energía reactiva
        for period_type in ['power_periods', 'energy_prices', 'energy_consumption', 'power_prices', 'reactive_energy', 'reactive_energy_prices']:
            if period_type not in detection or detection[period_type] is None:
                detection[period_type] = {}
            for period_key in ['P1', 'P2', 'P3', 'P4', 'P5', 'P6']:
                form_field_name = f"{period_type}_{period_key}"
                if form_field_name in request.form:
                    value = safe_float(request.form.get(form_field_name))
                    if value is not None:
                        detection[period_type][period_key] = value
                        current_app.logger.debug(f"[COM] Actualizado {period_type}.{period_key} = {value}")

        # Guardar todos los datos actualizados en la sesión
        session['detection_result'] = detection
        current_app.logger.info(f"[COM] Datos de factura actualizados y guardados en sesión: {detection.keys()}")
        
        # Actualizar el CUPS en la base de datos si ha cambiado
        lead_id = session.get('lead_id')
        if lead_id:
            lead = InvoiceLead.query.get(lead_id)
            if lead and lead.cups != detection.get('cups'):
                lead.cups = detection.get('cups')
                db.session.commit()
                current_app.logger.info(f"[COM] CUPS actualizado en BD para lead {lead_id}: {detection.get('cups')}")

        return redirect(url_for('commercial_invoice.calculate_savings'))
    
    # Asegurarse de que existan claves esperadas
    for key in ['reactive_energy', 'reactive_energy_prices']:
        if key not in detection:
            detection[key] = {}
            
    power_price_unit = 'año'
    
    def detect_power_price_unit(price):
        if price > 10:
            return 'año'
        elif price > 0.5:
            return 'mes'
        else:
            return 'día'
    
    power_prices = detection.get('power_prices', {})
    for period, price in power_prices.items():
        if price is not None and price > 0:
            power_price_unit = detect_power_price_unit(price)
            current_app.logger.info(f"[COM] Unidad de precio de potencia detectada: €/kW/{power_price_unit} (basado en {period}: {price})")
            break
    
    detection['power_price_unit'] = power_price_unit
    
    # Generar un token CSRF para el formulario
    csrf_token = generate_csrf()
    
    return render_template('commercial_invoice/confirm_tariff.html', 
                           title="Confirmar Datos de Factura (Comercial)", 
                           detection=detection,
                           csrf_token=csrf_token)


@commercial_invoice_bp.route('/calcular-ahorro', methods=['POST', 'GET'])
@login_required
@comercial_required
def calculate_savings():
    """Cálculo de ahorro basándonos en los datos de factura confirmados (comercial)"""
    lead_id = session.get('lead_id')
    detection_result = session.get('detection_result')
    
    if not lead_id or not detection_result:
        flash('Sesión expirada o datos faltantes. Por favor, comienza de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    # Recuperar lead de la base de datos
    lead = InvoiceLead.query.get(lead_id)
    
    if not lead or not os.path.exists(lead.file_path):
        flash('No se encontró el archivo de factura asociado.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    current_app.logger.info(f"[COM] Iniciando cálculo de ahorro con datos de factura: {detection_result.keys()}")
    
    try:
        tariff_type = detection_result.get('tariff', '2.0TD')
        current_app.logger.info(f"[COM] Tipo de tarifa: {tariff_type}")
        
        # Diagnóstico
        current_app.logger.info(f"[COM] DIAGNOSTICO DE DATOS - Claves: {list(detection_result.keys())}")
        if (not detection_result.get('energy_consumption') and not detection_result.get('consumption')) or \
           (len(detection_result.get('energy_consumption', {})) == 0 and len(detection_result.get('consumption', {})) == 0):
            current_app.logger.warning("[COM] Advertencia: Datos de consumo incompletos o faltantes")
        else:
            current_app.logger.info(f"[COM] Consumo OK: {detection_result.get('energy_consumption') or detection_result.get('consumption')}")
        if (not detection_result.get('power_periods') and not detection_result.get('power_contracted') and not detection_result.get('power')) or \
           (len(detection_result.get('power_periods', {})) == 0 and len(detection_result.get('power_contracted', {})) == 0 and len(detection_result.get('power', {})) == 0):
            current_app.logger.warning("[COM] Advertencia: Datos de potencia incompletos o faltantes")
        else:
            current_app.logger.info(f"[COM] Potencia OK: {detection_result.get('power_periods') or detection_result.get('power_contracted') or detection_result.get('power')}")
        if not detection_result.get('energy_prices') or len(detection_result.get('energy_prices', {})) == 0:
            current_app.logger.warning("[COM] Advertencia: Precios de energía incompletos o faltantes")
        else:
            current_app.logger.info(f"[COM] Precios energía OK: {detection_result.get('energy_prices')}")
        if not detection_result.get('power_prices') or len(detection_result.get('power_prices', {})) == 0:
            current_app.logger.warning("[COM] Advertencia: Precios de potencia incompletos o faltantes")
        else:
            current_app.logger.info(f"[COM] Precios potencia OK: {detection_result.get('power_prices')}")
        
        # Obtener datos de potencia contratada
        power_periods = detection_result.get('power_periods', {})
        if not power_periods:
            current_app.logger.warning("[COM] No se encontraron datos de potencia contratada")

        # Días de facturación
        billing_days = 30
        try:
            if detection_result.get('billing_days'):
                billing_days = int(detection_result.get('billing_days'))
            elif detection_result.get('billing_start_date') and detection_result.get('billing_end_date'):
                try:
                    from datetime import datetime
                    start_date = datetime.strptime(detection_result.get('billing_start_date'), '%d/%m/%Y')
                    end_date = datetime.strptime(detection_result.get('billing_end_date'), '%d/%m/%Y')
                    billing_days = (end_date - start_date).days + 1
                except Exception as e:
                    current_app.logger.warning(f"[COM] No se pudieron calcular días a partir de fechas: {e}")
        except (ValueError, TypeError) as e:
            current_app.logger.warning(f"[COM] Error al procesar días de facturación: {e}")
        
        current_app.logger.info(f"[COM] Días de facturación: {billing_days}")
        
        # Inicializar el servicio de comparación de tarifas
        tariff_comparison = TariffComparison()
        matching_rate = tariff_comparison.find_matching_rate(tariff_type)
        attempt_real_calculation = True

        if matching_rate:
            try:
                invoice_data = {
                    'energy_prices': detection_result.get('energy_prices', {}),
                    'power_periods': power_periods,
                    'energy_consumption': detection_result.get('energy_consumption', {}),
                    'power_prices': detection_result.get('power_prices', {}),
                    'billing_days': billing_days,
                    'total_cost': 0
                }
                current_app.logger.info("[COM] Procediendo con el cálculo usando los datos disponibles")
                
                current_app.logger.info(f"[COM] Datos preparados para cálculo: {invoice_data.keys()}")
                
                client_data = {
                    "current_energy_prices": invoice_data.get('energy_prices', {}),
                    "current_power_prices": invoice_data.get('power_prices', {}),
                    "consumption": invoice_data.get('energy_consumption', {}),
                    "power": invoice_data.get('power_periods', {}),
                    "billing_period_days": invoice_data.get('billing_days', 30),
                    "reactive_energy": detection_result.get('reactive_energy', {}),
                    "reactive_energy_prices": detection_result.get('reactive_energy_prices', {}),
                    "reactive_energy_total_cost": detection_result.get('reactive_energy_total_cost')
                }
                
                if detection_result.get('reactive_energy') or detection_result.get('reactive_energy_total_cost'):
                    current_app.logger.info(f"[COM] Reactiva incluida: {detection_result.get('reactive_energy')}")
                    current_app.logger.info(f"[COM] Precios reactiva incluidos: {detection_result.get('reactive_energy_prices')}")
                    current_app.logger.info(f"[COM] Coste total reactiva extraído: {detection_result.get('reactive_energy_total_cost')}")
                    if detection_result.get('reactive_energy_total_cost'):
                        current_app.logger.info("[COM] USANDO COSTE TOTAL EXTRAÍDO para el cálculo de energía reactiva")
                    else:
                        current_app.logger.info("[COM] Calculando coste de reactiva por períodos")
                
                current_app.logger.info("[COM] Iniciando cálculo de ahorro con TariffComparison")
                savings_data = tariff_comparison.calculate_savings(client_data, matching_rate)
                
                if savings_data:
                    current_app.logger.info(f"[COM] Cálculo exitoso: {savings_data.keys()}")
                    current_cost = savings_data.get('current_total_cost', 0)
                    ole_cost = savings_data.get('new_total_cost', 0)
                    monthly_savings = max(current_cost - ole_cost, 0)
                    savings_percent = (monthly_savings / current_cost * 100) if current_cost > 0 else 0
                    
                    reactive_energy_penalty = savings_data.get('reactive_energy_penalty', 0) or 0
                    power_excess_penalty = detection_result.get('power_excess_penalty', 0) or 0
                    
                    try:
                        if reactive_energy_penalty is None:
                            reactive_energy_penalty = 0
                        else:
                            reactive_energy_penalty = float(reactive_energy_penalty)
                    except (ValueError, TypeError):
                        reactive_energy_penalty = 0
                    
                    try:
                        if power_excess_penalty is None:
                            power_excess_penalty = 0
                        else:
                            power_excess_penalty = float(power_excess_penalty)
                    except (ValueError, TypeError):
                        power_excess_penalty = 0
                    
                    results = {
                        'yearly_savings': (monthly_savings / billing_days) * 365 if monthly_savings > 0 and billing_days and billing_days > 0 else 0,
                        'savings_percentage': savings_percent,
                        'monthly_savings': monthly_savings,
                        'estimation_reliability': 'Personalizado',
                        'call_recommended': savings_data.get('savings_percentage', 0) > 5,
                        'current_cost': current_cost,
                        'ole_cost': ole_cost,
                        'best_rate_name': matching_rate.get('name', ''),
                        'best_rate_supplier': matching_rate.get('supplier', ''),
                        'tariff_type': tariff_type,
                        'reactive_energy_penalty': reactive_energy_penalty,
                        'power_excess_penalty': power_excess_penalty,
                        'power_price_unit': detection_result.get('power_price_unit', 'año'),
                        'demo_mode': False
                    }
                    
                    current_app.logger.info(f"[COM] Valores pasados a plantilla - reactive_penalty: {results['reactive_energy_penalty']}")
                else:
                    raise ValueError("El servicio de comparación no devolvió datos de ahorro válidos")
            except Exception as e:
                error_message = str(e)
                current_app.logger.error(f"[COM] Error en el cálculo de ahorro real: {error_message}")
                attempt_real_calculation = False
                session['calculation_error'] = {
                    'message': error_message,
                    'missing_data': [],
                }
                if 'datos de consumo' in error_message.lower():
                    session['calculation_error']['missing_data'].append('consumption')
                if 'datos de potencia' in error_message.lower():
                    session['calculation_error']['missing_data'].append('power')
                current_app.logger.debug(f"[COM] Datos en sesión durante error: {list(detection_result.keys())}")
                current_app.logger.debug(f"[COM] Energy: {detection_result.get('energy_consumption', {})}")
                current_app.logger.debug(f"[COM] Power: {detection_result.get('power_periods', {})}")
                current_app.logger.debug(f"[COM] Energy prices: {detection_result.get('energy_prices', {})}")
                current_app.logger.debug(f"[COM] Power prices: {detection_result.get('power_prices', {})}")
        
        if 'results' not in locals() or not results:
            current_app.logger.warning("[COM] No se pudo realizar el cálculo real, usando valores mínimos")
            power_cost = sum((detection_result.get('power_prices', {}).get(p, 0) or 0) * (detection_result.get('power_periods', {}).get(p, 0) or 0) / 12 
                            for p in detection_result.get('power_periods', {}).keys())
            energy_cost = sum((detection_result.get('energy_prices', {}).get(p, 0) or 0) * (detection_result.get('energy_consumption', {}).get(p, 0) or 0) 
                            for p in detection_result.get('energy_consumption', {}).keys())
            total_cost = max((power_cost or 0) + (energy_cost or 0), 100)
            ole_cost = total_cost * 0.9
            monthly_savings = total_cost - ole_cost
            demo_reactive_penalty = 0
            demo_power_excess = 0
            results = {
                'yearly_savings': monthly_savings * 12,
                'savings_percentage': 10.0,
                'monthly_savings': monthly_savings,
                'estimation_reliability': 'Calculado',
                'call_recommended': True,
                'current_cost': total_cost,
                'ole_cost': ole_cost,
                'tariff_type': tariff_type,
                'reactive_energy_penalty': demo_reactive_penalty,
                'power_excess_penalty': demo_power_excess,
                'power_price_unit': 'año',
                'demo_mode': False
            }
        
        session['savings_results'] = results
        # Obtener datos del lead para completar información del cliente
        lead = InvoiceLead.query.get(lead_id) if lead_id else None
        
        session['confirmed_invoice_data'] = {
            'client_name': detection_result.get('client_name', lead.name if lead else ''),
            'client_email': lead.email if lead else '',
            'client_phone': lead.phone if lead else '',
            'cups': detection_result.get('cups', ''),
            'supply_address': detection_result.get('supply_address', ''),
            'provider_name': detection_result.get('provider_name', ''),
            'tariff_type': tariff_type,
            'billing_period': f"{detection_result.get('billing_start_date', '')} a {detection_result.get('billing_end_date', '')}",
            'billing_days': billing_days,
            'annual_consumption': calculate_annual_consumption(detection_result.get('energy_consumption', {}), billing_days),
            'current_annual_cost': (results.get('current_cost', 0) or 0) * (365 / billing_days) if results.get('current_cost') and billing_days and billing_days > 0 else 0
        }
        
        # Guardar resultados temporalmente en el lead
        lead.details = {
            'detected_tariff': tariff_type,
            'cups': detection_result.get('cups', ''),
            'client_name': detection_result.get('client_name', ''),
            'supply_address': detection_result.get('supply_address', ''),
            'provider_name': detection_result.get('provider_name', ''),
            'billing_start': detection_result.get('billing_start_date', ''),
            'billing_end': detection_result.get('billing_end_date', ''),
            'billing_days': billing_days,
            'power_periods': detection_result.get('power_periods', {}),
            'energy_consumption': detection_result.get('energy_consumption', {}),
            'energy_prices': detection_result.get('energy_prices', {}),
            'power_prices': detection_result.get('power_prices', {}),
            'calculation_timestamp': 'Calculado',
            'calculation_version': '1.1'
        }
        lead.status = 'in_progress'
        db.session.commit()
        
        # En lugar de ir directamente al resultado, mostrar los planes disponibles
        session['plans_results'] = results
        
        # Redirigir a la selección de planes para comerciales
        return redirect(url_for('commercial_invoice.plans_selection'))
        
    except Exception as e:
        current_app.logger.error(f"[COM] Error en el cálculo de ahorro: {str(e)}")
        flash('Error al procesar los cálculos. Por favor, intenta de nuevo más tarde.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))


@commercial_invoice_bp.route('/planes-disponibles')
@login_required
@comercial_required
def plans_selection():
    """Muestra todos los planes disponibles para selección por el comercial"""
    if 'plans_results' not in session or 'lead_id' not in session:
        flash('Se produjo un error en el procesamiento. Por favor, intenta de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    lead_id = session.get('lead_id')
    initial_results = session.get('plans_results', {})
    invoice_data = session.get('confirmed_invoice_data', {})
    detection_result = session.get('detection_result', {})
    
    try:
        # Recuperar lead de la base de datos
        lead = InvoiceLead.query.get(lead_id)
        if not lead:
            flash('No se encontró la solicitud en nuestra base de datos.', 'error')
            return redirect(url_for('commercial_invoice.estudio_gratuito'))
        
        # Obtener datos de tarificación y consumo
        tariff_type = invoice_data.get('tariff_type', '2.0TD')
        
        # Inicializar el servicio de comparación de tarifas para obtener todos los planes
        tariff_comparison = TariffComparison()
        all_rates = tariff_comparison.get_all_rates(tariff_type)
        
        # Logging para diagnosticar el problema de planes
        current_app.logger.info(f"[COM] Diagnóstico de planes - Tariff type: {tariff_type}")
        current_app.logger.info(f"[COM] Total de rates obtenidas: {len(all_rates)}")
        for i, rate in enumerate(all_rates):
            current_app.logger.info(f"[COM] Plan {i+1}: {rate.get('name')} - {rate.get('supplier')} - Valid: {rate.get('valid_from')} to {rate.get('valid_until')}")
        
        # Preparar datos del cliente para el cálculo
        client_data = {
            "current_energy_prices": detection_result.get('energy_prices', {}),
            "current_power_prices": detection_result.get('power_prices', {}),
            "consumption": detection_result.get('energy_consumption', {}),
            "power": detection_result.get('power_periods', {}),
            "billing_period_days": invoice_data.get('billing_days', 30),
            "reactive_energy": detection_result.get('reactive_energy', {}),
            "reactive_energy_prices": detection_result.get('reactive_energy_prices', {}),
            "reactive_energy_total_cost": detection_result.get('reactive_energy_total_cost')
        }
        
        # Calcular ahorro para cada plan
        plans_data = []
        
        # Obtener el coste actual del cálculo de ahorro inicial
        # Si no está disponible, calcularlo usando la primera tarifa disponible
        current_cost = initial_results.get('current_cost', 0)
        if current_cost == 0 and all_rates:
            # Calcular con la primera tarifa para obtener el coste actual
            first_rate = all_rates[0]
            initial_calculation = tariff_comparison.calculate_savings(client_data, first_rate)
            if initial_calculation:
                current_cost = initial_calculation.get('current_total_cost', 0)
                current_app.logger.info(f"[COM] Coste actual calculado: {current_cost} €/mes")
        
        for i, rate in enumerate(all_rates):
            try:
                current_app.logger.info(f"[COM] Procesando plan {i+1}/{len(all_rates)}: {rate.get('name')}")
                
                # Calcular ahorro específico para este plan
                plan_savings = tariff_comparison.calculate_savings(client_data, rate)
                
                if plan_savings:
                    ole_cost = plan_savings.get('new_total_cost', 0)
                    monthly_difference = current_cost - ole_cost  # Puede ser positivo (ahorro) o negativo (pérdida)
                    savings_percent = (monthly_difference / current_cost * 100) if current_cost > 0 else 0
                    billing_days_for_calc = invoice_data.get('billing_days', 30)
                    yearly_difference = (monthly_difference / billing_days_for_calc) * 365 if billing_days_for_calc and billing_days_for_calc > 0 else 0
                    
                    # Para comerciales: mostrar tanto ahorros como pérdidas
                    is_savings = monthly_difference >= 0
                    monthly_savings = monthly_difference if is_savings else 0
                    monthly_loss = abs(monthly_difference) if not is_savings else 0
                    yearly_savings = yearly_difference if is_savings else 0
                    yearly_loss = abs(yearly_difference) if not is_savings else 0
                    
                    current_app.logger.info(f"[COM] Plan {rate.get('name')}: Coste actual={current_cost}, Nuevo coste={ole_cost}, Diferencia mensual={monthly_difference}, Ahorro anual={yearly_difference}")
                    
                    # Extraer información adicional para mostrar en las cards
                    power_info = detection_result.get('power_periods', {})
                    total_power = sum(float(p) for p in power_info.values() if p and str(p).replace('.', '').isdigit())
                    
                    plans_data.append({
                        'name': rate.get('name', 'Plan sin nombre'),
                        'supplier': rate.get('supplier', 'OLE Consulting'),
                        'fixed_price': rate.get('fixed_price', False),
                        'contract_duration': rate.get('contract_duration', 12),
                        'yearly_savings': yearly_savings,
                        'monthly_savings': monthly_savings,
                        'yearly_loss': yearly_loss,
                        'monthly_loss': monthly_loss,
                        'is_savings': is_savings,
                        'savings_percentage': abs(savings_percent),  # Mostrar porcentaje absoluto
                        'current_cost': current_cost,
                        'ole_cost': ole_cost,
                        'rate_data': rate,  # Guardar datos completos del plan
                        'energy_prices': rate.get('energy_prices', {}),
                        'power_prices': rate.get('power_prices', {}),
                        'total_power_kw': total_power,
                        'best_option': False  # Se marcará después
                    })
                else:
                    current_app.logger.warning(f"[COM] No se pudo calcular ahorro para el plan {rate.get('name')} - plan_savings es None")
            except Exception as e:
                current_app.logger.error(f"[COM] Error calculando plan {rate.get('name')}: {str(e)}")
                import traceback
                current_app.logger.error(f"[COM] Traceback: {traceback.format_exc()}")
        
        # Ordenar planes: primero ahorros (descendente), luego pérdidas (ascendente)
        plans_data.sort(key=lambda x: (
            -1 if x.get('is_savings', True) else 1,  # Ahorros primero
            -x.get('yearly_savings', 0) if x.get('is_savings', True) else x.get('yearly_loss', 0)
        ))
        
        # Marcar el mejor plan
        if plans_data:
            plans_data[0]['best_option'] = True
        
        # Logging final de diagnóstico
        current_app.logger.info(f"[COM] Planes procesados exitosamente: {len(plans_data)}")
        for i, plan in enumerate(plans_data):
            current_app.logger.info(f"[COM] Plan final {i+1}: {plan['name']} - Ahorro anual: {plan['yearly_savings']:.2f}€")
        
        # Guardar planes en sesión para uso posterior
        session['all_plans_data'] = plans_data
        
        # Renderizar template con todos los planes
        return render_template('Private_Invoice/plans_selection.html',
                              title="Selección de Planes (Comercial)",
                              plans=plans_data,
                              invoice_data=invoice_data,
                              client_name=invoice_data.get('client_name', ''),
                              cups=invoice_data.get('cups', ''),
                              supply_address=invoice_data.get('supply_address', ''),
                              provider_name=invoice_data.get('provider_name', ''),
                              billing_period=invoice_data.get('billing_period', ''),
                              tariff_type=tariff_type)
    
    except Exception as e:
        current_app.logger.error(f"[COM] Error al procesar planes disponibles: {str(e)}")
        flash('Error al procesar los planes disponibles. Por favor, intenta de nuevo más tarde.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))


@commercial_invoice_bp.route('/seleccionar-plan/<int:plan_index>', methods=['GET'])
@login_required
@comercial_required
def select_plan(plan_index):
    """Selecciona un plan específico y muestra el detalle de ahorro"""
    if 'all_plans_data' not in session or 'lead_id' not in session:
        flash('Se produjo un error en el procesamiento. Por favor, intenta de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    plans_data = session.get('all_plans_data', [])
    lead_id = session.get('lead_id')
    invoice_data = session.get('confirmed_invoice_data', {})
    detection_result = session.get('detection_result', {})
    
    try:
        # Verificar que el índice es válido
        if plan_index < 0 or plan_index >= len(plans_data):
            flash('Plan no válido seleccionado.', 'error')
            return redirect(url_for('commercial_invoice.plans_selection'))
        
        # Obtener el plan seleccionado
        selected_plan = plans_data[plan_index]
        
        # Guardar el plan seleccionado en la sesión
        session['savings_results'] = {
            'yearly_savings': selected_plan.get('yearly_savings', 0),
            'monthly_savings': selected_plan.get('monthly_savings', 0),
            'savings_percentage': selected_plan.get('savings_percentage', 0),
            'estimation_reliability': 'Personalizado',
            'call_recommended': selected_plan.get('savings_percentage', 0) > 5,
            'current_cost': selected_plan.get('current_cost', 0),
            'ole_cost': selected_plan.get('ole_cost', 0),
            'best_rate_name': selected_plan.get('name', ''),
            'best_rate_supplier': selected_plan.get('supplier', ''),
            'tariff_type': invoice_data.get('tariff_type', '2.0TD'),
            'reactive_energy_penalty': detection_result.get('reactive_energy_penalty', 0),
            'power_excess_penalty': detection_result.get('power_excess_penalty', 0),
            'power_price_unit': detection_result.get('power_price_unit', 'año'),
            'demo_mode': False
        }
        
        # Actualizar lead en base de datos con el plan seleccionado
        lead = InvoiceLead.query.get(lead_id)
        if lead:
            lead_details = lead.details or {}
            lead_details.update({
                'estimated_savings': selected_plan.get('yearly_savings', 0),
                'savings_percent': selected_plan.get('savings_percentage', 0),
                'best_rate_name': selected_plan.get('name', ''),
                'best_rate_supplier': selected_plan.get('supplier', ''),
                'monthly_savings': selected_plan.get('monthly_savings', 0),
                'reliability': 'Personalizado',
                'current_cost': selected_plan.get('current_cost', 0),
                'ole_cost': selected_plan.get('ole_cost', 0),
                'demo_mode': False,
                'selected_plan_index': plan_index
            })
            lead.details = lead_details
            lead.status = 'completed'
            db.session.commit()
            current_app.logger.info(f"[COM] Plan seleccionado para lead {lead.id}: {selected_plan.get('name')}")
            
            # Enviar correo con el plan seleccionado
            try:
                current_app.logger.info(f"[COM] Enviando correo con resultados para lead {lead.id}")
                send_savings_report_email(lead, session.get('savings_results', {}), lead.file_path)
                current_app.logger.info(f"[COM] Correo enviado exitosamente para lead {lead.id}")
            except Exception as mail_error:
                current_app.logger.error(f"[COM] Error al enviar correo: {str(mail_error)}")
        
        # Redirigir a la página de resultados
        return redirect(url_for('commercial_invoice.saving_result'))
    
    except Exception as e:
        current_app.logger.error(f"[COM] Error al seleccionar plan: {str(e)}")
        flash('Error al seleccionar el plan. Por favor, intenta de nuevo más tarde.', 'error')
        return redirect(url_for('commercial_invoice.plans_selection'))


@commercial_invoice_bp.route('/resultado-ahorro')
@login_required
@comercial_required
def saving_result():
    """Muestra los resultados del cálculo de ahorro (comercial)"""
    if 'savings_results' not in session or 'lead_id' not in session:
        flash('Se produjo un error en el procesamiento. Por favor, intenta de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    results = session.get('savings_results', {})
    invoice_data = session.get('confirmed_invoice_data', {})
    lead_id = session.get('lead_id')
    
    current_app.logger.info(f"[COM] Mostrando resultados para lead_id: {lead_id}, ahorro: {results.get('yearly_savings')}")
    current_app.logger.debug(f"[COM] Datos de factura confirmados: {invoice_data.keys() if invoice_data else 'No disponibles'}")
    
    try:
        lead = InvoiceLead.query.get(lead_id)
        demo_mode = results.get('demo_mode', False)
        client_name = invoice_data.get('client_name', '')
        supply_address = invoice_data.get('supply_address', '')
        provider_name = invoice_data.get('provider_name', '')
        billing_period = invoice_data.get('billing_period', '')
        billing_days = invoice_data.get('billing_days', 30)
        monthly_savings = results.get('yearly_savings', 0) / 12
        reactive_energy_penalty = results.get('reactive_energy_penalty', 0)
        power_excess_penalty = results.get('power_excess_penalty', 0)
        reactive_energy_annual_penalty = reactive_energy_penalty * 7 if reactive_energy_penalty is not None else 0
        current_app.logger.info(f"[COM] Valor mensual de reactive_energy_penalty: {reactive_energy_penalty}")
        current_app.logger.info(f"[COM] Valor anual proyectado (factor 7): {reactive_energy_annual_penalty}")
        
        # Obtener nombre del comercial actual
        commercial_name = current_user.name if current_user.name else current_user.username
        
        return render_template('Private_Invoice/commercial_saving_result.html',
                               title="Estudio de Ahorro Energético",
                               yearly_savings=results.get('yearly_savings', 0),
                               monthly_savings=monthly_savings,
                               savings_percentage=results.get('savings_percentage', 0),
                               reliability=results.get('estimation_reliability', 'Estimado'),
                               current_cost=results.get('current_cost', 0),
                               ole_cost=results.get('ole_cost', 0),
                               tariff_type=results.get('tariff_type', '2.0TD'),
                               reactive_energy_penalty=reactive_energy_annual_penalty,
                               power_excess_penalty=power_excess_penalty,
                               power_price_unit=results.get('power_price_unit', 'año'),
                               demo_mode=demo_mode,
                               lead=lead,
                               client_name=client_name,
                               supply_address=supply_address,
                               provider_name=provider_name,
                               billing_period=billing_period,
                               billing_days=billing_days,
                               commercial_name=commercial_name)
    except Exception as e:
        current_app.logger.error(f"[COM] Error al mostrar resultados: {str(e)}")
        flash('Error al mostrar los resultados. Por favor, contacta con nuestro equipo.', 'error')
        return redirect(url_for('public.home'))


@commercial_invoice_bp.route('/solicitar-llamada', methods=['POST'])
@login_required
@comercial_required
def request_call():
    """Procesa la solicitud de llamada del usuario (comercial)"""
    if 'lead_id' not in session:
        return jsonify({'success': False, 'message': 'No se encontró tu solicitud.'})
        
    lead_id = session['lead_id']
    
    try:
        lead = InvoiceLead.query.get(lead_id)
        if not lead:
            return jsonify({'success': False, 'message': 'No se encontró tu solicitud en nuestra base de datos.'})
        
        lead.status = 'callback_requested'
        db.session.commit()
        
        return jsonify({
            'success': True,
            'message': 'Recibido. Nuestro equipo te llamará en las próximas 24 horas.'
        })
    except Exception as e:
        current_app.logger.error(f"[COM] Error al procesar solicitud de llamada: {str(e)}")
        return jsonify({
            'success': False,
            'message': 'Error al procesar tu solicitud. Por favor, llámanos directamente.'
        })


@commercial_invoice_bp.route('/generar-propuesta', methods=['GET', 'POST'])
@login_required
@comercial_required
def generate_proposal():
    """Permite seleccionar múltiples planes y generar una propuesta personalizada"""
    if 'all_plans_data' not in session or 'lead_id' not in session:
        flash('Se produjo un error en el procesamiento. Por favor, intenta de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.estudio_gratuito'))
    
    plans_data = session.get('all_plans_data', [])
    lead_id = session.get('lead_id')
    invoice_data = session.get('confirmed_invoice_data', {})
    
    if request.method == 'POST':
        # Procesar selección de planes y comentarios
        selected_plan_indices = request.form.getlist('selected_plans')
        custom_comment = request.form.get('custom_comment', '')
        
        if not selected_plan_indices:
            flash('Debes seleccionar al menos un plan para la propuesta.', 'warning')
            return redirect(url_for('commercial_invoice.generate_proposal'))
        
        # Filtrar planes seleccionados
        selected_plans = [plans_data[int(i)] for i in selected_plan_indices if int(i) < len(plans_data)]
        
        # Guardar en sesión para generar PDF
        session['proposal_data'] = {
            'selected_plans': selected_plans,
            'custom_comment': custom_comment,
            'commercial_name': current_user.name if current_user.name else current_user.username
        }
        
        # Asegurar que invoice_data esté disponible para el PDF
        if 'confirmed_invoice_data' in session:
            session['invoice_data'] = session['confirmed_invoice_data']
        
        current_app.logger.info(f"[COM] Datos guardados para PDF - proposal_data: {bool(session.get('proposal_data'))}, invoice_data: {bool(session.get('invoice_data'))}")
        
        # Redirigir a vista previa de propuesta
        return redirect(url_for('commercial_invoice.proposal_preview'))
    
    # GET: Mostrar formulario de selección
    return render_template('Private_Invoice/proposal_selection.html',
                          title="Generar Propuesta Personalizada",
                          plans=plans_data,
                          invoice_data=invoice_data,
                          client_name=invoice_data.get('client_name', ''),
                          supply_address=invoice_data.get('supply_address', ''))


@commercial_invoice_bp.route('/vista-previa-propuesta')
@login_required
def proposal_preview():
    """Muestra la vista previa de la propuesta antes de descargar"""
    try:
        # Obtener datos de la sesión
        proposal_data = session.get('proposal_data')
        invoice_data = session.get('invoice_data') or session.get('confirmed_invoice_data')
        
        if not proposal_data or not invoice_data:
            flash('No hay datos de propuesta disponibles. Por favor, genera una nueva propuesta.', 'error')
            return redirect(url_for('commercial_invoice.estudio_gratuito'))
        
        return render_template('Private_Invoice/proposal_preview.html',
                              title="Vista Previa de Propuesta",
                              proposal_data=proposal_data,
                              invoice_data=invoice_data,
                              commercial=current_user)
        
    except Exception as e:
        current_app.logger.error(f"[COM] Error en vista previa: {str(e)}")
        flash('Error al mostrar la vista previa. Por favor, inténtalo de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.generate_proposal'))


@commercial_invoice_bp.route('/download_proposal')
@login_required
def download_proposal():
    """Descargar propuesta en PDF"""
    from flask import make_response
    from app.services.pdf_generator import generate_proposal_pdf, create_proposal_filename
    
    try:
        # Obtener datos de la sesión
        proposal_data = session.get('proposal_data')
        invoice_data = session.get('invoice_data')
        
        current_app.logger.info(f"[COM] Verificando datos para PDF - proposal_data: {bool(proposal_data)}, invoice_data: {bool(invoice_data)}")
        current_app.logger.info(f"[COM] Claves en sesión: {list(session.keys())}")
        
        if not proposal_data or not invoice_data:
            flash('No hay datos de propuesta disponibles. Por favor, genera una nueva propuesta.', 'error')
            return redirect(url_for('commercial_invoice.estudio_gratuito'))
        
        # Generar PDF con información del comercial
        pdf_buffer = generate_proposal_pdf(proposal_data, invoice_data, current_user)
        
        # Crear respuesta
        response = make_response(pdf_buffer.getvalue())
        response.headers['Content-Type'] = 'application/pdf'
        
        # Nombre del archivo
        client_name = invoice_data.get('client_name', 'Cliente')
        filename = create_proposal_filename(client_name)
        response.headers['Content-Disposition'] = f'attachment; filename="{filename}"'
        
        return response
        
    except Exception as e:
        current_app.logger.error(f"[COM] Error generando PDF: {str(e)}")
        flash('Error al generar el PDF. Por favor, inténtalo de nuevo.', 'error')
        return redirect(url_for('commercial_invoice.generate_proposal'))
