/**
 * Archivo: CotizEspSolicitud.js (COMPLETO OPTIMIZADO)
 * Ruta: src/static/js/Ventas/Cotiz/CotizEspSolicitud.js
 * Descripción: Funciones JavaScript completas y optimizadas para el módulo de cotizaciones especiales
 * Optimización: Mantiene TODAS las funciones originales + nuevas características
 */

// Variable globales
let COUNTRIES_DATA = null;
let PROTOTIPO_MODE = true;  // Inicianizar PROTOTIPO_MODE

document.addEventListener('DOMContentLoaded', function() {
    console.log('DOM loaded - iniciando script de cotización completo optimizado');
    
    cargarConfiguracionEInicializar(); // Inicianizar PROTOTIPO_MODE
});

// ============================================
// MÓDULO: CARGAR CONFIGURACIÓN E INICIALIZAR 
// ============================================

async function cargarConfiguracionEInicializar() {  // Inicianizar PROTOTIPO_MODE
    try {
        // Llama al nuevo endpoint que creamos en Python
        const response = await fetch('/Ventas/Cotiz/EspecialSolicitud/GetConfig');
        const data = await response.json();
        
        if (data.success) {
            PROTOTIPO_MODE = data.PROTOTIPO_MODE;
        } else {
            console.warn('No se pudo cargar la configuración del prototipo, se usará el modo por defecto (True).');
        }
    } catch (error) {
        console.error('Error cargando configuración, se usará el modo prototipo por defecto:', error);
    } finally {
        // 🆕 4. Inicializar todos los módulos DESPUÉS de obtener la configuración
        console.log(`Modo Prototipo establecido en: ${PROTOTIPO_MODE}`);
        
        inicializarBusquedaOportunidad();
        inicializarFormulariosDinamicos();
        inicializarGeolocation();
        inicializarValidacionDinamica();
        inicializarContadoresProgreso();
        inicializarEnvioSolicitud();
    }
}

// ============================================
// CONSTANTES OPTIMIZADAS
// ============================================
const CONFIG = {
    MIN_OPPORTUNITY_NUMBER: 1000,
    JSON_COUNTRIES_URL: '/static/data/Utilities/countries_states_mx_us_ca.json',
    OPPORTUNITY_FIELDS: [
        'CRM_ContactID', 'CRM_ContactName', 'CRM_ContactType',
        'CRM_AssignedSalesperson', 'CRM_ContactAdress', 'CRM_ContactColonia',
        'CRM_ContactCity', 'CRM_ContactNumber', 'CRM_ContactCountry',
        'CRM_ContactLegalIdentifier', 'CRM_ContactZip', 'CRM_ContactState',
        'CRM_ContactEmail'
    ],
    FORM_MAPPING: {
        'FormSolicVis': 'section-FormSolicVis', // SOLVIS
        'FormPTTransNac': 'section-FormPTTransNac', // FPETABTRANS
        'FormPTTransUL': 'section-FormPTTransUL', // ← FPETABTRANSUL
        'FormAire': 'section-FormAire', // Aires
        'FormSistCritUPS': 'section-FormSistCritUPS', // ← SCUPS
        'FormBess': 'section-FormBess', // Step
        'FormSolar': 'section-FormSolar',  // ← SOLARR
        'FormEneCog': 'section-FormEneCog', // ← ENECOG
        'FormImess': 'section-FormImess', // ← IMESS
        'FormProyecEsp': 'section-FormProyecEsp' // PROYESP
    },
    REQUIRED_COUNTERS: {
        'general': {
            selector: '.section-FormGral',
            counterId: 'general-counter',
            baseFields: 2 // siteVisit + InfoProy
        },
        'solicvis': { // SOLVIS
            selector: '.section-FormSolicVis',
            counterId: 'solicvis-counter'
        },
        'pttransnac': { // FPETABTRANS
            selector: '.section-FormPTTransNac',
            counterId: 'pttransnac-counter'
        },
        'pttransul': { // ← FPETABTRANSUL
            selector: '.section-FormPTTransUL',
            counterId: 'pttransul-counter'
        },
        'aire': { // Aires
            selector: '.section-FormAire',
            counterId: 'aire-counter'
        },
        'sistcritups': { // ← SCUPS
            selector: '.section-FormSistCritUPS',
            counterId: 'sistcritups-counter'
        },
        'bess': { 
            selector: '.section-FormBess',
            counterId: 'bess-counter'
        }, // Step
        'solar': { // ← SOLARR
            selector: '.section-FormSolar',
            counterId: 'solar-counter'
        },
        'enecog': { // ← ENECOG
            selector: '.section-FormEneCog',
            counterId: 'enecog-counter'
        },
        'imess': { // ← IMESS
            selector: '.section-FormImess',
            counterId: 'imess-counter'
        },
        'proyecesp': { // PROYESP
            selector: '.section-FormProyecEsp',
            counterId: 'proyecesp-counter'
        }
    }
};


// ============================================
// MÓDULO: BÚSQUEDA DE OPORTUNIDAD
// ============================================

function inicializarBusquedaOportunidad() {
    const opportunityInput = document.getElementById('CRM_OpportunityNumber');
    const searchButton = document.getElementById('btn-search-opportunity') || 
                        document.querySelector('.form-section .btn-custom.btn-primary');
    
    if (!searchButton) {
        console.error('No se encontró el botón de búsqueda');
        return;
    }
    
    // Event listeners
    searchButton.addEventListener('click', function(e) {
        e.preventDefault();
        buscarOportunidad();
    });
    
    if (opportunityInput) {
        opportunityInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                buscarOportunidad();
            }
        });
    }
}
/*
// Funcion de buscarOportunidad
function buscarOportunidad() {
    const opportunityNumber = document.getElementById('CRM_OpportunityNumber').value.trim();
    
    // Validaciones básicas optimizadas
    if (!opportunityNumber) {
        mostrarAlerta('Por favor, ingrese un número de oportunidad', 'warning');
        return;
    }
    
    const numeroOportunidad = parseFloat(opportunityNumber);
    if (isNaN(numeroOportunidad) || numeroOportunidad <= CONFIG.MIN_OPPORTUNITY_NUMBER) {
        const mensaje = isNaN(numeroOportunidad) 
            ? 'El número de oportunidad debe ser un valor numérico válido'
            : `El número de oportunidad debe ser mayor a ${CONFIG.MIN_OPPORTUNITY_NUMBER}`;
        mostrarAlerta(mensaje, 'warning');
        return;
    }
    
    ejecutarBusquedaOportunidad(numeroOportunidad);
}
*/

function buscarOportunidad() {
    const opportunityNumber = document.getElementById('CRM_OpportunityNumber').value.trim();
    
    // 1. Validacion basica: el campo no debe estar vacío
    if (!opportunityNumber) {
        mostrarAlerta('Por favor, ingrese un numero de oportunidad', 'warning');
        return;
    }
    
    // --- LÓGICA CONDICIONAL ---
    if (PROTOTIPO_MODE) {
        // --- MODO PROTOTIPO (TRUE): Aplica la validación numérica estricta ---
        
        // 2. Intentar parsear el valor a número
        const numeroOportunidad = parseFloat(opportunityNumber);
        
        // 3. Validar si no es un número o si no cumple el mínimo
        if (isNaN(numeroOportunidad)) {
            mostrarAlerta('En MODO PROTOTIPO, el número debe ser un valor numérico válido.', 'warning');
            return;
        }

        if (numeroOportunidad <= CONFIG.MIN_OPPORTUNITY_NUMBER) { 
            const mensaje = `El numero de oportunidad debe ser mayor a ${CONFIG.MIN_OPPORTUNITY_NUMBER}`;
            mostrarAlerta(mensaje, 'warning');
            return;
        }
        
        // 4. Si pasa las validaciones de Prototipo, se envía el valor numérico
        ejecutarBusquedaOportunidad(numeroOportunidad);

    } else {
        // --- MODO REAL (FALSE): Omite TODAS las validaciones numéricas ---
        
        // Simplemente envía el valor como string (ej. "OPP2-000185").
        // El backend (Python) y el CRM se encargarán de validar el formato.
        ejecutarBusquedaOportunidad(opportunityNumber);
    }
}


function ejecutarBusquedaOportunidad(numeroOportunidad) {
    // Mostrar loading
    Swal.fire({
        title: 'Buscando oportunidad...',
        text: 'Por favor espere mientras buscamos la información',
        allowOutsideClick: false,
        didOpen: () => {
            Swal.showLoading();
        }
    });
    
    // Petición AJAX
    fetch('/Ventas/Cotiz/EspecialSolicitud/BuscarOportunidad', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-Requested-With': 'XMLHttpRequest'
        },
        body: JSON.stringify({
            opportunity_number: numeroOportunidad
        })
    })
    .then(response => {
        if (!response.ok) {
            return response.json().then(errorData => {
                throw new Error(JSON.stringify(errorData));
            });
        }
        return response.json();
    })
    .then(data => {
        if (!data.success) {
            const error = data.error || {};
            mostrarAlerta(error.message || 'Error desconocido', error.alert_type || 'error');
            return;
        }
        
        if (data.data) {
            llenarCamposOportunidad(data.data);
            mostrarAlerta('Oportunidad encontrada exitosamente', 'success');
        }
    })
    .catch(error => {
        console.error('Error en búsqueda:', error);
        
        try {
            const errorData = JSON.parse(error.message);
            if (errorData.error) {
                mostrarAlerta(errorData.error.message, errorData.error.alert_type || 'error');
                return;
            }
        } catch (parseError) {
            // Error no estructurado
        }
        
        let mensaje = 'Error desconocido';
        if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
            mensaje = 'Error de conexión. Verifique su conexión a internet.';
        }
        mostrarAlerta(mensaje, 'error');
    });
}

function llenarCamposOportunidad(oportunidad) {
    CONFIG.OPPORTUNITY_FIELDS.forEach(campoId => {
        const elemento = document.getElementById(campoId);
        if (elemento) {
            elemento.value = oportunidad[campoId] || '';
            elemento.classList.add('campo-llenado');
        }
    });
}

// ============================================
// MÓDULO: GEOLOCALIZACIÓN - NUEVO
// ============================================

async function inicializarGeolocation() {
    console.log('🌍 Inicializando módulo de geolocalización...');
    
    try {
        // Cargar datos de países/estados
        await cargarDatosPaises();
        
        // Configurar event listeners
        configurarSelectoresPais();
        
        console.log('✅ Geolocalización inicializada correctamente');
        
    } catch (error) {
        console.error('❌ Error inicializando geolocalización:', error);
        mostrarAlerta('Error cargando datos de países. Contacte al administrador.', 'warning');
    }
}

async function cargarDatosPaises() {
    if (COUNTRIES_DATA) {
        console.log('📋 Datos de países ya cargados');
        return;
    }
    
    console.log('📡 Cargando datos de países desde JSON...');
    
    try {
        const response = await fetch(CONFIG.JSON_COUNTRIES_URL);
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const jsonData = await response.json();
        
        // Convertir estructura del JSON a formato esperado por el código
        COUNTRIES_DATA = {};
        
        if (jsonData.countries && Array.isArray(jsonData.countries)) {
            jsonData.countries.forEach(country => {
                const countryCode = country.isoCode;
                const countryName = country.name;
                const states = {};
                
                // Convertir array de states a objeto
                if (country.states && Array.isArray(country.states)) {
                    country.states.forEach(state => {
                        states[state.isoCode] = state.name;
                    });
                }
                
                COUNTRIES_DATA[countryCode] = {
                    name: countryName,
                    states: states
                };
            });
            
            console.log(`✅ Cargados ${Object.keys(COUNTRIES_DATA).length} países desde JSON`);
            console.log('📊 Países disponibles:', Object.keys(COUNTRIES_DATA).map(code => 
                `${code}: ${COUNTRIES_DATA[code].name} (${Object.keys(COUNTRIES_DATA[code].states).length} estados)`
            ));
            
        } else {
            throw new Error('Estructura de JSON inválida: no se encontró el array "countries"');
        }
        
        // Llenar select de países
        llenarSelectPaises();
        
    } catch (error) {
        console.error('❌ Error cargando JSON de países:', error);
        
        // Fallback: crear datos básicos manualmente
        COUNTRIES_DATA = {
            "MX": {
                "name": "México",
                "states": {
                    "CDMX": "Ciudad de México",
                    "EdoMex": "Estado de México", 
                    "Jalisco": "Jalisco",
                    "NuevoLeon": "Nuevo León",
                    "Puebla": "Puebla",
                    "Veracruz": "Veracruz"
                }
            },
            "US": {
                "name": "Estados Unidos",
                "states": {
                    "CA": "California",
                    "TX": "Texas", 
                    "NY": "Nueva York",
                    "FL": "Florida",
                    "IL": "Illinois",
                    "PA": "Pennsylvania"
                }
            },
            "CA": {
                "name": "Canadá",
                "states": {
                    "ON": "Ontario",
                    "QC": "Quebec",
                    "BC": "British Columbia", 
                    "AB": "Alberta",
                    "MB": "Manitoba",
                    "SK": "Saskatchewan"
                }
            }
        };
        
        console.log('🔄 Usando datos de países básicos como fallback');
        console.log('⚠️ Motivo del fallback:', error.message);
        llenarSelectPaises();
    }
}

function llenarSelectPaises() {
    const countrySelect = document.getElementById('visitCountry');
    
    if (!countrySelect || !COUNTRIES_DATA) {
        console.warn('⚠️ No se puede llenar select de países');
        return;
    }
    
    // Limpiar opciones existentes (excepto la primera)
    countrySelect.innerHTML = '<option value="" selected disabled>Selecciona un país</option>';
    
    // Agregar países ordenados alfabéticamente
    const countriesArray = Object.entries(COUNTRIES_DATA)
        .map(([code, data]) => ({ code, name: data.name }))
        .sort((a, b) => a.name.localeCompare(b.name));
    
    countriesArray.forEach(country => {
        const option = document.createElement('option');
        option.value = country.code;
        option.textContent = country.name;
        countrySelect.appendChild(option);
    });
    
    console.log(`✅ Select de países llenado con ${countriesArray.length} opciones`);
}

function configurarSelectoresPais() {
    const countrySelect = document.getElementById('visitCountry');
    const stateSelect = document.getElementById('visitState');
    
    if (!countrySelect || !stateSelect) {
        console.warn('⚠️ Selectores de país/estado no encontrados');
        return;
    }
    
    // Event listener para cambio de país
    countrySelect.addEventListener('change', function() {
        const paisSeleccionado = this.value;
        
        if (paisSeleccionado) {
            llenarSelectEstados(paisSeleccionado);
            stateSelect.disabled = false;
            
            // Validar país
            validateBasicField(this);
            actualizarContadorGeneral();
            
        } else {
            // Resetear estados
            stateSelect.innerHTML = '<option value="" selected disabled>Primero selecciona un país</option>';
            stateSelect.disabled = true;
            stateSelect.value = '';
            stateSelect.classList.remove('field-valid', 'field-invalid');
            stateSelect.classList.add('field-pending');
        }
    });
    
    // Event listener para cambio de estado
    stateSelect.addEventListener('change', function() {
        validateBasicField(this);
        actualizarContadorGeneral();
    });
}

function llenarSelectEstados(paisCodigo) {
    const stateSelect = document.getElementById('visitState');
    
    if (!stateSelect || !COUNTRIES_DATA || !COUNTRIES_DATA[paisCodigo]) {
        console.warn(`⚠️ No se pueden cargar estados para país: ${paisCodigo}`);
        return;
    }
    
    const estados = COUNTRIES_DATA[paisCodigo].states;
    
    // Limpiar opciones existentes
    stateSelect.innerHTML = '<option value="" selected disabled>Selecciona un estado</option>';
    
    // Agregar estados ordenados alfabéticamente
    const estadosArray = Object.entries(estados)
        .map(([code, name]) => ({ code, name }))
        .sort((a, b) => a.name.localeCompare(b.name));
    
    estadosArray.forEach(estado => {
        const option = document.createElement('option');
        option.value = estado.code;
        option.textContent = estado.name;
        stateSelect.appendChild(option);
    });
    
    console.log(`✅ Estados cargados para ${COUNTRIES_DATA[paisCodigo].name}: ${estadosArray.length} opciones`);
}

// ============================================
// MÓDULO: FORMULARIOS DINÁMICOS
// ============================================

function inicializarFormulariosDinamicos() {
    console.log('Inicializando formularios dinámicos...');

    // Ocultar todas las secciones al inicio
    Object.values(CONFIG.FORM_MAPPING).forEach(sectionClass => {
        const section = document.querySelector(`.${sectionClass}`);
        if (section) {
            section.style.display = 'none';
        }
    });

    // Agregar event listeners a checkboxes
    Object.keys(CONFIG.FORM_MAPPING).forEach(checkboxId => {
        const checkbox = document.getElementById(checkboxId);
        const sectionClass = CONFIG.FORM_MAPPING[checkboxId];
        
        if (checkbox) {
            checkbox.addEventListener('change', function() {
                const label = document.querySelector(`label[for="${checkboxId}"]`);
                const nombreFormulario = label ? label.textContent : checkboxId;
                toggleFormularioSeccion(this.checked, sectionClass, nombreFormulario);
                
                // Actualizar contador de progreso y botón de envío
                actualizarEstadoBotonEnvio();
            });
        }
    });
}

function toggleFormularioSeccion(mostrar, sectionClass, nombreFormulario) {
    const section = document.querySelector(`.${sectionClass}`);
    
    if (!section) {
        console.error(`Sección ${sectionClass} no encontrada`);
        return;
    }

    if (mostrar) {
        // Mostrar con animación
        section.style.display = 'block';
        section.style.opacity = '0';
        section.style.transform = 'translateY(-10px)';
        
        setTimeout(() => {
            section.style.transition = 'all 0.3s ease-in-out';
            section.style.opacity = '1';
            section.style.transform = 'translateY(0)';
            
            // Notificar que el formulario es visible
            notifyFormularioVisible(sectionClass);
            
            // Actualizar contadores
            actualizarTodosLosContadores();
        }, 10);

        mostrarNotificacionToast(`Formulario "${nombreFormulario}" activado`, 'info');
        
    } else {
        // Ocultar con animación
        section.style.transition = 'all 0.3s ease-in-out';
        section.style.opacity = '0';
        section.style.transform = 'translateY(-10px)';
        
        setTimeout(() => {
            section.style.display = 'none';
            
            // Limpiar campos del formulario oculto
            clearFormularioSeccion(section);
            
            // Actualizar contadores
            actualizarTodosLosContadores();
        }, 300);

        mostrarNotificacionToast(`Formulario "${nombreFormulario}" desactivado`, 'warning');
    }
}

function clearFormularioSeccion(section) {
    if (!section) return;
    
    const inputs = section.querySelectorAll('input, select, textarea');
    inputs.forEach(input => {
        if (input.type === 'checkbox' || input.type === 'radio') {
            input.checked = false;
        } else {
            input.value = '';
        }
        input.classList.remove('field-valid', 'field-invalid', 'field-pending');
    });
}

function notifyFormularioVisible(sectionClass) {
    const formModules = {
        'section-FormSolicVis': 'FormSolicVis', // SOLVIS
        'section-FormPTTransNac': 'FormPTTransNac', // FPETABTRANS
        'section-FormPTTransUL': 'FormPTTransUL', // ← FPETABTRANSUL
        'section-FormAire': 'FormAire', // Aires
        'section-FormSistCritUPS': 'FormSistCritUPS', // ← SCUPS
        'section-FormBess': 'FormBess', // Step
        'section-FormSolar': 'FormSolar', // ← SOLARR
        'section-FormEneCog': 'FormEneCog', // ← ENECOG
        'section-FormImess': 'FormImess', // ← IMESS
        'section-FormProyecEsp': 'FormProyecEsp' // PROYESP
    };
    
    const moduleName = formModules[sectionClass];
    if (moduleName && window[moduleName] && window[moduleName].onBecomeVisible) {
        window[moduleName].onBecomeVisible();
    }
}

// ============================================
// MÓDULO: CONTADORES DE PROGRESO - REQADD
// ============================================

window.ConditionalFieldsManager = (function() {
    'use strict';

    function autoInit(containerSelector) {
        const container = document.querySelector(containerSelector);
        if (!container) return;

        const triggers = container.querySelectorAll('[data-conditional-toggle]');
        
        triggers.forEach(trigger => {
            // Establece el estado inicial correcto al cargar
            handleToggle(trigger); 
            
            // Añade el listener para que se actualice con cada cambio del usuario
            trigger.addEventListener('change', () => handleToggle(trigger));
        });
    }

    function handleToggle(trigger) {
        const sectionId = trigger.getAttribute('data-conditional-toggle');
        const showWhenValue = trigger.getAttribute('data-show-when');
        const section = document.getElementById(sectionId);
        if (!section) return;

        const shouldShow = trigger.value === showWhenValue;

        // Habilita/deshabilita los campos y muestra/oculta la sección
        section.style.display = shouldShow ? 'block' : 'none';
        const fields = section.querySelectorAll('input, select, textarea');
        fields.forEach(field => {
            field.disabled = !shouldShow;
        });

        // ⭐ LA CLAVE: Llama al contador DESPUÉS de cada cambio.
        if (window.actualizarTodosLosContadores) {
            window.actualizarTodosLosContadores();
        }
    }

    return { autoInit };
})();

/**
 * Verifica si un campo debe ser considerado en la validación y conteo.
 * Un campo es válido si no está deshabilitado y es visible.
 * @param {HTMLElement} element El elemento del formulario a verificar.
 * @returns {boolean} True si el campo debe ser contado.
 */
function isFieldVisible(element) {
    if (!element || element.disabled) {
        return false;
    }
    // La propiedad offsetParent es null si el elemento o sus padres tienen 'display: none'.
    return element.offsetParent !== null;
}

function inicializarContadoresProgreso() {
    console.log('📊 Inicializando contadores de progreso...');
    
    // Configurar contadores para todas las secciones
    Object.keys(CONFIG.REQUIRED_COUNTERS).forEach(sectionKey => {
        const config = CONFIG.REQUIRED_COUNTERS[sectionKey];
        inicializarContadorSeccion(sectionKey, config);
    });
    
    // Event listeners globales para campos requeridos
    document.addEventListener('change', debounce(actualizarTodosLosContadores, 100));
    document.addEventListener('input', debounce(actualizarTodosLosContadores, 300));
}

function inicializarContadorSeccion(sectionKey, config) {
    const section = document.querySelector(config.selector);
    const counter = document.getElementById(config.counterId);
    
    if (!section || !counter) {
        console.warn(`⚠️ Sección o contador no encontrado para: ${sectionKey}`);
        return;
    }
    
    // Configurar estado inicial
    actualizarContadorSeccion(sectionKey);
}

function actualizarContadorSeccion(sectionKey) {
    const config = CONFIG.REQUIRED_COUNTERS[sectionKey];
    const section = document.querySelector(config.selector);
    const counter = document.getElementById(config.counterId);
    if (!section || !counter) return;
    
    // --- INICIO DE LA MODIFICACIÓN ---

    // 1. Obtén TODOS los campos con [required]
    const allRequiredFields = Array.from(section.querySelectorAll('[required]'));

    // 2. Filtra la lista para quedarte SOLO con los que son visibles Y están habilitados
    const visibleRequiredFields = allRequiredFields.filter(field => isFieldVisible(field));

    // 3. Usa esta nueva lista filtrada para todos los cálculos
    const totalRequired = visibleRequiredFields.length;
    let completed = 0;
    
    visibleRequiredFields.forEach(field => {
        if (isFieldCompleted(field)) {
            completed++;
        }
    });

    // --- FIN DE LA MODIFICACIÓN ---

    // El resto de la función no necesita cambios...
    if (sectionKey === 'general') {
        const stats = calcularStatsFormularioGeneral();
        // (La lógica especial para 'general' podría necesitar ajustes si también usa campos condicionales)
    }
    
    actualizarContadorVisual(counter, completed, totalRequired);
}

function calcularStatsFormularioGeneral() {
    // Los campos base ahora son 4: InfoProy, visitCountry, visitState, y visitAddress.
    // El campo 'siteVisit' ha sido eliminado.
    let total = 4;
    let completed = 0;

    // 1. Info Proyecto (sigue siendo requerido)
    const infoProy = document.getElementById('InfoProy');
    if (infoProy && isFieldCompleted(infoProy)) {
        completed++;
    }

    // 2. Campos de ubicación (ahora siempre requeridos)
    const camposUbicacion = ['visitCountry', 'visitState', 'visitAddress'];
    camposUbicacion.forEach(fieldId => {
        const field = document.getElementById(fieldId);
        if (field && isFieldCompleted(field)) {
            completed++;
        }
    });

    return { total, completed };
}

function isFieldCompleted(field) {
    if (!field) return false;
    
    if (field.tagName === 'SELECT') {
        const selectedOption = field.options[field.selectedIndex];
        return field.value !== '' && selectedOption && !selectedOption.disabled;
    }
    
    return field.value.trim() !== '';
}

function actualizarContadorVisual(counter, completed, total) {
    if (!counter) return;
    
    counter.textContent = `${completed}/${total} completados`;
    
    // Actualizar clases CSS
    counter.classList.remove('pending', 'complete', 'error');
    
    if (completed === 0) {
        counter.classList.add('pending');
    } else if (completed === total) {
        counter.classList.add('complete');
    } else {
        counter.classList.add('pending');
    }
}

function actualizarTodosLosContadores() {
    Object.keys(CONFIG.REQUIRED_COUNTERS).forEach(sectionKey => {
        actualizarContadorSeccion(sectionKey);
    });
    
    // Actualizar estado del botón de envío
    actualizarEstadoBotonEnvio();
}

function actualizarContadorGeneral() {
    actualizarContadorSeccion('general');
    actualizarEstadoBotonEnvio();
}

function actualizarEstadoBotonEnvio() {
    const submitButton = document.getElementById('btn-submit-request') || 
                        document.querySelector('.single-button-center .btn-custom.btn-primary');
    if (!submitButton) return;
    
    // Verificar si al menos un formulario específico está seleccionado
    const formulariosSeleccionados = Object.keys(CONFIG.FORM_MAPPING).some(checkboxId => {
        const checkbox = document.getElementById(checkboxId);
        return checkbox && checkbox.checked;
    });
    
    // Verificar si el formulario general está completo
    const statsGeneral = calcularStatsFormularioGeneral();
    const generalCompleto = statsGeneral.completed === statsGeneral.total;
    
    const puedeEnviar = formulariosSeleccionados && generalCompleto;
    
    submitButton.disabled = !puedeEnviar;
    
    // Actualizar texto de ayuda
    const helpText = document.getElementById('submit-help');
    if (helpText) {
        if (!formulariosSeleccionados) {
            helpText.textContent = 'Seleccione al menos un tipo de formulario para continuar';
            helpText.style.color = '#6c757d';
        } else if (!generalCompleto) {
            helpText.textContent = 'Complete el formulario general para continuar';
            helpText.style.color = '#6c757d';
        } else {
            helpText.textContent = 'Todo listo para enviar la solicitud';
            helpText.style.color = '#28a745';
        }
    }
}

// ============================================
// MÓDULO: VALIDACIÓN DINÁMICA MEJORADA
// ============================================

function inicializarValidacionDinamica() {
    console.log('✅ Inicializando validación dinámica mejorada...');
    
    const requiredFields = document.querySelectorAll('[required]');
    
    requiredFields.forEach(field => {
        configurarValidacionCampo(field);
    });
    
    // Observer para campos que se agregan dinámicamente
    configurarObserverCamposDinamicos();
}

function configurarValidacionCampo(field) {
    // Evitar listeners duplicados
    if (field.hasAttribute('data-validation-configured')) return;
    field.setAttribute('data-validation-configured', 'true');
    
    // Agregar clase visual a label
    const label = getFieldLabel(field);
    if (label && !label.classList.contains('required')) {
        label.classList.add('required');
    }
    
    // Event listeners optimizados
    field.addEventListener('blur', () => {
        validateBasicField(field);
        actualizarContadorSeccion(getFieldSection(field));
    });
    
    field.addEventListener('change', () => {
        validateBasicField(field);
        actualizarContadorSeccion(getFieldSection(field));
    });
    
    // Para inputs de texto, validación mientras escribe (debounced)
    if (field.tagName === 'INPUT' || field.tagName === 'TEXTAREA') {
        field.addEventListener('input', debounce(() => {
            validateBasicField(field);
            actualizarContadorSeccion(getFieldSection(field));
        }, 500));
    }
}

function getFieldSection(field) {
    const section = field.closest('.section-FormGral, .section-FormSolicVis, .section-FormPTTransNac, .section-FormPTTransUL, .section-FormAire, .section-FormSistCritUPS, .section-FormBess, .section-FormSolar, .section-FormEneCog, .section-FormImess, .section-FormProyecEsp'); // Step // ← SOLARR // ← ENECOG // ← IMESS // Aires // FPETABTRANS // ← FPETABTRANSUL // ← SCUPS // PROYESP // SOLVIS
    if (!section) return null;
    if (section.classList.contains('section-FormGral')) return 'general';
    if (section.classList.contains('section-FormSolicVis')) return 'solicvis'; // SOLVIS
    if (section.classList.contains('section-FormPTTransNac')) return 'pttransnac'; // FPETABTRANS
    if (section.classList.contains('section-FormPTTransUL')) return 'pttransul'; // FPETABTRANSUL
    if (section.classList.contains('section-FormAire')) return 'aire'; // Aires
    if (section.classList.contains('section-FormSistCritUPS')) return 'sistcritups'; // ← SCUPS
    if (section.classList.contains('section-FormBess')) return 'bess'; // Step
    if (section.classList.contains('section-FormSolar')) return 'solar'; // ← SOLARR
    if (section.classList.contains('section-FormEneCog')) return 'enecog'; // ← ENECOG
    if (section.classList.contains('section-FormImess')) return 'imess'; // ← IMESS
    if (section.classList.contains('section-FormProyecEsp')) return 'proyecesp'; // PROYESP
    return null;
}

function configurarObserverCamposDinamicos() {
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            mutation.addedNodes.forEach(function(node) {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    const newRequiredFields = node.querySelectorAll('[required]');
                    newRequiredFields.forEach(field => {
                        // Agregar listeners a campos nuevos
                        configurarValidacionCampo(field);
                    });
                }
            });
        });
    });
    
    observer.observe(document.body, { childList: true, subtree: true });
}

// ============================================
// MÓDULO: VALIDACIÓN BÁSICA MEJORADA
// ============================================

function inicializarValidacionBasica() {
    const requiredFields = document.querySelectorAll('[required]');
    
    requiredFields.forEach(field => {
        // Agregar clase visual a label
        const label = getFieldLabel(field);
        if (label && !label.classList.contains('required')) {
            label.classList.add('required');
        }
        
        // Event listeners básicos
        field.addEventListener('blur', () => validateBasicField(field));
        field.addEventListener('change', () => validateBasicField(field));
    });
}

function validateBasicField(element) {
    if (!element) return false;
    
    let isValid = true;
    let message = '';
    
    // Validación mejorada para SELECT con opción disabled
    if (element.tagName === 'SELECT') {
        const selectedOption = element.options[element.selectedIndex];
        
        // Verificar que tenga valor Y que la opción no esté disabled
        isValid = element.value !== '' && 
                  selectedOption && 
                  !selectedOption.disabled;
        
        if (!isValid) {
            if (element.value === '' || !selectedOption) {
                message = 'Debe seleccionar una opción';
            } else if (selectedOption.disabled) {
                message = 'Debe seleccionar una opción válida';
            }
        }
    } else {
        isValid = element.value.trim() !== '';
        message = isValid ? '' : 'Este campo es obligatorio';
    }
    
    // Actualizar clases visuales mejoradas
    updateValidationClasses(element, isValid);
    
    return isValid;
}

// Función optimizada para actualizar clases visuales
function updateValidationClasses(element, isValid) {
    element.classList.remove('field-valid', 'field-invalid', 'field-pending');
    
    // Para SELECT, verificar opción disabled específicamente
    if (element.tagName === 'SELECT') {
        const selectedOption = element.options[element.selectedIndex];
        const hasDisabledSelected = selectedOption && selectedOption.disabled;
        
        if (element.value === '' || hasDisabledSelected) {
            element.classList.add('field-pending');
        } else if (isValid) {
            element.classList.add('field-valid');
        } else {
            element.classList.add('field-invalid');
        }
    } else {
        // Para otros elementos
        if (element.value.trim() === '') {
            element.classList.add('field-pending');
        } else if (isValid) {
            element.classList.add('field-valid');
        } else {
            element.classList.add('field-invalid');
        }
    }
}

function validateForm(formSelector) {
    const form = typeof formSelector === 'string' ? 
                document.querySelector(formSelector) : formSelector;
    
    if (!form) return { isValid: false, errors: ['Formulario no encontrado'] };
    
    // const requiredFields = form.querySelectorAll('[required]');

    const allRequiredFields = Array.from(form.querySelectorAll('[required]'));
    const requiredFields = allRequiredFields.filter(field => isFieldVisible(field));

    const errors = [];
    let isValid = true;
    
    requiredFields.forEach(field => {
        if (!validateBasicField(field)) {
            isValid = false;
            const fieldName = getFieldLabel(field)?.textContent || field.id || 'Campo';
            errors.push(`${fieldName} es obligatorio`);
        }
    });
    
    return { isValid, errors, totalFields: requiredFields.length };
}

function validateSection(sectionSelector) {
    const section = document.querySelector(sectionSelector);
    if (!section) return { isValid: false, errors: ['Sección no encontrada'] };
    
    return validateForm(section);
}

// ============================================
// UTILIDADES OPTIMIZADAS
// ============================================

function debounce(func, delay) {
    let timeoutId;
    return function (...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
}

function getFieldLabel(element) {
    const container = element.closest('.form-group') || element.closest('.field-group');
    if (container) {
        return document.querySelector(`label[for="${element.id}"]`) || 
               container.querySelector('label');
    }
    return null;
}

function mostrarAlerta(mensaje, tipo = 'info') {
    const iconMap = {
        'success': 'success',
        'error': 'error',
        'warning': 'warning',
        'info': 'info'
    };
    
    const titleMap = {
        'success': '¡Éxito!',
        'error': 'Error',
        'warning': 'Advertencia',
        'info': 'Información'
    };
    
    Swal.fire({
        icon: iconMap[tipo] || 'info',
        title: titleMap[tipo] || 'Información',
        text: mensaje,
        confirmButtonText: 'Entendido',
        timer: tipo === 'success' ? 5000 : null,
        timerProgressBar: tipo === 'success'
    });
}

function mostrarNotificacionToast(mensaje, tipo) {
    Swal.fire({
        toast: true,
        position: 'top-end',
        icon: tipo,
        title: mensaje,
        showConfirmButton: false,
        timer: 2000,
        timerProgressBar: true
    });
}

function limpiarCamposOportunidad() {
    CONFIG.OPPORTUNITY_FIELDS.forEach(campoId => {
        const elemento = document.getElementById(campoId);
        if (elemento) {
            elemento.value = '';
            elemento.classList.remove('campo-llenado', 'field-valid', 'field-invalid', 'field-pending');
        }
    });
}

// ============================================
// MÓDULO: ENVÍO DE SOLICITUD
// ============================================

function inicializarEnvioSolicitud() {
    const enviarButton = document.getElementById('btn-submit-request') || 
                        document.querySelector('.single-button-center .btn-custom.btn-primary');
    
    if (enviarButton) {
        enviarButton.addEventListener('click', function(e) {
            e.preventDefault();
            procesarEnvioSolicitud();
        });
    }
}

function procesarEnvioSolicitud() {
    console.log('Iniciando proceso de envío de solicitud...');
    
    // 1. Validar formularios activos
    const validationResult = validarFormulariosCompletos();
    
    if (!validationResult.isValid) {
        mostrarErroresValidacion(validationResult.errors);
        return;
    }
    
    // 2. Recopilar todos los datos
    const datosCompletos = recopilarDatosSolicitud();
    
    if (!datosCompletos) {
        mostrarAlerta('Error al recopilar datos. Verifique que todos los campos estén completos.', 'error');
        return;
    }
    
    // 3. Enviar al backend
    enviarSolicitudBackend(datosCompletos);
}

function validarFormulariosCompletos() {
    const errores = [];
    let esValido = true;
    
    // Validar formulario general (siempre requerido)
    const resultadoGeneral = validateSection('.section-FormGral');
    if (!resultadoGeneral.isValid) {
        esValido = false;
        errores.push({
            seccion: 'Formulario General',
            errores: resultadoGeneral.errors
        });
    }
    
    // Validar formularios de checkbox activos (optimizado)
    const formularioMapping = {
        'FormSolicVis': { // SOLVIS
            seccion: '.section-FormSolicVis',
            nombre: 'Formulario de Solicitud de Visita'
        },
        'FormPTTransNac': { // FPETABTRANS
            seccion: '.section-FormPTTransNac', // FPETABTRANS
            nombre: 'Formulario de Plantas, Tableros y Transformadores Nacionales' // FPETABTRANS
        },
        'FormPTTransUL': { // ← FPETABTRANSUL
            seccion: '.section-FormPTTransUL',
            nombre: 'Formulario de Plantas, Tableros y Transformadores UL'
        },
        'FormAire': { // Aires
            seccion: '.section-FormAire', 
            nombre: 'Formulario de Aires Acondicionados' 
        },
        'FormSistCritUPS': { // ← SCUPS
            seccion: '.section-FormSistCritUPS',
            nombre: 'Formulario de Sistemas Críticos (UPS)'
        }, 
        'FormBess': { 
            seccion: '.section-FormBess', 
            nombre: 'Formulario de BESS' 
        }, // Step
        'FormSolar': { // ← SOLARR
            seccion: '.section-FormSolar', 
            nombre: 'Formulario de Sistemas Solares' 
        },
        'FormEneCog': { // ← ENECOG
            seccion: '.section-FormEneCog', 
            nombre: 'Formulario de Energía de Cogeneración' 
        },
        'FormImess': { // ← IMESS
            seccion: '.section-FormImess',
            nombre: 'Formulario de IMESS'
        }, 
        'FormProyecEsp': { // PROYESP
            seccion: '.section-FormProyecEsp',
            nombre: 'Formulario de Proyectos Especiales'
        }
    };
    
    Object.keys(formularioMapping).forEach(checkboxId => {
        const checkbox = document.getElementById(checkboxId);
        const config = formularioMapping[checkboxId];
        
        if (checkbox && checkbox.checked) {
            const resultado = validateSection(config.seccion);
            if (!resultado.isValid) {
                esValido = false;
                errores.push({
                    seccion: config.nombre,
                    errores: resultado.errors
                });
            }
        }
    });
    
    // Validar que al menos un checkbox esté seleccionado
    const checkboxesActivos = Object.keys(formularioMapping).some(id => {
        const checkbox = document.getElementById(id);
        return checkbox && checkbox.checked;
    });
    
    if (!checkboxesActivos) {
        esValido = false;
        errores.push({
            seccion: 'Selección de Formularios',
            errores: ['Debe seleccionar al menos un tipo de formulario para cotización']
        });
    }
    
    return { isValid: esValido, errors: errores };
}

function mostrarErroresValidacion(errores) {
    let mensajeCompleto = 'Se encontraron los siguientes errores:\n\n';
    
    errores.forEach((error, index) => {
        mensajeCompleto += `${index + 1}. ${error.seccion}:\n`;
        if (Array.isArray(error.errores)) {
            error.errores.forEach(err => {
                mensajeCompleto += `   • ${err}\n`;
            });
        } else {
            mensajeCompleto += `   • ${error.errores}\n`;
        }
        mensajeCompleto += '\n';
    });
    
    Swal.fire({
        icon: 'warning',
        title: 'Formularios Incompletos',
        text: mensajeCompleto,
        confirmButtonText: 'Revisar Formularios',
        customClass: {
            content: 'text-left'
        }
    });
}

function recopilarDatosSolicitud() {
    try {
        const datos = {
            // Datos de la oportunidad
            oportunidad: recopilarDatosOportunidad(),
            
            // Formulario general (siempre incluido)
            formularioGeneral: recopilarDatosFormulario('.section-FormGral', 'General'),
            
            // Formularios específicos según checkbox activos
            formulariosEspecificos: recopilarFormulariosActivos(),
            
            // Archivos de todos los formularios
            archivos: recopilarArchivosFormularios()
        };
        
        console.log('Datos recopilados:', datos);
        return datos;
        
    } catch (error) {
        console.error('Error al recopilar datos:', error);
        return null;
    }
}

function recopilarArchivosFormularios() {
    const archivos = [];
    
    // Lista de formularios que pueden tener archivos
    const formulariosConArchivos = [
        { // SOLVIS
            modulo: 'FormSolicVis',
            tipo: 'SolicVis',
            seccion: '.section-FormSolicVis',
            nombre: 'Solicitud de Visita'
        },
        { // FPETABTRANS
            modulo: 'FormPTTransNac',
            tipo: 'PTTransNac',
            seccion: '.section-FormPTTransNac',
            nombre: 'Plantas, Tableros y Transformadores Nacionales'
        },
        { // ← FPETABTRANSUL
            modulo: 'FormPTTransUL',
            tipo: 'PTTransUL',
            seccion: '.section-FormPTTransUL',
            nombre: 'Plantas, Tableros y Transformadores UL'
        },
        { // Aires
            modulo: 'FormAire', 
            tipo: 'Aire',
            seccion: '.section-FormAire',
            nombre: 'Aires'
        },
        { // ← SCUPS
            modulo: 'FormSistCritUPS',
            tipo: 'SistCritUPS',
            seccion: '.section-FormSistCritUPS',
            nombre: 'Sistemas Críticos (UPS)'
        },        
        { 
            modulo: 'FormBess', 
            tipo: 'Bess',  // Tener cuidado a agregar exactamente igual en el backend (procesar_documentos_con_formids_v2 y procesar_form_data_con_archivos_v3 y obtener_quotation_type_id)
            seccion: '.section-FormBess',
            nombre: 'BESS'
        }, // Step
        { // ← SOLARR
            modulo: 'FormSolar', 
            tipo: 'Solar',
            seccion: '.section-FormSolar',
            nombre: 'Sistemas Solares'
        },
        { // ← ENECOG
            modulo: 'FormEneCog', 
            tipo: 'EnergyCogeneration',
            seccion: '.section-FormEneCog',
            nombre: 'Energía y Cogeneración'
        },
        { // ← IMESS
            modulo: 'FormImess', 
            tipo: 'Imess',
            seccion: '.section-FormImess',
            nombre: 'IMESS'
        },
        { // PROYESP
            modulo: 'FormProyecEsp',
            tipo: 'ProyecEsp',
            seccion: '.section-FormProyecEsp',
            nombre: 'Proyectos Especiales'
        }
    ];
    
    console.log('📁 Iniciando recopilación de archivos de formularios...');
    
    formulariosConArchivos.forEach(formulario => {
        try {
            const seccion = document.querySelector(formulario.seccion);
            
            // Verificar si la sección está visible (checkbox activado)
            if (!seccion || seccion.style.display === 'none') {
                console.log(`📋 ${formulario.nombre}: sección no visible, omitiendo`);
                return;
            }
            
            // Verificar si el módulo existe y tiene función getFiles
            if (!window[formulario.modulo]) {
                console.log(`⚠️ ${formulario.nombre}: módulo ${formulario.modulo} no encontrado`);
                return;
            }
            
            if (typeof window[formulario.modulo].getFiles !== 'function') {
                console.log(`⚠️ ${formulario.nombre}: función getFiles no disponible en ${formulario.modulo}`);
                return;
            }
            
            // Obtener archivos del módulo
            const archivosFormulario = window[formulario.modulo].getFiles();
            console.log(`📁 ${formulario.nombre}: obtenidos ${archivosFormulario ? archivosFormulario.length : 0} archivos`);
            
            if (!archivosFormulario || !Array.isArray(archivosFormulario) || archivosFormulario.length === 0) {
                console.log(`📭 ${formulario.nombre}: sin archivos válidos`);
                return;
            }
            
            // Validación mejorada de archivos
            const archivosValidos = archivosFormulario.filter(archivo => {
                // Verificar que es un objeto File válido
                if (!(archivo instanceof File)) {
                    console.warn(`⚠️ ${formulario.nombre}: objeto no es File válido:`, archivo);
                    return false;
                }
                
                // Verificar que tiene nombre y tamaño
                if (!archivo.name || archivo.name.trim() === '') {
                    console.warn(`⚠️ ${formulario.nombre}: archivo sin nombre válido`);
                    return false;
                }
                
                if (archivo.size === 0) {
                    console.warn(`⚠️ ${formulario.nombre}: archivo vacío: ${archivo.name}`);
                    return false;
                }
                
                // Verificar tamaño máximo (2MB)
                if (archivo.size > 2 * 1024 * 1024) {
                    console.warn(`⚠️ ${formulario.nombre}: archivo muy grande: ${archivo.name} (${(archivo.size / 1024 / 1024).toFixed(2)}MB)`);
                    return false;
                }
                
                return true;
            });
            
            if (archivosValidos.length === 0) {
                console.log(`❌ ${formulario.nombre}: ningún archivo válido después de la validación`);
                return;
            }
            
            // Agregar archivos válidos al resultado
            archivos.push({
                formularioTipo: formulario.tipo,
                formularioNombre: formulario.modulo,
                formularioDisplayName: formulario.nombre,
                archivos: archivosValidos,
                cantidad: archivosValidos.length,
                totalSize: archivosValidos.reduce((sum, file) => sum + file.size, 0)
            });
            
            console.log(`✅ ${formulario.nombre}: ${archivosValidos.length} archivos válidos agregados`);
            
        } catch (error) {
            console.error(`❌ Error procesando ${formulario.nombre}:`, error);
        }
    });
    
    // Estadísticas finales
    const totalFormularios = archivos.length;
    const totalArchivos = archivos.reduce((sum, form) => sum + form.cantidad, 0);
    const totalSize = archivos.reduce((sum, form) => sum + form.totalSize, 0);
    
    console.log(`📊 Recopilación completada:`);
    console.log(`   📂 Formularios con archivos: ${totalFormularios}`);
    console.log(`   📄 Total de archivos: ${totalArchivos}`);
    console.log(`   💾 Tamaño total: ${(totalSize / 1024 / 1024).toFixed(2)} MB`);
    
    return archivos;
}

function recopilarDatosOportunidad() {
    const datosOportunidad = {};
    
    // Agregar número de oportunidad al principio
    const campos = ['CRM_OpportunityNumber', ...CONFIG.OPPORTUNITY_FIELDS];
    
    campos.forEach(campoId => {
        const elemento = document.getElementById(campoId);
        if (elemento) {
            datosOportunidad[campoId] = elemento.value.trim();
        }
    });
    
    return datosOportunidad;
}

function recopilarDatosFormulario(selectorSeccion, tipoFormulario) {
    const seccion = document.querySelector(selectorSeccion);
    if (!seccion) return null;
    
    const datosFormulario = {
        tipo: tipoFormulario,
        preguntas: []
    };
    
    // Buscar todos los elementos de entrada en la sección
    const elementos = seccion.querySelectorAll('input, select, textarea');
    
    elementos.forEach((elemento, index) => {
        // Omitir elementos que no son parte del formulario (como botones de búsqueda)
        if (elemento.type === 'button' || elemento.type === 'submit') {
            return;
        }
        
        const label = obtenerLabelElemento(elemento);
        const tipoElemento = obtenerTipoElemento(elemento);
        const respuesta = obtenerRespuestaElemento(elemento);
        
        // Solo agregar si tiene una pregunta (label) válida
        if (label && label.trim() !== '') {
            datosFormulario.preguntas.push({
                linea: index + 1,
                pregunta: label.trim(),
                tipoElemento: tipoElemento,
                respuesta: respuesta,
                elementoId: elemento.id || `elemento_${index}`
            });
        }
    });
    
    return datosFormulario;
}

function recopilarFormulariosActivos() {
    const formulariosActivos = [];
    
    const formularioMapping = {
        'FormSolicVis': { // SOLVIS
            seccion: '.section-FormSolicVis',
            tipo: 'SolicVis',
            nombre: 'Solicitud de Visita'
        }, 
        'FormPTTransNac': { // FPETABTRANS
            seccion: '.section-FormPTTransNac',
            tipo: 'PTTransNac',
            nombre: 'Plantas, Tableros y Transformadores Nacionales'
        },
        'FormPTTransUL': { // ← FPETABTRANSUL
            seccion: '.section-FormPTTransUL',
            tipo: 'PTTransUL',
            nombre: 'Plantas, Tableros y Transformadores UL'
        },
        'FormAire': { // Aires
            seccion: '.section-FormAire',
            tipo: 'Aire',
            nombre: 'Aires'
        },
        'FormSistCritUPS': { // ← SCUPS
            seccion: '.section-FormSistCritUPS',
            tipo: 'SistCritUPS',
            nombre: 'Sistemas Críticos (UPS)'
        },
        'FormBess': { 
            seccion: '.section-FormBess',
            tipo: 'Bess', // Tener cuidado a agregar exactamente igual en el backend (procesar_documentos_con_formids_v2 y procesar_form_data_con_archivos_v3 y obtener_quotation_type_id)
            nombre: 'BESS'
        }, // Step
        'FormSolar': { // ← SOLARR
            seccion: '.section-FormSolar', 
            tipo: 'Solar',
            nombre: 'Sistemas Solares'
        },
        'FormEneCog': { // ← ENECOG
            seccion: '.section-FormEneCog', 
            tipo: 'EnergyCogeneration',
            nombre: 'Energía y Cogeneración'
        },
        'FormImess': { // ← IMESS
            seccion: '.section-FormImess',
            tipo: 'Imess',
            nombre: 'IMESS'
        },
        'FormProyecEsp': { // PROYESP
            seccion: '.section-FormProyecEsp',
            tipo: 'ProyecEsp',
            nombre: 'Proyectos Especiales'
        }
    };
    
    Object.keys(formularioMapping).forEach(checkboxId => {
        const checkbox = document.getElementById(checkboxId);
        const config = formularioMapping[checkboxId];
        
        if (checkbox && checkbox.checked) {
            const datosFormulario = recopilarDatosFormulario(config.seccion, config.tipo);
            if (datosFormulario) {
                datosFormulario.nombre = config.nombre;
                formulariosActivos.push(datosFormulario);
            }
        }
    });
    
    return formulariosActivos;
}

function obtenerLabelElemento(elemento) {
    // Buscar label por 'for' attribute
    let label = document.querySelector(`label[for="${elemento.id}"]`);
    
    if (!label) {
        // Buscar label en el contenedor padre
        const container = elemento.closest('.form-group') || elemento.closest('.field-group');
        if (container) {
            label = container.querySelector('label');
        }
    }
    
    return label ? label.textContent.replace(':', '').trim() : '';
}

function obtenerTipoElemento(elemento) {
    if (elemento.tagName === 'SELECT') {
        return 'select';
    } else if (elemento.tagName === 'TEXTAREA') {
        return 'textarea';
    } else if (elemento.type === 'checkbox') {
        return 'checkbox';
    } else if (elemento.type === 'radio') {
        return 'radio';
    } else {
        return 'text';
    }
}

function obtenerRespuestaElemento(elemento) {
    if (elemento.type === 'checkbox') {
        return elemento.checked ? 'true' : 'false';
    } else if (elemento.type === 'radio') {
        return elemento.checked ? elemento.value : '';
    } else if (elemento.tagName === 'SELECT') {
        const selectedOption = elemento.options[elemento.selectedIndex];
        return selectedOption ? selectedOption.text : '';
    } else {
        return elemento.value.trim();
    }
}

function enviarSolicitudBackend(datos) {
    // Calcular tiempo estimado basado en archivos
    let tiempoEstimadoSegundos = 30; // Base mínimo
    let totalArchivos = 0;
    
    if (datos.archivos && datos.archivos.length > 0) {
        totalArchivos = datos.archivos.reduce((sum, form) => sum + form.cantidad, 0);
        // 40 segundos por archivo + 30 segundos base de procesamiento
        tiempoEstimadoSegundos = (totalArchivos * 40) + 30;
    }
    
    const tiempoEstimadoMinutos = Math.ceil(tiempoEstimadoSegundos / 60);
    
    console.log(`⏱️ Estimación de tiempo: ${totalArchivos} archivos = ~${tiempoEstimadoMinutos} minuto(s)`);
    
    // Mostrar loading con información detallada
    Swal.fire({
        title: 'Enviando solicitud...',
        html: `
            <div style="text-align: left; margin: 20px 0;">
                <p><strong>📤 Procesando solicitud de cotización</strong></p>
                ${totalArchivos > 0 ? `
                    <p>📁 Archivos a procesar: <strong>${totalArchivos}</strong></p>
                    <p>⏱️ Tiempo estimado: <strong>${tiempoEstimadoMinutos} minuto(s)</strong></p>
                    <p style="color: #6c757d; font-size: 0.9em;">
                        🔒 <em>Los archivos se escanean por seguridad. No recargue la página.</em>
                    </p>
                ` : `
                    <p>⏱️ Tiempo estimado: <strong>Menos de 1 minuto</strong></p>
                `}
                <div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-radius: 4px;">
                    <small style="color: #495057;">
                        💡 <strong>Mantén esta ventana abierta</strong> - El proceso continúa en segundo plano
                    </small>
                </div>
            </div>
        `,
        allowOutsideClick: false,
        allowEscapeKey: false,
        showConfirmButton: false,
        didOpen: () => {
            Swal.showLoading();
        }
    });
    
    // Timeout dinámico basado en número de archivos
    const timeoutDuration = Math.min(Math.max(tiempoEstimadoSegundos * 1000, 60000), 300000);
    
    console.log(`⏰ Timeout configurado: ${timeoutDuration/1000} segundos`);
    
    const timeoutId = setTimeout(() => {
        // Mensaje mejorado de progreso
        Swal.fire({
            title: '⏳ Seguimos trabajando...',
            html: `
                <div style="text-align: left; margin: 20px 0;">
                    <p><strong>🔄 El proceso continúa ejecutándose</strong></p>
                    <p>📁 Archivos: <strong>${totalArchivos}</strong> (escaneo de seguridad en progreso)</p>
                    <p style="color: #28a745; font-weight: 500;">
                        ✅ Todo está funcionando correctamente
                    </p>
                    <div style="margin: 15px 0; padding: 15px; background: #e7f3ff; border-left: 4px solid #007bff; border-radius: 4px;">
                        <p style="margin: 0; color: #004085;">
                            <strong>🛡️ Escaneo de Seguridad:</strong><br>
                            Cada archivo se verifica contra malware para proteger el sistema.
                            Este proceso puede tomar 30-60 segundos por archivo.
                        </p>
                    </div>
                    <div style="margin-top: 15px; padding: 10px; background: #fff3cd; border-radius: 4px;">
                        <small style="color: #856404;">
                            ⚠️ <strong>¡IMPORTANTE!</strong> No cierres esta ventana ni recargues la página.
                            El proceso se completará automáticamente.
                        </small>
                    </div>
                </div>
            `,
            showCancelButton: false,
            confirmButtonText: '👍 Entendido, seguiré esperando',
            allowOutsideClick: false,
            allowEscapeKey: false,
            icon: 'info',
            customClass: {
                popup: 'large-popup-info',
                confirmButton: 'btn-continue-waiting'
            }
        }).then((result) => {
            if (result.isConfirmed) {
                // Volver al loading original sin cerrar el proceso
                Swal.fire({
                    title: '🔄 Continuando proceso...',
                    html: `
                        <div style="text-align: center; margin: 20px 0;">
                            <p><strong>📊 Procesamiento en curso</strong></p>
                            <p style="color: #6c757d;">
                                Archivos restantes: <strong>${totalArchivos}</strong>
                            </p>
                            <div style="margin-top: 15px;">
                                <div class="spinner-border text-primary" role="status">
                                    <span class="sr-only">Cargando...</span>
                                </div>
                            </div>
                        </div>
                    `,
                    allowOutsideClick: false,
                    allowEscapeKey: false,
                    showConfirmButton: false,
                    didOpen: () => {
                        Swal.showLoading();
                    }
                });
            }
        });
    }, timeoutDuration);
    
    // Preparar y enviar request
    const requestOptions = prepararRequestOptions(datos);
    
    // Enviar datos al backend
    fetch('/Ventas/Cotiz/EspecialSolicitud/Enviar', requestOptions)
    .then(response => {
        clearTimeout(timeoutId);
        
        console.log(`📡 Respuesta del servidor: ${response.status} ${response.statusText}`);
        
        if (!response.ok) {
            return response.json().then(errorData => {
                throw new Error(JSON.stringify(errorData));
            });
        }
        return response.json();
    })
    .then(data => {
        console.log('✅ Respuesta exitosa del servidor:', data);
        
        if (data.success) {
            mostrarResultadoExitoso(data);
        } else {
            const error = data.error || {};
            mostrarAlerta(error.message || 'Error al procesar la solicitud', error.alert_type || 'error');
        }
    })
    .catch(error => {
        clearTimeout(timeoutId);
        console.error('❌ Error en envío de solicitud:', error);
        mostrarErrorEnvio(error);
    });
}

function mostrarResultadoExitoso(data) {
    // Mensaje final mejorado con estadísticas
    let mensaje = data.message || 'Su solicitud de cotización ha sido enviada exitosamente';
    
    // Construir resumen detallado
    let resumenHTML = `
        <div style="text-align: left; margin: 20px 0;">
            <div style="background: #d4edda; border: 1px solid #c3e6cb; border-radius: 8px; padding: 15px; margin-bottom: 15px;">
                <h4 style="color: #155724; margin: 0 0 10px 0;">🎉 Solicitud Procesada Exitosamente</h4>
                <p style="margin: 0; color: #155724;">${mensaje}</p>
            </div>
    `;
    
    // Información de formularios
    if (data.data && data.data.forms_created && data.data.forms_created.length > 0) {
        resumenHTML += `
            <div style="margin: 15px 0;">
                <strong>📋 Formularios Procesados:</strong> ${data.data.forms_created.length}
                <ul style="margin: 5px 0; padding-left: 20px;">
        `;
        data.data.forms_created.forEach(formId => {
            const tipoForm = extraerTipoFormulario(formId);
            resumenHTML += `<li>${tipoForm}</li>`;
        });
        resumenHTML += `</ul></div>`;
    }
    
    // Información de archivos
    if (data.data && data.data.archivos_subidos > 0) {
        resumenHTML += `
            <div style="margin: 15px 0;">
                <strong>📁 Archivos Subidos:</strong> ${data.data.archivos_subidos}
                <br><small style="color: #6c757d;">Todos los archivos fueron escaneados y almacenados de forma segura</small>
            </div>
        `;
    }
    
    // Información de tareas
    if (data.data && data.data.tasks_generated && data.data.tasks_generated.length > 0) {
        resumenHTML += `
            <div style="margin: 15px 0;">
                <strong>📋 Tareas Generadas:</strong> ${data.data.tasks_generated.length}
                <br><small style="color: #6c757d;">El departamento de ingeniería ha sido notificado</small>
            </div>
        `;
    }
    
    // ID de la oportunidad
    if (data.data && data.data.opportunity_id) {
        resumenHTML += `
            <div style="margin: 15px 0; padding: 10px; background: #f8f9fa; border-radius: 4px;">
                <strong>🆔 ID de Oportunidad:</strong> <code>${data.data.opportunity_id}</code>
            </div>
        `;
    }
    
    resumenHTML += `</div>`;
    
    // Mostrar resultado final con opciones claras
    Swal.fire({
        icon: 'success',
        title: '🎉 ¡Solicitud Completada!',
        html: resumenHTML,
        showCancelButton: true,
        confirmButtonText: '🆕 Nueva Solicitud',
        cancelButtonText: '📝 Mantener Formulario',
        reverseButtons: true,
        allowOutsideClick: true,
        customClass: {
            popup: 'large-popup-success',
            confirmButton: 'btn-new-request',
            cancelButton: 'btn-keep-form'
        }
    }).then((result) => {
        if (result.isConfirmed) {
            // Usuario quiere nueva solicitud
            console.log('🆕 Usuario eligió crear nueva solicitud');
            limpiarFormularioCompleto();
            mostrarNotificacionToast('Formulario limpiado para nueva solicitud', 'info');
        } else {
            // Usuario quiere mantener el formulario
            console.log('📝 Usuario eligió mantener formulario actual');
            mostrarNotificacionToast('Formulario mantenido. Puede editarlo o enviar otra solicitud.', 'info');
        }
    });
}

function mostrarErrorEnvio(error) {
    try {
        const errorData = JSON.parse(error.message);
        if (errorData.error) {
            mostrarAlerta(errorData.error.message, errorData.error.alert_type || 'error');
            return;
        }
    } catch (parseError) {
        console.error('❌ Error parseando respuesta de error:', parseError);
    }
    
    // Mensajes de error más específicos con contexto
    let mensaje = 'Error al enviar la solicitud.';
    let sugerencias = '';
    
    if (error.message.includes('Failed to fetch') || error.message.includes('NetworkError')) {
        mensaje = 'Error de conexión con el servidor.';
        sugerencias = 'Verifique su conexión a internet e intente nuevamente.';
    } else if (error.message.includes('timeout')) {
        mensaje = 'La solicitud tardó demasiado en procesarse.';
        sugerencias = 'Esto puede deberse a archivos grandes o conexión lenta. Intente con archivos más pequeños.';
    } else if (error.message.includes('413') || error.message.includes('Request Entity Too Large')) {
        mensaje = 'Los archivos son demasiado grandes para el servidor.';
        sugerencias = 'Reduzca el tamaño de los archivos a menos de 2MB cada uno e intente nuevamente.';
    } else if (error.message.includes('500')) {
        mensaje = 'Error interno del servidor durante el procesamiento.';
        sugerencias = 'El problema puede ser temporal. Intente nuevamente en unos minutos.';
    }
    
    Swal.fire({
        icon: 'error',
        title: '❌ Error en el Envío',
        html: `
            <div style="text-align: left; margin: 20px 0;">
                <p><strong>${mensaje}</strong></p>
                ${sugerencias ? `<p style="color: #6c757d;">${sugerencias}</p>` : ''}
                <div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-radius: 4px;">
                    <small style="color: #6c757d;">
                        💾 Sus datos del formulario se mantuvieron. Puede corregir el problema e intentar nuevamente.
                    </small>
                </div>
            </div>
        `,
        confirmButtonText: 'Entendido',
        customClass: {
            popup: 'large-popup-error'
        }
    });
}

// ============================================
// FUNCIONES AUXILIARES
// ============================================

function prepararRequestOptions(datos) {
    // Verificar archivos con validación mejorada
    const hayArchivos = datos.archivos && Array.isArray(datos.archivos) && datos.archivos.length > 0;
    
    if (hayArchivos) {
        console.log('📤 Enviando con archivos - usando FormData');
        
        // Estadísticas previas al envío
        let totalArchivos = 0;
        let totalSize = 0;
        
        datos.archivos.forEach(formulario => {
            totalArchivos += formulario.cantidad;
            totalSize += formulario.totalSize;
            console.log(`   📁 ${formulario.formularioDisplayName}: ${formulario.cantidad} archivos`);
        });
        
        console.log(`   📊 Total: ${totalArchivos} archivos, ${(totalSize / 1024 / 1024).toFixed(2)} MB`);
        
        // Crear FormData
        const formData = new FormData();
        formData.append('data', JSON.stringify(datos));
        
        // Agregar archivos
        datos.archivos.forEach(formulario => {
            const tipoForm = formulario.formularioTipo;
            const archivos = formulario.archivos;
            
            archivos.forEach((archivo, index) => {
                const fieldName = `files_${tipoForm}[]`;
                formData.append(fieldName, archivo);
                console.log(`  📎 ${index + 1}. ${archivo.name} agregado como ${fieldName}`);
            });
        });
        
        return {
            method: 'POST',
            headers: {
                'X-Requested-With': 'XMLHttpRequest'
            },
            body: formData
        };
        
    } else {
        console.log('📤 Enviando sin archivos - usando JSON');
        
        return {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest'
            },
            body: JSON.stringify(datos)
        };
    }
}

function extraerTipoFormulario(formId) {
    // Extraer tipo de formulario del FormID para mostrar nombres amigables
    if (formId.includes('FormSolicVis')) return '📋 Solicitud de Visita'; // SOLVIS
    if (formId.includes('FormPTTransNac')) return '⚡ Plantas, Tableros y Transformadores Nacionales'; // FPETABTRANS
    if (formId.includes('FormPTTransUL')) return '⚡ Plantas, Tableros y Transformadores UL'; // FPETABTRANSUL
    if (formId.includes('FormAire')) return '❄️ Aires Acondicionados'; // Aires
    if (formId.includes('FormSistCritUPS')) return '🔋 Sistemas Críticos (UPS)'; // SCUPS
    if (formId.includes('FormGral')) return '📋 Formulario General';
    if (formId.includes('FormBess')) return '🔋 BESS'; // Step
    if (formId.includes('FormSolar')) return '☀️ Sistemas Solares'; // ← SOLARR
    if (formId.includes('FormEneCog')) return '⚡ Energía y Cogeneración'; // ← ENECOG
    if (formId.includes('FormImess')) return '🛡️ IMESS'; // ← IMESS
    if (formId.includes('FormProyecEsp')) return '🔧 Proyectos Especiales'; // PROYESP
    return '📄 Formulario Específico';
}

function limpiarFormularioCompleto() {
    try {
        console.log('🧹 Limpiando formulario completo...');
        
        // Limpiar campos de oportunidad
        limpiarCamposOportunidad();
        
        // Limpiar checkboxes de formularios
        const checkboxes = ['FormSolicVis', 'FormPTTransNac', 'FormPTTransUL', 'FormAire', 'FormSistCritUPS', 'FormBess', 'FormSolar', 'FormEneCog', 'FormImess', 'FormProyecEsp']; // Step // ← SOLARR // ← ENECOG // ← IMESS // ← AIRES // ← FPETABTRANS // ← FPETABTRANSUL // ← SCUPS // PROYESP // ← SOLVIS
        checkboxes.forEach(checkboxId => {
            const checkbox = document.getElementById(checkboxId);
            if (checkbox && checkbox.checked) {
                checkbox.checked = false;
                checkbox.dispatchEvent(new Event('change'));
            }
        });
        
        // Limpiar formulario general
        const formGeneral = document.querySelector('.section-FormGral');
        if (formGeneral) {
            const inputs = formGeneral.querySelectorAll('input, select, textarea');
            inputs.forEach(input => {
                if (input.type === 'checkbox' || input.type === 'radio') {
                    input.checked = false;
                } else {
                    input.value = '';
                }
                input.classList.remove('field-valid', 'field-invalid', 'field-pending');
            });
        }
        
        // Limpiar archivos de todos los módulos
        const modulos = ['FormSolicVis', 'FormPTTransNac', 'FormPTTransUL', 'FormAire', 'FormSistCritUPS', 'FormBess', 'FormSolar', 'FormEneCog', 'FormImess', 'FormProyecEsp']; // Step // ← SOLARR // ← ENECOG // ← IMESS // ← AIRES // ← FPETABTRANS // ← FPETABTRANSUL // ← SCUPS // PROYESP // ← GRAL // ← SOLVIS
        modulos.forEach(modulo => {
            if (window[modulo] && typeof window[modulo].clearAllFiles === 'function') {
                window[modulo].clearAllFiles();
            }
        });
        
        // Actualizar contadores
        actualizarTodosLosContadores();
        
        console.log('✅ Formulario limpiado completamente');
        
    } catch (error) {
        console.error('❌ Error limpiando formulario:', error);
    }
}

// ============================================
// API PÚBLICA PARA OTROS MÓDULOS
// ============================================

window.CotizacionEspecial = {
    
    // Validación
    validateForm: validateForm,
    validateSection: validateSection,
    validateBasicField: validateBasicField,
    
    // Utilidades
    clearFields: limpiarCamposOportunidad,
    showAlert: mostrarAlerta,
    showToast: mostrarNotificacionToast,
    
    // Búsqueda
    searchOpportunity: buscarOportunidad,
    
    // Envío
    procesarEnvio: procesarEnvioSolicitud,
    recopilarDatos: recopilarDatosSolicitud,
    validarCompleto: validarFormulariosCompletos,
    
    // Limpieza
    clearCompleteForm: limpiarFormularioCompleto,
    
    // Contadores
    updateCounters: actualizarTodosLosContadores,
    updateGeneralCounter: actualizarContadorGeneral,
    
    // Geolocalización
    loadCountriesData: cargarDatosPaises,
    fillStates: llenarSelectEstados,
    
    // Formularios dinámicos
    toggleFormSection: toggleFormularioSeccion,
    notifyFormVisible: notifyFormularioVisible
};

// ============================================
// FUNCIONES DE DEPURACIÓN MEJORADAS
// ============================================

function debugFormularios() {
    console.log('🔍 === DEBUG DE FORMULARIOS ===');

    const modulos = ['FormSolicVis', 'FormPTTransNac', 'FormPTTransUL', 'FormAire', 'FormSistCritUPS', 'FormBess', 'FormSolar', 'FormEneCog', 'FormImess', 'FormProyecEsp']; // Step // ← SOLARR // ← ENECOG // ← IMESS // ← AIRES // ← FPETABTRANS // ← FPETABTRANSUL // ← SCUPS // PROYESP // ← GRAL // ← SOLVIS

    modulos.forEach(modulo => {
        console.log(`\n📋 ${modulo}:`);
        
        if (!window[modulo]) {
            console.log('   ❌ Módulo no existe');
            return;
        }
        
        console.log('   ✅ Módulo existe');
        
        if (typeof window[modulo].getFiles === 'function') {
            const archivos = window[modulo].getFiles();
            console.log(`   📁 Archivos: ${archivos ? archivos.length : 0}`);
            
            if (archivos && archivos.length > 0) {
                archivos.forEach((archivo, index) => {
                    console.log(`      ${index + 1}. ${archivo.name} (${(archivo.size / 1024).toFixed(1)} KB)`);
                });
            }
        } else {
            console.log('   ⚠️ Función getFiles no disponible');
        }
        
        if (typeof window[modulo].getFileStats === 'function') {
            const stats = window[modulo].getFileStats();
            console.log('   📊 Estadísticas:', stats);
        }
    });
    
    // Debug de contadores
    console.log('\n📊 === DEBUG DE CONTADORES ===');
    Object.keys(CONFIG.REQUIRED_COUNTERS).forEach(sectionKey => {
        const config = CONFIG.REQUIRED_COUNTERS[sectionKey];
        const counter = document.getElementById(config.counterId);
        console.log(`${sectionKey}: ${counter ? counter.textContent : 'No encontrado'}`);
    });
    
    // Debug de validación
    console.log('\n✅ === DEBUG DE VALIDACIÓN ===');
    const requiredFields = document.querySelectorAll('[required]');
    console.log(`Total campos requeridos: ${requiredFields.length}`);
    
    let validCount = 0;
    let invalidCount = 0;
    let pendingCount = 0;
    
    requiredFields.forEach(field => {
        if (field.classList.contains('field-valid')) validCount++;
        else if (field.classList.contains('field-invalid')) invalidCount++;
        else if (field.classList.contains('field-pending')) pendingCount++;
    });
    
    console.log(`Válidos: ${validCount}, Inválidos: ${invalidCount}, Pendientes: ${pendingCount}`);
}

function debugGeolocation() {
    console.log('🌍 === DEBUG DE GEOLOCALIZACIÓN ===');
    
    if (!COUNTRIES_DATA) {
        console.log('❌ COUNTRIES_DATA no está cargado');
        return;
    }
    
    console.log('✅ COUNTRIES_DATA cargado correctamente');
    console.log(`📊 Total países: ${Object.keys(COUNTRIES_DATA).length}`);
    
    Object.entries(COUNTRIES_DATA).forEach(([code, country]) => {
        const statesCount = Object.keys(country.states).length;
        console.log(`🌐 ${code}: ${country.name} (${statesCount} estados/provincias)`);
        
        // Mostrar algunos estados como ejemplo
        const stateEntries = Object.entries(country.states);
        const sampleStates = stateEntries.slice(0, 3);
        sampleStates.forEach(([stateCode, stateName]) => {
            console.log(`   📍 ${stateCode}: ${stateName}`);
        });
        
        if (stateEntries.length > 3) {
            console.log(`   ... y ${stateEntries.length - 3} más`);
        }
    });
    
    // Verificar selectores
    console.log('\n🔍 === ESTADO DE SELECTORES ===');
    const countrySelect = document.getElementById('visitCountry');
    const stateSelect = document.getElementById('visitState');
    
    console.log(`Country Select: ${countrySelect ? 'Encontrado' : 'No encontrado'}`);
    if (countrySelect) {
        console.log(`  Opciones: ${countrySelect.options.length}`);
        console.log(`  Valor actual: "${countrySelect.value}"`);
    }
    
    console.log(`State Select: ${stateSelect ? 'Encontrado' : 'No encontrado'}`);
    if (stateSelect) {
        console.log(`  Opciones: ${stateSelect.options.length}`);
        console.log(`  Valor actual: "${stateSelect.value}"`);
        console.log(`  Deshabilitado: ${stateSelect.disabled}`);
    }
}

// Función global de debug disponible en consola
window.debugCotizacion = debugFormularios;
window.debugGeo = debugGeolocation;

// ============================================
// UTILIDADES ADICIONALES
// ============================================

function resetAllValidationStates() {
    console.log('🔄 Reseteando estados de validación...');
    
    const allFields = document.querySelectorAll('input, select, textarea');
    allFields.forEach(field => {
        field.classList.remove('field-valid', 'field-invalid', 'field-pending');
    });
    
    actualizarTodosLosContadores();
}

function forceValidateAllFields() {
    console.log('🔍 Forzando validación de todos los campos...');
    
    const requiredFields = document.querySelectorAll('[required]');
    requiredFields.forEach(field => {
        validateBasicField(field);
    });
    
    actualizarTodosLosContadores();
}

// Agregar funciones de utilidad a la API pública
window.CotizacionEspecial.resetValidation = resetAllValidationStates;
window.CotizacionEspecial.forceValidateAll = forceValidateAllFields;
window.CotizacionEspecial.debug = debugFormularios;
window.CotizacionEspecial.debugGeo = debugGeolocation;

// ============================================
// LOG DE INICIALIZACIÓN
// ============================================

console.log('✅ CotizEspSolicitud.js cargado completamente');
console.log('📋 Módulos disponibles:', Object.keys(window.CotizacionEspecial));
console.log('🔧 Funciones de debug disponibles:');
console.log('   - window.debugCotizacion() - Debug general de formularios');
console.log('   - window.debugGeo() - Debug de geolocalización');
console.log('🌍 API pública: window.CotizacionEspecial');