document.addEventListener('DOMContentLoaded', function () {
    const $ = jQuery;

    // --- VARIABLES GLOBALES ---
    let charts = {};
    let currentRows = [];
    let lastDashboardData = null; // Store fetched data for report
    let currentIndex = -1;
    let currentStatusFilter = 'active'; // Default view

    // --- VARIABLES PARA PAGINACIÓN (CARGAR MÁS) ---
    let allFetchedRows = [];
    let shownCount = 0;
    const BATCH_SIZE = efa_vars.batch_size || 100;

    // --- CHECK CHART.JS ---
    if (typeof Chart === 'undefined') {
        console.error('GW Analytics: Chart.js no se ha cargado correctamente.');
        $('.efa-wrapper').html('<div class="notice notice-error inline"><p>Error crítico: No se han podido cargar las librerías gráficas. Por favor, comprueba tu conexión a internet o contacta con soporte.</p></div>');
        return;
    }

    if (typeof ChartDataLabels !== 'undefined') { Chart.register(ChartDataLabels); }

    const body = $('body');
    const toggleBtn = $('#efa-theme-toggle');

    // --- INICIALIZACIÓN TEMA (Dark/Light) ---
    // Sincronizamos HTML y BODY para que el CSS funcione bien
    // Primero verificar si hay una preferencia guardada en localStorage (prioridad)
    // Si no, usar la preferencia por defecto del servidor
    let defaultTheme = 'light';
    if (typeof efa_vars !== 'undefined' && efa_vars.default_theme) {
        defaultTheme = efa_vars.default_theme;
    }
    
    // Si es 'auto', detectar preferencia del sistema
    if (defaultTheme === 'auto') {
        if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
            defaultTheme = 'dark';
        } else {
            defaultTheme = 'light';
        }
    }
    
    // Verificar localStorage primero (si el usuario ya cambió manualmente)
    const savedTheme = localStorage.getItem('efa_theme');
    const themeToUse = savedTheme || defaultTheme;
    
    if (themeToUse === 'dark') {
        $('html').addClass('efa-dark-mode');
        body.addClass('efa-dark-mode');
        updateToggleIcon(true);
    } else {
        updateToggleIcon(false);
    }

    toggleBtn.on('click', function () {
        $('html').toggleClass('efa-dark-mode');
        body.toggleClass('efa-dark-mode');
        const isDark = body.hasClass('efa-dark-mode');
        localStorage.setItem('efa_theme', isDark ? 'dark' : 'light');
        updateToggleIcon(isDark);
        updateChartsTheme();
    });

    function updateToggleIcon(isDark) {
        if (toggleBtn.length) {
            // Siempre usar bombilla, pero con diferentes colores según el modo
            const icon = 'dashicons-lightbulb';
            const title = isDark ? 'Cambiar a Modo Claro' : 'Cambiar a Modo Oscuro';
            toggleBtn.html(`<span class="dashicons ${icon}"></span>`);
            toggleBtn.attr('title', title);
        }
    }

    function getChartColors() {
        const isDark = body.hasClass('efa-dark-mode');
        return { grid: isDark ? '#3a3a5e' : '#e5e5e5', text: isDark ? '#a0a0c0' : '#666666', tooltipBg: isDark ? 'rgba(42,42,62,0.9)' : 'rgba(0,0,0,0.8)', tooltipText: '#ffffff' };
    }

    function updateChartsTheme() {
        const colors = getChartColors();
        Object.values(charts).forEach(chart => {
            if (!chart) return;
            if (chart.options.scales && chart.options.scales.x) {
                if (chart.options.scales.x.grid) chart.options.scales.x.grid.color = colors.grid;
                if (chart.options.scales.x.ticks) chart.options.scales.x.ticks.color = colors.text;
            }
            if (chart.options.scales && chart.options.scales.y) {
                if (chart.options.scales.y.grid) chart.options.scales.y.grid.color = colors.grid;
                if (chart.options.scales.y.ticks) chart.options.scales.y.ticks.color = colors.text;
            }
            if (chart.options.plugins.legend) chart.options.plugins.legend.labels.color = colors.text;
            if (chart.options.plugins.datalabels) chart.options.plugins.datalabels.color = body.hasClass('efa-dark-mode') ? '#fff' : '#444';
            chart.update('none');
        });
    }

    const SEMANTIC_COLORS = { 'facebook': '#1877F2', 'instagram': '#E1306C', 'google': '#4285F4', 'youtube': '#FF0000', 'ads': '#EA4335', 'organic': '#34A853', 'organico': '#34A853', 'seo': '#34A853', 'whatsapp': '#25D366', 'linkedin': '#0A66C2', 'tiktok': '#000000', 'email': '#FBBC05', 'newsletter': '#FBBC05', 'chatgpt': '#000000', 'directo': '#646970', 'referral': '#A142F4' };
    const FALLBACK_PALETTE = ['#0d9488', '#be123c', '#d97706', '#4338ca', '#a21caf', '#15803d', '#0369a1', '#b91c1c'];

    function getColorForString(str) {
        if (!str) return '#646970'; const lower = str.toLowerCase().trim();
        if (SEMANTIC_COLORS[lower]) return SEMANTIC_COLORS[lower];
        for (const [key, color] of Object.entries(SEMANTIC_COLORS)) { if (lower.includes(key)) return color; }
        let hash = 0; for (let i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); }
        return FALLBACK_PALETTE[Math.abs(hash % FALLBACK_PALETTE.length)];
    }

    // Helper function to highlight keywords in text
    function highlightKeywords(text, keywords) {
        if (!text || !keywords || keywords.length === 0) return text;

        let result = text;
        keywords.forEach(keyword => {
            if (!keyword || keyword.trim() === '') return;

            // Escape special regex characters in keyword
            const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
            const regex = new RegExp(`(${escapedKeyword})`, 'gi');

            result = result.replace(regex, '<span class="efa-highlight-keyword">$1</span>');
        });

        return result;
    }

    // Helper function to format dates nicely
    function formatDateNicely(dateString) {
        if (!dateString) return '-';

        const date = new Date(dateString);
        const now = new Date();

        // Calculate days difference
        const diffTime = now - date;
        const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));

        // Month names in Spanish
        const months = ['ENE', 'FEB', 'MAR', 'ABR', 'MAY', 'JUN', 'JUL', 'AGO', 'SEP', 'OCT', 'NOV', 'DIC'];

        // Format: 02 OCT 25 (19:34h)
        const day = String(date.getDate()).padStart(2, '0');
        const month = months[date.getMonth()];
        const year = String(date.getFullYear()).slice(-2);
        const hours = String(date.getHours()).padStart(2, '0');
        const minutes = String(date.getMinutes()).padStart(2, '0');

        let formattedDate = `${day} ${month} ${year} (${hours}:${minutes}h)`;

        // Add relative time with color
        let relativeTime = '';
        if (diffDays === 0) {
            relativeTime = 'Hoy';
        } else if (diffDays === 1) {
            relativeTime = 'Ayer';
        } else if (diffDays < 30) {
            relativeTime = `Hace ${diffDays} días`;
        } else if (diffDays < 365) {
            const months = Math.floor(diffDays / 30);
            relativeTime = `Hace ${months} ${months === 1 ? 'mes' : 'meses'}`;
        } else {
            const years = Math.floor(diffDays / 365);
            relativeTime = `Hace ${years} ${years === 1 ? 'año' : 'años'}`;
        }

        if (relativeTime) {
            formattedDate += ` - <span style="color: #e01d75; font-weight: 600;">${relativeTime}</span>`;
        }

        return formattedDate;
    }

    const dom = {
        formFilter: $('#efa-form-filter'), dateRange: $('#efa-date-range'), customDates: $('#efa-custom-dates'), startDate: $('#efa-start-date'), endDate: $('#efa-end-date'), btnApply: $('#efa-apply-filters'),
        statusFilter: $('#efa-status-filter'), commercialFilter: $('#efa-commercial-filter'), btnDeleteAll: $('#efa-btn-delete-all'), btnExcel: $('#efa-btn-excel'),
        tableBody: $('#efa-table-body'),
        modalOverlay: $('.efa-modal-overlay'), slidePanel: $('.efa-slide-panel'), panelContent: $('#efa-panel-content'), closeBtn: $('.efa-close-btn'),
        prevBtn: $('#efa-prev-btn'), nextBtn: $('#efa-next-btn'), navCounter: $('#efa-nav-counter'),
        panelSpamBtn: $('#efa-panel-spam-btn'), panelDeleteBtn: $('#efa-panel-delete-btn'), // Botones removidos del HTML pero mantenidos para compatibilidad
        btnWa: $('#efa-btn-wa'), btnReply: $('#efa-btn-reply'),
        btnCols: $('#efa-btn-cols'), colsDropdown: $('#efa-cols-dropdown'),
        loadingOverlay: $('#efa-loading-overlay')
    };

    // --- SEARCH LOGIC ---
    $('#efa-search-input').on('input', function () {
        const term = $(this).val().toLowerCase().trim();

        if (term === '') {
            currentRows = [...allFetchedRows];
        } else {
            currentRows = allFetchedRows.filter(row => {
                // Buscamos en todos los campos relevantes
                const searchableText = [
                    row.form,
                    row.origin,
                    row.name,
                    row.email,
                    row.phone,
                    row.id,
                    row.crm_status
                ].join(' ').toLowerCase();

                return searchableText.includes(term);
            });
        }

        // Aplicar filtro de destacados si está activo
        const isHighlightedFilterActive = $('#efa-toggle-highlighted').is(':checked');
        if (isHighlightedFilterActive) {
            currentRows = currentRows.filter(row => row.highlight === true);
        }

        // Render filtered table
        shownCount = 0;
        dom.tableBody.empty();
        renderNextBatch();
    });

    // --- HIGHLIGHTED FILTER TOGGLE ---
    $('#efa-toggle-highlighted').on('change', function () {
        const term = $('#efa-search-input').val().toLowerCase().trim();
        const isHighlightedFilterActive = $(this).is(':checked');

        // Empezar desde todos los registros
        if (term === '') {
            currentRows = [...allFetchedRows];
        } else {
            currentRows = allFetchedRows.filter(row => {
                const searchableText = [
                    row.form,
                    row.origin,
                    row.name,
                    row.email,
                    row.phone,
                    row.id,
                    row.crm_status
                ].join(' ').toLowerCase();
                return searchableText.includes(term);
            });
        }

        // Aplicar filtro de destacados
        if (isHighlightedFilterActive) {
            currentRows = currentRows.filter(row => row.highlight === true);
        }

        shownCount = 0;
        dom.tableBody.empty();
        renderNextBatch();
    });

    // --- CUSTOM DATE RANGE LOGIC ---
    dom.dateRange.on('change', function () {
        const selected = $(this).val();
        if (selected === 'custom') {
            dom.customDates.removeClass('efa-hidden').show();
        } else {
            dom.customDates.addClass('efa-hidden').hide();
        }
    });

    // Trigger on page load to show/hide based on current selection
    if (dom.dateRange.length) {
        const initialValue = dom.dateRange.val();
        if (initialValue === 'custom') {
            dom.customDates.removeClass('efa-hidden').show();
        } else {
            dom.customDates.addClass('efa-hidden').hide();
        }
    }

    // --- INYECCIÓN DEL BOTÓN "CARGAR MÁS" ---
    $('.efa-main-layout').after(`
        <div class="efa-load-more-container">
            <button id="efa-btn-load-more" class="efa-btn-load-more hidden">
                <span class="dashicons dashicons-arrow-down-alt2"></span> Cargar más
            </button>
        </div>
    `);

    // --- ORIGIN DROPDOWN LOGIC ---
    const originBtn = $('#efa-origin-btn');
    const originDropdown = $('#efa-origin-dropdown');
    const originAll = $('#efa-origin-all');
    const originChecks = $('.efa-origin-check');

    if (originBtn.length) {
        originBtn.on('click', function (e) {
            e.stopPropagation();
            originDropdown.toggleClass('open');
            // Close others
            $('#efa-form-dropdown').removeClass('open');
        });

        $(document).on('click', function (e) {
            if (!$(e.target).closest('#efa-origin-wrapper').length) {
                originDropdown.removeClass('open');
            }
        });

        // Select All
        originAll.on('change', function () {
            const isChecked = $(this).is(':checked');
            originChecks.prop('checked', isChecked);
            updateOriginButtonText();
        });

        // Individual Checks
        originChecks.on('change', function () {
            const allChecked = originChecks.length === originChecks.filter(':checked').length;
            originAll.prop('checked', allChecked);
            updateOriginButtonText();
        });

        function updateOriginButtonText() {
            const checkedCount = originChecks.filter(':checked').length;
            const totalCount = originChecks.length;

            if (checkedCount === totalCount) {
                originBtn.find('span:first').text('Orígenes: Todos');
            } else if (checkedCount === 0) {
                originBtn.find('span:first').text('Orígenes: Ninguno');
            } else {
                originBtn.find('span:first').text(`Orígenes: ${checkedCount}`);
            }
        }

        // Init text
        updateOriginButtonText();
    }

    // --- FORM DROPDOWN LOGIC ---
    const formBtn = $('#efa-form-btn');
    const formDropdown = $('#efa-form-dropdown');
    const formAll = $('#efa-form-all');
    const formChecks = $('.efa-form-check');

    if (formBtn.length) {
        formBtn.on('click', function (e) {
            e.stopPropagation();
            formDropdown.toggleClass('open');
            // Close others
            $('#efa-origin-dropdown').removeClass('open');
        });

        $(document).on('click', function (e) {
            if (!$(e.target).closest('#efa-form-wrapper').length) {
                formDropdown.removeClass('open');
            }
        });

        // Select All
        formAll.on('change', function () {
            const isChecked = $(this).is(':checked');
            formChecks.prop('checked', isChecked);
            updateFormButtonText();
        });

        // Individual Checks
        formChecks.on('change', function () {
            const allChecked = formChecks.length === formChecks.filter(':checked').length;
            formAll.prop('checked', allChecked);
            updateFormButtonText();
        });

        function updateFormButtonText() {
            const checkedCount = formChecks.filter(':checked').length;
            const totalCount = formChecks.length;

            if (checkedCount === totalCount) {
                formBtn.find('span:first').text('Formularios: Todos');
            } else if (checkedCount === 0) {
                formBtn.find('span:first').text('Formularios: Ninguno');
            } else {
                formBtn.find('span:first').text(`Formularios: ${checkedCount}`);
            }
        }

        // Init text
        updateFormButtonText();
    }

    // Listener del botón cargar más
    $('#efa-btn-load-more').on('click', function () {
        renderNextBatch();
    });

    // === TOOLTIP HANDLER ===
    const tooltip = $('<div class="efa-tooltip"></div>').appendTo('body');

    $(document).on('mouseenter', '.efa-tooltip-header', function (e) {
        const text = $(this).attr('data-tooltip');
        const rect = this.getBoundingClientRect();

        tooltip.text(text).show();

        const tooltipWidth = tooltip.outerWidth();
        const left = rect.left + (rect.width / 2) - (tooltipWidth / 2);
        const top = rect.top - tooltip.outerHeight() - 8;

        tooltip.css({
            left: left + 'px',
            top: top + 'px'
        });
    });

    $(document).on('mouseleave', '.efa-tooltip-header', function () {
        tooltip.hide();
    });

    // === COLUMNS CONFIGURATION ===
    const tableColumns = [
        { id: 'date', label: 'Fecha', index: 0, def: true, key: 'date' },
        { id: 'form', label: 'Formulario', index: 1, def: false, key: 'form' },
        { id: 'origin', label: 'Origen', index: 2, def: true, key: 'origin' },
        { id: 'name', label: 'Nombre', index: 3, def: true, key: 'name' },
        { id: 'email', label: 'Email', index: 4, def: true, key: 'email' },
        { id: 'phone', label: 'Teléfono', index: 5, def: true, key: 'phone' },
        { id: 'landing', label: 'Landing', index: 6, def: false, key: 'landing' },
        { id: 'prev', label: 'Previa', index: 7, def: false, key: 'prev' },
        { id: 'lead', label: 'Lead', index: 8, def: false, key: 'lead_page' },
        { id: 'crm_status', label: 'Estado CRM', index: 9, def: true, key: 'crm_status' },
        { id: 'mail', label: 'Mail (Comercial)', index: 10, def: true, key: 'is_commercial' },
        { id: 'id', label: 'ID', index: 11, def: false, key: 'id' },
        { id: 'status', label: 'Spam', index: 12, def: true, key: 'risk' },
        { id: 'action', label: 'Acción', index: 13, def: true, key: null }
    ];

    if (dom.tableBody.length) {
        tableColumns.forEach(col => {
            const checked = col.def ? 'checked' : '';
            dom.colsDropdown.append(`
                <label class="efa-col-option">
                    <input type="checkbox" class="efa-col-check" data-index="${col.index}" ${checked}> ${col.label}
                </label>
            `);
        });

        dom.btnCols.on('click', function (e) {
            e.stopPropagation();
            dom.colsDropdown.toggleClass('open');
        });

        $(document).on('click', function (e) {
            if (!$(e.target).closest('.efa-columns-wrapper').length) {
                dom.colsDropdown.removeClass('open');
            }
        });

        $(document).on('change', '.efa-col-check', function () {
            const index = $(this).data('index');
            const isVisible = $(this).is(':checked');
            toggleColumn(index, isVisible);
        });
    }

    function toggleColumn(index, isVisible) {
        // nth-child is 1-based. index comes from data-index which is 0-based.
        // So we need index + 1.
        $(`table.efa-table th:nth-child(${index + 1})`).toggle(isVisible);
        $(`table.efa-table td:nth-child(${index + 1})`).toggle(isVisible);
    }

    function applyColumnVisibility() {
        $('.efa-col-check').each(function () {
            const idx = $(this).data('index');
            const visible = $(this).is(':checked');
            toggleColumn(idx, visible);
        });
    }

    function renderTable(rows, append = false) {
        if (!dom.tableBody.length) return;

        if (!append && rows.length === 0) {
            dom.tableBody.html('<tr><td colspan=13 class="efa-no-data">Sin datos</td></tr>');
            return;
        }

        let html = '';
        rows.forEach(row => {
            const color = getColorForString(row.origin);

            // Spam Status: Icon Only
            let spamBadge = '';
            if (row.risk === 2) {
                spamBadge = '<span class="efa-badge spam"><span class="dashicons dashicons-warning"></span></span>';
            } else {
                spamBadge = '<span class="efa-badge safe"><span class="dashicons dashicons-shield"></span></span>';
            }

            let rowClass = row.is_commercial ? 'efa-commercial-row' : '';
            if (row.highlight) {
                rowClass += ' efa-highlight-row';
            }
            if (row.read_status != '1') {
                rowClass += ' efa-unread';
            }

            let mailDot = row.is_commercial
                ? '<span class="efa-dot-green" title="Aceptado"></span>'
                : '<span class="efa-dot-red" title="No Aceptado"></span>';

            let crmStatus = row.crm_status || 'new';
            let crmLabel = 'Nuevo';
            let crmColor = '#2271b1';
            if (typeof efa_vars !== 'undefined' && efa_vars.crm_labels) {
                const labelObj = efa_vars.crm_labels.find(l => l.id === crmStatus);
                if (labelObj) {
                    crmLabel = labelObj.label;
                    crmColor = labelObj.color;
                }
            }

            let notesBadge = (row.notes_count && row.notes_count > 0) ? `<span class="efa-notes-badge-table" title="${row.notes_count} notas">${row.notes_count}</span>` : '';
            // Badge inside the button
            let crmBadge = `<span class="efa-crm-badge" style="background-color: ${crmColor}; color: #fff; display:inline-flex;align-items:center;">${crmLabel}${notesBadge}</span>`;

            // Add arrow if replied, with count if more than 1
            let dateDisplay = row.date;
            if (row.replied_status && row.replied_status !== '') {
                const repliesCount = row.replies_count || (row.replied_status ? 1 : 0);
                const countText = repliesCount > 1 ? `${repliesCount}` : '';
                dateDisplay = `${row.date} <span style="color: #e01d75; font-weight: bold; margin-left: 4px;" title="${repliesCount} respuesta${repliesCount > 1 ? 's' : ''} enviada${repliesCount > 1 ? 's' : ''}">${countText}→</span>`;
            }

            html += `<tr data-id="${row.id}" class="${rowClass}">
                <td style="width:90px;">${dateDisplay}</td>
                <td title="${row.form}">${row.form}</td>
                <td><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${color};margin-right:5px;"></span>${row.origin}</td>
                <td title="${row.name || ''}">${row.name || '-'}</td>
                <td class="efa-cell-email" title="${row.email || ''}">${row.email || '-'}</td>
                <td>${row.phone || '-'}</td>
                <td class="efa-cell-url" title="${row.landing || ''}">${row.landing || '-'}</td>
                <td class="efa-cell-url" title="${row.prev || ''}">${row.prev || '-'}</td>
                <td class="efa-cell-url" title="${row.lead_page || ''}">${row.lead_page || '-'}</td>
                <td>${crmBadge}</td>
                <td style="text-align:center;">${mailDot}</td>
                <td style="width:50px;">#${row.id}</td>
                <td class="efa-cell-status" style="text-align:center;">${spamBadge}</td>
                <td style="text-align:center;width:50px;"><span class="dashicons dashicons-trash efa-delete-btn" title="Eliminar"></span></td>
            </tr>`;
        });

        if (append) {
            dom.tableBody.append(html);
        } else {
            dom.tableBody.html(html);
        }

        applyColumnVisibility();
    }

    dom.btnApply.on('click', (e) => { e.preventDefault(); fetchData(); });

    // --- VIEW SELECTOR LOGIC ---
    // --- SIDEBAR NAVIGATION ---
    // --- SIDEBAR NAVIGATION ---
    // Static items (Todos, Destacados, Spam, Papelera)
    $('.efa-nav-item[data-filter]').on('click', function () {
        $('.efa-nav-item').removeClass('active');
        $(this).addClass('active');

        const filter = $(this).data('filter');

        // Reset specific filters
        $('#efa-current-status-filter').val('active');
        $('#efa-current-form-filter').val('');
        window.currentCrmStateFilter = null;

        // Set context based on filter
        if (filter === 'trash') {
            $('#efa-current-status-filter').val('trash');
        } else if (filter === 'spam') {
            // Spam is handled via risk_filter in fetchData, but we can set a flag or just rely on the active class logic in fetchData if we wanted, 
            // but fetchData uses risk_filter param. 
            // Let's pass the override to fetchData directly or set a global.
            // Actually fetchData takes arguments.
        }

        // We need to pass the correct overrides to fetchData
        let statusOverride = 'active';
        let riskOverride = 'all';
        let highlightOverride = false;
        let repliedOverride = false;
        let unreadOverride = false;

        if (filter === 'trash') {
            statusOverride = 'trash';
        } else if (filter === 'spam') {
            riskOverride = 'spam';
        } else if (filter === 'starred') {
            highlightOverride = true;
        } else if (filter === 'replied') {
            repliedOverride = true;
        } else if (filter === 'unread') {
            unreadOverride = true;
        } else if (filter === 'all') {
            // Default
        }

        fetchData(statusOverride, riskOverride, highlightOverride, repliedOverride, unreadOverride);
    });

    // --- LÓGICA DE FILTROS Y BOTÓN BORRAR ---
    updateDeleteButtonVisibility();

    $('#efa-toggle-safe, #efa-toggle-spam, #efa-toggle-commercial').on('change', function () {
        updateDeleteButtonVisibility();
        fetchData();
    });

    function updateDeleteButtonVisibility() {
        let showSpam = $('#efa-toggle-spam').is(':checked');
        let showSafe = $('#efa-toggle-safe').is(':checked');

        if (showSpam && !showSafe) {
            dom.btnDeleteAll.removeClass('efa-hidden');
        } else {
            dom.btnDeleteAll.addClass('efa-hidden');
        }
    }

    // Arrancamos datos
    fetchData();

    // --- RESIZABLE COLUMNS ---
    function makeColumnsResizable() {
        const table = $('.efa-table');
        const headers = table.find('thead th');

        headers.each(function (index) {
            const th = $(this);

            // Don't add resizer to last column (Acción)
            if (index === headers.length - 1) return;

            const resizer = $('<div class="column-resizer"></div>');
            th.css('position', 'relative');
            th.append(resizer);

            let startX, startWidth;

            resizer.on('mousedown', function (e) {
                e.preventDefault();
                e.stopPropagation();

                startX = e.pageX;
                startWidth = th.outerWidth();

                $(document).on('mousemove.resize', function (e) {
                    const diff = e.pageX - startX;
                    const newWidth = Math.max(50, startWidth + diff); // Min width 50px

                    th.css('width', newWidth + 'px');

                    // Update corresponding cells
                    const columnIndex = th.index();
                    table.find('tbody tr').each(function () {
                        $(this).find('td').eq(columnIndex).css('width', newWidth + 'px');
                    });
                });

                $(document).on('mouseup.resize', function () {
                    $(document).off('mousemove.resize mouseup.resize');

                    // Save column widths to localStorage
                    saveColumnWidths();
                });
            });
        });

        // Load saved column widths
        loadColumnWidths();
    }

    function saveColumnWidths() {
        const widths = [];
        $('.efa-table thead th').each(function () {
            const width = $(this).css('width');
            widths.push(width);
        });
        localStorage.setItem('efa_column_widths', JSON.stringify(widths));
    }

    function loadColumnWidths() {
        const savedWidths = localStorage.getItem('efa_column_widths');
        if (savedWidths) {
            try {
                const widths = JSON.parse(savedWidths);
                $('.efa-table thead th').each(function (index) {
                    if (widths[index]) {
                        $(this).css('width', widths[index]);
                    }
                });
            } catch (e) {
                console.error('Error loading column widths:', e);
            }
        }
    }

    // Initialize resizable columns after first render
    setTimeout(makeColumnsResizable, 500);

    // --- EXPORT TO EXCEL ---
    dom.btnExcel.on('click', function (e) {
        e.preventDefault();
        if (currentRows.length === 0) { alert('No hay datos para exportar'); return; }

        let visibleCols = [];
        $('.efa-col-check:checked').each(function () {
            const idx = $(this).data('index');
            const colDef = tableColumns.find(c => c.index === idx);
            if (colDef) visibleCols.push(colDef);
        });

        if (visibleCols.length === 0) { alert('Selecciona al menos una columna'); return; }

        // Separador desde PHP (configuración)
        const sep = (typeof efa_vars.separator !== 'undefined') ? efa_vars.separator : ';';

        let csvContent = "data:text/csv;charset=utf-8,\uFEFF";
        let headerRow = visibleCols.map(c => c.label).join(sep);
        csvContent += headerRow + "\n";

        currentRows.forEach(function (row) {
            let rowData = [];
            visibleCols.forEach(col => {
                if (col.id === 'action') { rowData.push(""); return; }
                let val = '';
                if (col.id === 'status') { val = (row.risk === 2) ? 'Spam' : 'Correcto'; }
                else if (col.id === 'mail') { val = row.is_commercial ? 'Si' : 'No'; }
                else { val = row[col.key] || ''; if (typeof val === 'string') val = val.replace(/"/g, '""'); }
                rowData.push(`"${val}"`);
            });
            csvContent += rowData.join(sep) + "\n";
        });

        const encodedUri = encodeURI(csvContent);
        const link = document.createElement("a");
        link.setAttribute("href", encodedUri);
        const today = new Date().toISOString().slice(0, 10);
        link.setAttribute("download", `leads_export_${today}.csv`);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    });

    // --- MODAL HANDLER ---
    $(document).on('click', '.efa-table tbody tr', function (e) {
        if ($(e.target).closest('.efa-badge').length || $(e.target).closest('.efa-delete-btn').length) return;

        const id = $(this).data('id');
        const idx = currentRows.findIndex(r => r.id == id);
        
        // Store the row index in the visible table (for navigation in unread filter)
        const rowIndex = $(this).index();

        // Check if clicked on CRM badge or Notes badge
        const isCrmClick = $(e.target).closest('.efa-crm-badge').length > 0 || $(e.target).closest('.efa-notes-badge-table').length > 0;

        // Don't call markAsRead here - let openModal handle it
        // This avoids double filtering of currentRows
        openModal(idx, isCrmClick, rowIndex);
    });

    function markAsRead(id, index) {
        // Optimistic update
        if (currentRows[index]) {
            currentRows[index].read_status = '1';
        }
        const row = $(`tr[data-id="${id}"]`);
        row.removeClass('efa-unread');

        // Update master array too
        const masterIdx = allFetchedRows.findIndex(r => r.id == id);
        if (masterIdx > -1) allFetchedRows[masterIdx].read_status = '1';

        // Update highlighted unread count if this was a highlighted email
        if (currentRows[index] && currentRows[index].highlight) {
            updateHighlightedUnreadCount(-1);
        }

        // Update unread counter in sidebar (decrement by 1)
        if (lastDashboardData && lastDashboardData.sidebar_counts && lastDashboardData.sidebar_counts.unread !== undefined) {
            // Decrement the backend count by 1
            lastDashboardData.sidebar_counts.unread = Math.max(0, lastDashboardData.sidebar_counts.unread - 1);
            $('#efa-count-unread').text(lastDashboardData.sidebar_counts.unread);
        } else {
            // Fallback: recalculate from allFetchedRows
            updateUnreadCounter();
        }

        // If we're in "Sin leer" filter and panel is open, filter currentRows and update navigation
        // BUT: Don't do this if we're navigating (handled separately in nextBtn/prevBtn handlers)
        // This is only for when markAsRead is called from other places (like clicking on a row)
        if (window.currentUnreadFilter && dom.slidePanel.hasClass('open')) {
            // Check if this is being called from navigation (we'll skip the auto-reload in that case)
            // We can detect this by checking if currentIndex matches the removed index
            const previousLength = currentRows.length;
            const removedIndex = index; // Store the index of the removed item
            currentRows = currentRows.filter(r => !r.read_status || r.read_status === '0' || r.read_status !== '1');
            
            // Find the new index of the current email (if it's still unread) or adjust to next/previous
            if (currentRows.length < previousLength) {
                // The email at 'index' was removed
                // Adjust currentIndex: if currentIndex was at or after the removed item, adjust it
                if (currentIndex > removedIndex) {
                    // We were after the removed item, so decrement (item shifted left)
                    currentIndex--;
                } else if (currentIndex === removedIndex) {
                    // We were at the removed item
                    // Stay at the same index (which now points to what was index+1)
                    // currentIndex stays the same, no change needed
                }
                // If currentIndex < removedIndex, it stays the same (item before removed one)
                
                // Ensure index is valid
                if (currentIndex >= currentRows.length && currentRows.length > 0) {
                    currentIndex = currentRows.length - 1;
                } else if (currentIndex < 0) {
                    currentIndex = 0;
                }
                
                // Update navigation counter
                updateNavState();
                
                // If there are no more unread emails, close the panel
                if (currentRows.length === 0) {
                    closeModal();
                } else if (currentIndex >= 0 && currentIndex < currentRows.length) {
                    // Only reload if we're NOT navigating (navigation handles its own reload)
                    // We can detect navigation by checking if the removed index was the next index
                    const isNavigating = (removedIndex === currentIndex + 1);
                    if (!isNavigating) {
                        // Reload the current email details if panel is still open (without marking as read)
                        const newRowData = currentRows[currentIndex];
                        if (newRowData && newRowData.id !== id) {
                            // Only reload if it's a different email - load without marking as read
                            window.currentRowData = newRowData;
                            dom.panelContent.html('<div style="text-align:center;padding:40px;">Cargando datos...</div>');
                            $.ajax({
                                url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
                                data: { action: 'efa_get_submission_details', nonce: efa_vars.nonce, id: newRowData.id },
                                success: function (res) {
                                    if (res.success) {
                                        renderDetails(res.data, newRowData);
                                    } else {
                                        dom.panelContent.html('Error.');
                                    }
                                }
                            });
                        } else {
                            // Same email or no valid row, just update nav state
                            updateNavState();
                        }
                    }
                }
            } else {
                // Email is still in list, just update nav state
                updateNavState();
            }
        }

        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_mark_as_read', nonce: efa_vars.nonce, id: id }
        });
    }

    function updateHighlightedUnreadBadge(count) {
        const badge = $('#efa-highlight-badge');
        const countElement = $('#efa-highlight-count');

        if (count > 0) {
            countElement.text(count);
            badge.fadeIn(300);
        } else {
            badge.fadeOut(300);
        }
    }

    function updateHighlightedToggle() {
        const toggleWrapper = $('#efa-highlight-filter-wrapper');

        // Count highlighted emails in current results (read or unread)
        const highlightedCount = currentRows.filter(r => r.highlight).length;

        if (highlightedCount > 0) {
            toggleWrapper.fadeIn(300);
        } else {
            toggleWrapper.fadeOut(300);
            // Reset toggle when no highlighted emails
            $('#efa-toggle-highlighted').prop('checked', false);
        }
    }

    function updateHighlightedUnreadCount(delta) {
        const countElement = $('#efa-highlight-count');
        const currentCount = parseInt(countElement.text()) || 0;
        const newCount = Math.max(0, currentCount + delta);
        updateHighlightedUnreadBadge(newCount);
    }

    dom.closeBtn.on('click', closeModal); dom.modalOverlay.on('click', closeModal);
    dom.prevBtn.on('click', function () { 
        if (currentIndex > 0) {
            // When navigating, mark as read if not already read (for unread filter)
            const newIndex = currentIndex - 1;
            if (newIndex >= 0 && newIndex < currentRows.length) {
                currentIndex = newIndex;
                const rowData = currentRows[currentIndex];
                if (rowData) {
                    // Mark as read if not already read (only in unread filter)
                    if (window.currentUnreadFilter && rowData.read_status != '1') {
                        markAsRead(rowData.id, currentIndex);
                        // After markAsRead, currentRows and currentIndex may have changed
                        // Re-get the rowData in case index changed
                        if (currentIndex >= 0 && currentIndex < currentRows.length) {
                            window.currentRowData = currentRows[currentIndex];
                        } else {
                            // Index changed, use the new current index
                            if (currentRows.length > 0 && currentIndex < currentRows.length) {
                                window.currentRowData = currentRows[currentIndex];
                            } else {
                                return; // No more rows
                            }
                        }
                    } else {
                        window.currentRowData = rowData;
                    }
                    updateNavState();
                    dom.panelContent.html('<div style="text-align:center;padding:40px;">Cargando datos...</div>');
                    const finalRowData = window.currentRowData;
                    if (finalRowData) {
                        $.ajax({
                            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
                            data: { action: 'efa_get_submission_details', nonce: efa_vars.nonce, id: finalRowData.id },
                            success: function (res) {
                                if (res.success) {
                                    renderDetails(res.data, finalRowData);
                                    updateNavState(); // Update again after loading
                                } else {
                                    dom.panelContent.html('Error.');
                                }
                            }
                        });
                    }
                }
            }
        }
    });
    dom.nextBtn.on('click', function () { 
        // DEBUG: Log current state
        console.log('=== NEXT BUTTON CLICK ===');
        console.log('currentIndex:', currentIndex);
        console.log('currentRows.length:', currentRows.length);
        console.log('currentUnreadFilter:', window.currentUnreadFilter);
        console.log('currentRowData.id:', window.currentRowData?.id);
        console.log('First 5 currentRows IDs:', currentRows.slice(0, 5).map(r => r.id));
        
        // In unread filter, if we're showing a read email (currentIndex = -1),
        // we need to find the next unread email in the original table order
        let nextIndex;
        if (window.currentUnreadFilter && currentRows.length > 0) {
            // Check if currentIndex is -1 (meaning we're showing a read email that was filtered out)
            if (currentIndex === -1) {
                // Current email is not in currentRows (it was filtered out because it's read)
                // Use the stored nextUnreadIndex if available, otherwise find it from allFetchedRows
                if (window.nextUnreadIndex !== undefined && window.nextUnreadIndex >= 0) {
                    nextIndex = window.nextUnreadIndex;
                    console.log('Using stored nextUnreadIndex =', nextIndex);
                } else {
                    // Find the next unread email after the current one in allFetchedRows
                    const currentId = window.currentRowData?.id;
                    if (currentId) {
                        const currentIndexInAll = allFetchedRows.findIndex(r => r.id == currentId);
                        if (currentIndexInAll >= 0 && currentIndexInAll < allFetchedRows.length - 1) {
                            // Look for the next unread email after the current one
                            for (let i = currentIndexInAll + 1; i < allFetchedRows.length; i++) {
                                const r = allFetchedRows[i];
                                if (!r.read_status || r.read_status === '0' || r.read_status !== '1') {
                                    // Found the next unread email, now find its index in currentRows
                                    nextIndex = currentRows.findIndex(cr => cr.id == r.id);
                                    console.log('Found next unread at allFetchedRows[' + i + '], currentRows index =', nextIndex);
                                    break;
                                }
                            }
                        }
                    }
                    if (nextIndex === undefined || nextIndex < 0) {
                        // Fallback to first unread email
                        nextIndex = 0;
                        console.log('Using nextIndex = 0 (fallback)');
                    }
                }
            } else if (currentIndex >= 0 && currentIndex < currentRows.length) {
                // Current email is in currentRows, so next is currentIndex + 1
                nextIndex = currentIndex + 1;
                console.log('Using nextIndex =', nextIndex, '(currentIndex + 1)');
            } else {
                // Invalid index, go to first
                nextIndex = 0;
                console.log('Using nextIndex = 0 (invalid currentIndex)');
            }
        } else {
            // Not in unread filter, just move to next
            nextIndex = currentIndex + 1;
            console.log('Using nextIndex =', nextIndex, '(not in unread filter)');
        }
        
        // Validate nextIndex
        if (nextIndex < 0) nextIndex = 0;
        if (nextIndex >= currentRows.length) {
            if (currentRows.length > 0) {
                nextIndex = currentRows.length - 1;
            } else {
                closeModal();
                return;
            }
        }
        
        console.log('Final nextIndex:', nextIndex);
        console.log('nextRowData.id:', currentRows[nextIndex]?.id);
        console.log('========================');
        
        if (nextIndex >= 0 && nextIndex < currentRows.length) {
            const nextRowData = currentRows[nextIndex];
            if (nextRowData) {
                const nextId = nextRowData.id;
                console.log('NEXT: About to show email id=' + nextId + ' at index=' + nextIndex);
                
                // Mark as read if not already read (only in unread filter)
                if (window.currentUnreadFilter && nextRowData.read_status != '1') {
                    // IMPORTANT: First, find the NEXT unread email AFTER nextId in the table
                    // We need to do this BEFORE marking nextId as read, so we can find it in the table
                    const nextIdRow = $(`tr[data-id="${nextId}"]`);
                    const nextIdTableIndex = nextIdRow.index();
                    console.log('NEXT: nextId=' + nextId + ', table row index=' + nextIdTableIndex);
                    
                    // Look for the next unread email in the table after nextId
                    const tableRows = $('.efa-table tbody tr');
                    let foundNextUnreadId = null;
                    let foundNextUnreadTableIndex = -1;
                    
                    for (let i = nextIdTableIndex + 1; i < tableRows.length; i++) {
                        const nextTableRow = $(tableRows[i]);
                        if (nextTableRow.hasClass('efa-unread')) {
                            foundNextUnreadId = nextTableRow.data('id');
                            foundNextUnreadTableIndex = i;
                            console.log('NEXT: Found next unread at table row ' + i + ', id=' + foundNextUnreadId);
                            break;
                        }
                    }
                    
                    // Now mark the email as read (optimistic update)
                    if (currentRows[nextIndex]) {
                        currentRows[nextIndex].read_status = '1';
                    }
                    const row = $(`tr[data-id="${nextId}"]`);
                    row.removeClass('efa-unread');
                    
                    // Update master array too
                    const masterIdx = allFetchedRows.findIndex(r => r.id == nextId);
                    if (masterIdx > -1) allFetchedRows[masterIdx].read_status = '1';
                    
                    // Update highlighted unread count if this was a highlighted email
                    if (currentRows[nextIndex] && currentRows[nextIndex].highlight) {
                        updateHighlightedUnreadCount(-1);
                    }
                    
                    // Update unread counter in sidebar (decrement by 1)
                    if (lastDashboardData && lastDashboardData.sidebar_counts && lastDashboardData.sidebar_counts.unread !== undefined) {
                        lastDashboardData.sidebar_counts.unread = Math.max(0, lastDashboardData.sidebar_counts.unread - 1);
                        $('#efa-count-unread').text(lastDashboardData.sidebar_counts.unread);
                    }
                    
                    // Filter out read emails from currentRows (this removes nextId)
                    const beforeFilterLength = currentRows.length;
                    currentRows = currentRows.filter(r => !r.read_status || r.read_status === '0' || r.read_status !== '1');
                    const afterFilterLength = currentRows.length;
                    
                    console.log('NEXT: Filtered currentRows from ' + beforeFilterLength + ' to ' + afterFilterLength);
                    
                    // Use the nextRowData we already have (before filtering) to show nextId
                    currentIndex = -1; // Indicate we're showing a read email (not in currentRows)
                    window.currentRowData = nextRowData; // Use the rowData we already have
                    console.log('NEXT: Showing nextId=' + nextId + ' (using stored rowData)');
                    
                    // Store the next unread index for the next navigation
                    if (foundNextUnreadId) {
                        const foundNextUnreadIndex = currentRows.findIndex(cr => cr.id == foundNextUnreadId);
                        if (foundNextUnreadIndex >= 0) {
                            window.nextUnreadIndex = foundNextUnreadIndex;
                            console.log('NEXT: Stored nextUnreadIndex=' + foundNextUnreadIndex + ' (id=' + foundNextUnreadId + ')');
                        } else {
                            // The next unread email is not in currentRows (maybe filtered by date range)
                            // Use the first item in currentRows as fallback
                            window.nextUnreadIndex = currentRows.length > 0 ? 0 : -1;
                            console.log('NEXT: nextUnreadId not in currentRows, using fallback nextUnreadIndex=' + window.nextUnreadIndex);
                        }
                    } else {
                        // No more unread emails
                        window.nextUnreadIndex = -1;
                        console.log('NEXT: No more unread emails');
                    }
                    
                    // Send AJAX to mark as read in backend
                    $.ajax({
                        url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
                        data: { action: 'efa_mark_as_read', nonce: efa_vars.nonce, id: nextId }
                    });
                } else {
                    // Not marking as read, just move to next
                    currentIndex = nextIndex;
                    window.currentRowData = nextRowData;
                }
                
                updateNavState();
                dom.panelContent.html('<div style="text-align:center;padding:40px;">Cargando datos...</div>');
                const finalRowData = window.currentRowData;
                if (finalRowData) {
                    $.ajax({
                        url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
                        data: { action: 'efa_get_submission_details', nonce: efa_vars.nonce, id: finalRowData.id },
                        success: function (res) {
                            if (res.success) {
                                renderDetails(res.data, finalRowData);
                                updateNavState(); // Update again after loading
                            } else {
                                dom.panelContent.html('Error.');
                            }
                        }
                    });
                }
            }
        }
    });

    function openModal(index, autoOpenCrm = false, tableRowIndex = null) {
        if (index < 0 || index >= currentRows.length) return;
        currentIndex = index;
        const rowData = currentRows[index];
        
        // Check if rowData exists and is valid
        if (!rowData) return;
        
        window.currentRowData = rowData; // Store current row data globally
        
        // Mark as read if not already read (only when first opening, not when navigating)
        // We check if the panel is already open to avoid double-marking
        const isPanelAlreadyOpen = dom.slidePanel.hasClass('open');
        if (!isPanelAlreadyOpen && rowData.read_status != '1') {
            // IMPORTANT: Find the next unread email BEFORE marking as read and removing the class
            // This way we can find it in the table using the efa-unread class
            let nextUnreadId = null;
            let nextUnreadIndex = -1;
            
            if (window.currentUnreadFilter && tableRowIndex !== null && tableRowIndex >= 0) {
                // Look for the next unread email in the visible table rows
                // Do this BEFORE we remove the efa-unread class
                const tableRows = $('.efa-table tbody tr');
                console.log('openModal: Searching for next unread starting from table row ' + (tableRowIndex + 1) + ' of ' + tableRows.length);
                
                for (let i = tableRowIndex + 1; i < tableRows.length; i++) {
                    const nextRow = $(tableRows[i]);
                    // Check if this row has the efa-unread class (meaning it's unread)
                    if (nextRow.hasClass('efa-unread')) {
                        nextUnreadId = nextRow.data('id');
                        // Find its index in the ORIGINAL currentRows (before filtering)
                        nextUnreadIndex = currentRows.findIndex(cr => cr.id == nextUnreadId);
                        console.log('openModal: Found next unread at table row ' + i + ', id=' + nextUnreadId + ', index in original currentRows=' + nextUnreadIndex);
                        break;
                    }
                }
            }
            
            // Now mark as read - this will update the status but we'll handle filtering separately
            // We don't want markAsRead to filter currentRows here because we want to show the clicked email
            if (currentRows[index]) {
                currentRows[index].read_status = '1';
            }
            const row = $(`tr[data-id="${rowData.id}"]`);
            row.removeClass('efa-unread');
            
            // Update master array too
            const masterIdx = allFetchedRows.findIndex(r => r.id == rowData.id);
            if (masterIdx > -1) allFetchedRows[masterIdx].read_status = '1';
            
            // Update highlighted unread count if this was a highlighted email
            if (currentRows[index] && currentRows[index].highlight) {
                updateHighlightedUnreadCount(-1);
            }
            
            // Update unread counter in sidebar (decrement by 1)
            if (lastDashboardData && lastDashboardData.sidebar_counts && lastDashboardData.sidebar_counts.unread !== undefined) {
                lastDashboardData.sidebar_counts.unread = Math.max(0, lastDashboardData.sidebar_counts.unread - 1);
                $('#efa-count-unread').text(lastDashboardData.sidebar_counts.unread);
            }
            
            // Send AJAX to mark as read in backend
            $.ajax({
                url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
                data: { action: 'efa_mark_as_read', nonce: efa_vars.nonce, id: rowData.id }
            });
            
            // In unread filter, filter currentRows AFTER we've stored the rowData
            // The clicked email is now marked as read, so it will be filtered out
            // But we want to show it, so we'll keep it in window.currentRowData
            if (window.currentUnreadFilter) {
                // Store the original rowData and index before filtering
                const clickedId = rowData.id;
                
                // Filter out read emails - this removes the clicked email from currentRows
                currentRows = currentRows.filter(r => !r.read_status || r.read_status === '0' || r.read_status !== '1');
                
                // Find the index of the next unread email in the FILTERED currentRows
                // We already found nextUnreadId and nextUnreadIndex before marking as read
                let finalNextUnreadIndex = -1;
                if (nextUnreadId) {
                    finalNextUnreadIndex = currentRows.findIndex(cr => cr.id == nextUnreadId);
                    console.log('openModal: nextUnreadId=' + nextUnreadId + ', finalNextUnreadIndex in filtered currentRows=' + finalNextUnreadIndex);
                }
                
                // If we didn't find it using table row index, fall back to currentRows[0]
                if (finalNextUnreadIndex < 0 && currentRows.length > 0) {
                    finalNextUnreadIndex = 0;
                    console.log('openModal: Using fallback finalNextUnreadIndex=0');
                }
                
                // Set currentIndex to -1 to indicate we're showing a read email (not in currentRows)
                // But store the next unread index for navigation
                currentIndex = -1;
                window.nextUnreadIndex = finalNextUnreadIndex; // Store for next button
                console.log('openModal: clickedId=' + clickedId + ', tableRowIndex=' + tableRowIndex + ', nextUnreadId=' + nextUnreadId + ', finalNextUnreadIndex=' + finalNextUnreadIndex);
                
                // Keep the original rowData to show the clicked email
                window.currentRowData = rowData;
            }
        }
        
        // Update nav state before opening (so counter is correct)
        updateNavState();
        updatePanelOrigin();
        
        dom.modalOverlay.addClass('open'); dom.slidePanel.addClass('open');

        // Close CRM and Reply panels initially to avoid weird transitions, unless we want it open immediately (but we need data first)
        $('#efa-crm-panel').removeClass('open');
        $('#efa-reply-panel').removeClass('open');

        dom.panelContent.html('<div style="text-align:center;padding:40px;">Cargando datos...</div>');
        dom.btnWa.attr('href', '#');
        dom.btnReply.prop('disabled', true).css('opacity', '0.5');

        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_get_submission_details', nonce: efa_vars.nonce, id: rowData.id },
            success: function (res) {
                if (res.success) {
                    renderDetails(res.data, rowData);
                    if (autoOpenCrm) {
                        $('#efa-crm-panel').addClass('open');
                    }
                } else {
                    dom.panelContent.html('Error.');
                }
            }
        });
    }

    function updateNavState() {
        // If we're in "Sin leer" filter, use the sidebar count (total unread) instead of currentRows.length
        // This is because currentRows only contains unread emails within the selected date range,
        // but the sidebar count shows ALL unread emails in the database
        let totalCount = currentRows.length;
        let displayIndex = currentIndex;
        
        if (window.currentUnreadFilter && lastDashboardData && lastDashboardData.sidebar_counts) {
            // Use the sidebar unread count which includes ALL unread emails (not just in date range)
            totalCount = lastDashboardData.sidebar_counts.unread || currentRows.length;
            
            // If currentIndex is -1, we're showing a read email, so display as "1" (first position)
            if (currentIndex === -1) {
                displayIndex = 0;
            }
        }
        
        dom.navCounter.text((displayIndex + 1) + ' / ' + totalCount);
        dom.prevBtn.prop('disabled', currentIndex <= 0 && currentIndex !== -1);
        dom.nextBtn.prop('disabled', currentIndex >= currentRows.length - 1 && currentIndex !== -1);
        
        // Actualizar origen en el header
        updatePanelOrigin();
    }
    
    function updatePanelOrigin() {
        const originEl = $('#efa-panel-origin');
        if (!window.currentRowData || !window.currentRowData.origin) {
            originEl.hide();
            return;
        }
        
        const origin = window.currentRowData.origin;
        const color = getColorForString(origin);
        originEl.html(`<span style="color:${color};font-weight:bold;font-size:14px;">●</span> <span style="font-size:13px;color:var(--efa-text-main);">${origin}</span>`).show();
    }

    function closeModal() { dom.modalOverlay.removeClass('open'); dom.slidePanel.removeClass('open'); }

    function renderDetails(data, rowData) {
        let cleanPhone = (rowData.phone || '').replace(/[^0-9]/g, '');
        if (cleanPhone) { dom.btnWa.attr('href', 'https://wa.me/' + cleanPhone); }
        else { dom.btnWa.attr('href', '#'); }
        
        // Setup reply button handler
        if (rowData.email) {
            dom.btnReply.prop('disabled', false).css('opacity', '1').off('click').on('click', function(e) {
                e.preventDefault();
                openReplyPanel(rowData, data);
            });
        } else {
            dom.btnReply.prop('disabled', true).css('opacity', '0.5').off('click');
        }

        // Format date nicely
        const formattedDate = formatDateNicely(data.meta.created_at);

        let html = '';

        // SECTION 1: DATE BLOCK (New Location)
        let acceptanceHtml = '';
        if (rowData.is_commercial) {
            acceptanceHtml = `<span class="efa-badge safe" style="font-size:10px; padding: 2px 8px;">✔ Aceptación Recibida</span>`;
        }

        html += `<div class="efa-panel-date-block">
            <div class="efa-pdb-left">
                <span class="dashicons dashicons-calendar-alt"></span>
                <span>${formattedDate}</span>
            </div>
            <div class="efa-pdb-right">
                ${acceptanceHtml}
            </div>
        </div>`;

        // CRM Section removed from here. Moved to secondary panel.

        // Prepare data for accordion sections
        let name = '', email = '', phone = '', message = '';
        let otherFields = [];
        let hasPathInfo = false;
        let pathHtml = '';

        if (data.values) {
            data.values.forEach(f => {
                if (f.key === 'efa_spam_override') return;
                if (['landing_url', 'prev_url', 'current_url', 'origen'].includes(f.key)) return;

                let k = f.key.toLowerCase();
                // Exclude fields that are already displayed or irrelevant
                if (k.includes('aceptacion') || k.includes('acceptance') || k.includes('comercial') || k.includes('commercial') || k.includes('efa_crm_') || k.includes('efa_read_status') || k.includes('efa_replied_')) return;

                if (k.includes('name') || k.includes('nombre')) name = f.value;
                else if (k.includes('email') || k.includes('correo')) email = f.value;
                else if (k.includes('tel') || k.includes('phone') || k.includes('movil')) phone = f.value;
                else if (k.includes('message') || k.includes('mensaje')) message = f.value;
                else otherFields.push({ key: f.key.replace(/_/g, ' '), value: f.value });
            });
        }
        if (!name && rowData.name) name = rowData.name;
        if (!email && rowData.email) email = rowData.email;

        // Check if path info exists
        if (data.path_info) {
            if (data.path_info.landing) {
                pathHtml += `<div class="efa-path-step" title="Landing de entrada">${data.path_info.landing}</div>`;
                hasPathInfo = true;
            }
            if (data.path_info.prev && data.path_info.prev !== data.path_info.landing) {
                pathHtml += `<span class="dashicons dashicons-arrow-right-alt2 efa-path-arrow"></span>`;
                pathHtml += `<div class="efa-path-step" title="Anterior">${data.path_info.prev}</div>`;
                hasPathInfo = true;
            }
            if (data.path_info.lead && data.path_info.lead !== data.path_info.prev) {
                pathHtml += `<span class="dashicons dashicons-arrow-right-alt2 efa-path-arrow"></span>`;
                pathHtml += `<div class="efa-path-step" title="Lead Convertido"><strong>${data.path_info.lead}</strong></div>`;
                hasPathInfo = true;
            }
        }

        // ACCORDION SECTION 1: INFORMACIÓN DEL LEAD (Always visible, open by default)
        html += `
            <div class="efa-accordion-section active">
                <div class="efa-accordion-header" data-accordion="lead-info">
                    <div class="efa-accordion-title">
                        <span class="dashicons dashicons-id"></span>
                        <span>Información del Lead</span>
                    </div>
                    <span class="efa-accordion-icon dashicons dashicons-arrow-up-alt2"></span>
                </div>
                <div class="efa-accordion-content" style="display: block;">
                    <div class="efa-lead-info-compact">
                        <div class="efa-lead-item">
                            <span class="efa-lead-label">Nombre:</span>
                            <span class="efa-lead-value highlight">${name || '-'}</span>
                        </div>
                        <div class="efa-lead-item">
                            <span class="efa-lead-label">Email:</span>
                            <span class="efa-lead-value">${email ? `<a href="mailto:${email}">${email}</a>` : '-'}</span>
                        </div>
                        <div class="efa-lead-item">
                            <span class="efa-lead-label">Teléfono:</span>
                            <span class="efa-lead-value">${phone ? `<a href="tel:${phone}">${phone}</a>` : '-'}</span>
                        </div>
        `;
        
        if (message) {
            // Highlight keywords in message if row is highlighted
            const highlightedMessage = (rowData.highlight && typeof efa_vars.highlight_keywords !== 'undefined')
                ? highlightKeywords(message, efa_vars.highlight_keywords)
                : message;
            html += `
                        <div class="efa-lead-item efa-lead-message">
                            <span class="efa-lead-label">Mensaje:</span>
                            <div class="efa-lead-message-text">${highlightedMessage}</div>
                        </div>
            `;
        }
        
        html += `
                    </div>
                </div>
            </div>
        `;

        // ACCORDION SECTION 2: RESPUESTA (Show all replies)
        const replies = data.replies && Array.isArray(data.replies) && data.replies.length > 0 ? data.replies : (data.reply && data.reply.message ? [data.reply] : []);
        if (replies.length > 0) {
            const repliesCount = replies.length;
            html += `
                <div class="efa-accordion-section">
                    <div class="efa-accordion-header" data-accordion="reply-info">
                        <div class="efa-accordion-title">
                            <span class="dashicons dashicons-email-alt"></span>
                            <span>Respuesta</span>
                            <span class="efa-replies-badge">${repliesCount}</span>
                        </div>
                        <span class="efa-accordion-icon dashicons dashicons-arrow-down-alt2"></span>
                    </div>
                    <div class="efa-accordion-content">
                        <div class="efa-replies-container">
            `;
            
            // Mostrar todas las respuestas (la más reciente primero)
            const sortedReplies = [...replies].reverse(); // Invertir para mostrar la más reciente primero
            sortedReplies.forEach((reply, index) => {
                const replyDate = reply.date ? formatDateNicely(reply.date) : '';
                const replySubject = reply.subject || '';
                const replyMessage = reply.message || '';
                const isLast = index === sortedReplies.length - 1;
                const replyNumber = sortedReplies.length - index; // Número de respuesta (1 = más reciente)
                
                html += `
                    <div class="efa-reply-item ${isLast ? 'efa-reply-item-last' : ''}">
                        <div class="efa-reply-item-header">
                            <span class="efa-reply-item-number">Respuesta #${replyNumber}</span>
                            ${replyDate ? `<span class="efa-reply-item-date">${replyDate}</span>` : ''}
                        </div>
                        <div class="efa-lead-info-compact">
                            ${replySubject ? `
                                <div class="efa-lead-item">
                                    <span class="efa-lead-label">Asunto:</span>
                                    <span class="efa-lead-value">${replySubject}</span>
                                </div>
                            ` : ''}
                            <div class="efa-lead-item efa-lead-message">
                                <span class="efa-lead-label">Mensaje:</span>
                                <div class="efa-reply-message-text">${replyMessage}</div>
                            </div>
                        </div>
                    </div>
                `;
            });
            
            html += `
                        </div>
                    </div>
                </div>
            `;
        }

        // ACCORDION SECTION 3: RUTA DE CONVERSIÓN (Only if has path info)
        if (hasPathInfo && pathHtml) {
            html += `
                <div class="efa-accordion-section">
                    <div class="efa-accordion-header" data-accordion="path-info">
                        <div class="efa-accordion-title">
                            <span class="dashicons dashicons-location"></span>
                            <span>Ruta de Conversión</span>
                        </div>
                        <span class="efa-accordion-icon dashicons dashicons-arrow-down-alt2"></span>
                    </div>
                    <div class="efa-accordion-content">
                        <div class="efa-user-path">${pathHtml}</div>
                    </div>
                </div>
            `;
        }

        // ACCORDION SECTION 4: OTROS DETALLES (Only if has other fields)
        if (otherFields.length > 0) {
            html += `
                <div class="efa-accordion-section">
                    <div class="efa-accordion-header" data-accordion="other-details">
                        <div class="efa-accordion-title">
                            <span class="dashicons dashicons-list-view"></span>
                            <span>Otros Detalles</span>
                        </div>
                        <span class="efa-accordion-icon dashicons dashicons-arrow-down-alt2"></span>
                    </div>
                    <div class="efa-accordion-content">
                        <div class="efa-data-grid single-col">
                            <div class="efa-field-group"><span class="efa-fg-label">Formulario ID</span><span class="efa-fg-value">${data.meta.form_name} (#${data.meta.id})</span></div>
            `;
            otherFields.forEach(field => {
                html += `<div class="efa-field-group"><span class="efa-fg-label">${field.key}</span><span class="efa-fg-value">${field.value}</span></div>`;
            });
            html += `
                        </div>
                    </div>
                </div>
            `;
        }

        dom.panelContent.html(html);

        // Setup accordion functionality
        setupAccordion();

        // Render CRM Panel (Hidden by default)
        renderCrmPanel(data, rowData);

        // Manage Button Handler
        $('#efa-panel-manage-btn').off('click').on('click', function () {
            $('#efa-crm-panel').toggleClass('open');
        });
    }

    // Accordion functionality
    function setupAccordion() {
        $('.efa-accordion-header').off('click').on('click', function() {
            const section = $(this).closest('.efa-accordion-section');
            const content = section.find('.efa-accordion-content');
            const icon = $(this).find('.efa-accordion-icon');
            
            // Toggle this section
            if (section.hasClass('active')) {
                section.removeClass('active');
                content.slideUp(300);
                icon.removeClass('dashicons-arrow-up-alt2').addClass('dashicons-arrow-down-alt2');
            } else {
                section.addClass('active');
                content.slideDown(300);
                icon.removeClass('dashicons-arrow-down-alt2').addClass('dashicons-arrow-up-alt2');
            }
        });

        // Botones de spam y delete removidos del panel principal
        // Los eventos se mantienen comentados por si se necesitan en el futuro
        /*
        // Configurar botones de cabecera
        let isSpam = (rowData.risk === 2);
        updatePanelSpamButton(isSpam);

        // Eventos de botones de cabecera
        dom.panelSpamBtn.off('click').on('click', function () {
            // Read current state from rowData (not closure variable)
            const currentIsSpam = (rowData.risk === 2);
            const newStatus = currentIsSpam ? 'safe' : 'spam';
            const btn = $(this);

            toggleSpamStatus(rowData.id, newStatus, function (success) {
                if (success) {
                    // Update rowData
                    rowData.risk = (newStatus === 'spam' ? 2 : 0);

                    // Check filters for removal
                    const showSafe = $('#efa-toggle-safe').is(':checked');
                    const showSpam = $('#efa-toggle-spam').is(':checked');
                    let shouldRemove = false;
                    if (showSpam && !showSafe && newStatus === 'safe') shouldRemove = true;
                    if (showSafe && !showSpam && newStatus === 'spam') shouldRemove = true;

                    if (shouldRemove) {
                        closeSlidePanel();
                        // Remove from DOM and arrays
                        $(`tr[data-id="${rowData.id}"]`).fadeOut(300, function () { $(this).remove(); });
                        allFetchedRows = allFetchedRows.filter(r => r.id != rowData.id);
                        currentRows = currentRows.filter(r => r.id != rowData.id);
                        renderNextBatch();
                    } else {
                        // Update master array
                        const masterIdx = allFetchedRows.findIndex(r => r.id == rowData.id);
                        if (masterIdx > -1) allFetchedRows[masterIdx].risk = rowData.risk;

                        currentRows[currentIndex] = rowData;

                        // Update button appearance
                        updatePanelSpamButton(rowData.risk === 2);

                        // Update table row
                        refreshTableRow(rowData.id, rowData.risk);
                    }
                }
            });
        });

            deleteSubmission(rowData.id, function (success) {
                if (success) {
                    // Forzar recarga de página para asegurar que se reflejan los cambios
                    window.location.reload();
                }
            });
        });
        */

    }


    function refreshTableRow(id, risk) {
        if (!dom.tableBody.length) return;
        const row = $(`tr[data-id="${id}"]`);
        const badge = row.find('.efa-badge');

        // Update classes and HTML for Text style
        if (risk === 2) {
            badge.removeClass('safe').addClass('spam').html('<span class="dashicons dashicons-warning"></span> Spam');
        } else {
            badge.removeClass('spam').addClass('safe').html('<span class="dashicons dashicons-shield"></span> Correcto');
        }
        // Remove inline styles to let CSS handle it
        badge.removeAttr('style');
    }

    function toggleSpamStatus(id, status, callback) {
        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_toggle_spam_status', nonce: efa_vars.nonce, id: id, status: status },
            success: function (res) { callback && callback(res.success); }
        });
    }

    function updatePanelSpamButton(isSpam) {
        const btn = dom.panelSpamBtn;
        // Panel button keeps text for clarity, but uses updated icons if needed.
        // User complained about "previous buttons" appearing. If they meant the table, refreshTableRow handles it.
        // If they meant the panel, let's keep it consistent with current design.
        if (isSpam) {
            btn.html('<span class="dashicons dashicons-warning"></span> Spam')
                .removeClass('spam-active').addClass('spam-inactive');
        } else {
            btn.html('<span class="dashicons dashicons-shield"></span> Correcto')
                .removeClass('spam-inactive').addClass('spam-active');
        }
    }

    // Exponer funciones globales para acciones desde la tabla (si se usan onclick inline)
    window.gwToggleSpam = function (id, makeSpam) { toggleSpamStatus(id, makeSpam); };
    window.gwDeleteSub = function (id) { deleteSubmission(id); };

    function deleteSubmission(id, callback) {
        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_delete_submission', nonce: efa_vars.nonce, id: id },
            success: function (res) { callback && callback(res.success); }
        });
    }


    $(document).on('click', '.efa-badge', function (e) {
        e.stopPropagation();
        const badge = $(this);
        const row = badge.closest('tr');
        const id = row.data('id');
        const isSpam = badge.hasClass('spam');
        const newStatus = isSpam ? 'safe' : 'spam';

        // If changing from SAFE to SPAM, show SweetAlert2 dialog
        if (newStatus === 'spam' && typeof Swal !== 'undefined') {
            // Get email from row data
            const rowData = currentRows.find(r => r.id == id);
            if (!rowData || !rowData.email) {
                // Fallback to simple toggle if email not found
                performSpamToggle(badge, row, id, newStatus);
                return;
            }

            const email = rowData.email;

            Swal.fire({
                title: 'Gestión de Spam',
                html: `
                    <p style="margin-bottom: 20px; color: #666;">¿Qué acción deseas aplicar a <strong>${email}</strong>?</p>
                    <div class="efa-spam-actions">
                        <div class="efa-spam-action-item" id="spam-only-btn">
                            <div class="efa-sa-icon" style="background: #f59e0b;"><span class="dashicons dashicons-warning"></span></div>
                            <div class="efa-sa-content">
                                <strong>Solo marcar como Spam</strong>
                                <p>Marca este correo específico como spam. Futuros correos seguirán entrando.</p>
                            </div>
                        </div>

                        <div class="efa-spam-action-item" id="spam-blacklist-btn">
                            <div class="efa-sa-icon" style="background: #dc2626;"><span class="dashicons dashicons-shield"></span></div>
                            <div class="efa-sa-content">
                                <strong>Spam + Bloquear Remitente</strong>
                                <p>Marca como spam y añade el email a la lista negra. No recibirás más correos de esta dirección.</p>
                            </div>
                        </div>

                        <div class="efa-spam-action-item" id="delete-all-btn">
                            <div class="efa-sa-icon" style="background: #7f1d1d;"><span class="dashicons dashicons-trash"></span></div>
                            <div class="efa-sa-content">
                                <strong>Eliminar Todo del Remitente</strong>
                                <p>Borra este correo, TODOS los anteriores y añade el email a la lista negra. Acción irreversible.</p>
                            </div>
                        </div>
                        
                        <div class="efa-spam-action-item cancel" id="cancel-btn">
                            <div class="efa-sa-content" style="text-align: center; width: 100%;">
                                <strong>Cancelar</strong>
                            </div>
                        </div>
                    </div>
                `,
                showConfirmButton: false,
                showCancelButton: false,
                width: '500px',
                padding: '2em',
                didOpen: () => {
                    // Add click handlers to custom buttons
                    document.getElementById('spam-only-btn').addEventListener('click', () => {
                        Swal.close();
                        // Just mark as spam, no blacklist
                        performSpamToggle(badge, row, id, newStatus);
                        Swal.fire({
                            title: 'Marcado como spam',
                            text: 'El correo ha sido marcado como spam',
                            icon: 'success',
                            timer: 1500,
                            showConfirmButton: false
                        });
                    });

                    document.getElementById('spam-blacklist-btn').addEventListener('click', () => {
                        Swal.close();
                        // Mark as spam + blacklist
                        blacklistEmail(email, function (success) {
                            if (success) {
                                // Mark current email as spam
                                performSpamToggle(badge, row, id, newStatus);

                                // Find and mark all other emails from this sender as spam
                                let affectedCount = 0;
                                const emailLower = email.toLowerCase().trim();

                                console.log('Looking for emails matching:', emailLower, 'excluding ID:', id);

                                // Update all rows in data arrays
                                allFetchedRows.forEach(r => {
                                    if (r.email) {
                                        const rEmailLower = r.email.toLowerCase().trim();
                                        const rId = String(r.id);
                                        const currentId = String(id);

                                        console.log('Checking:', rEmailLower, 'ID:', rId, 'Match:', rEmailLower === emailLower, 'Different ID:', rId !== currentId);

                                        if (rEmailLower === emailLower && rId !== currentId) {
                                            r.risk = 2;
                                            affectedCount++;
                                            // Update visual if visible in table
                                            refreshTableRow(r.id, 2);
                                            console.log('Marked as spam:', r.id);
                                        }
                                    }
                                });

                                currentRows.forEach(r => {
                                    if (r.email) {
                                        const rEmailLower = r.email.toLowerCase().trim();
                                        if (rEmailLower === emailLower && String(r.id) !== String(id)) {
                                            r.risk = 2;
                                        }
                                    }
                                });

                                console.log('Total affected:', affectedCount);

                                Swal.fire({
                                    title: 'Spam + Lista negra',
                                    text: `${email} añadido a la lista negra${affectedCount > 0 ? ` y ${affectedCount + 1} correo(s) marcados como spam` : ''}`,
                                    icon: 'success',
                                    timer: 2000,
                                    showConfirmButton: false
                                });
                            } else {
                                Swal.fire('Error', 'No se pudo actualizar la lista negra', 'error');
                            }
                        });
                    });

                    document.getElementById('delete-all-btn').addEventListener('click', () => {
                        Swal.close();
                        // Delete all emails from this sender + blacklist
                        deleteAllFromSender(email, function (success, count) {
                            if (success) {
                                Swal.fire({
                                    title: '¡Completado!',
                                    text: `${count} correo(s) eliminado(s) y remitente añadido a la lista negra`,
                                    icon: 'success',
                                    timer: 2000,
                                    showConfirmButton: false
                                });
                                // Reload data to reflect changes
                                setTimeout(() => {
                                    location.reload();
                                }, 2000);
                            } else {
                                Swal.fire('Error', 'No se pudieron eliminar los correos', 'error');
                            }
                        });
                    });

                    document.getElementById('cancel-btn').addEventListener('click', () => {
                        Swal.close();
                    });
                }
            });
        } else {
            // SPAM → SAFE: Show dialog with all options
            const rowData = currentRows.find(r => r.id == id);
            if (!rowData || !rowData.email) {
                // Fallback to simple toggle if email not found
                performSpamToggle(badge, row, id, newStatus);
                return;
            }

            const email = rowData.email;

            Swal.fire({
                title: 'Gestión de Spam',
                html: `
                    <p style="margin-bottom: 20px; color: #666;">¿Qué acción deseas aplicar a <strong>${email}</strong>?</p>
                    <div class="efa-spam-actions">
                        <div class="efa-spam-action-item" id="unspam-only-btn">
                            <div class="efa-sa-icon" style="background: #10b981;"><span class="dashicons dashicons-yes"></span></div>
                            <div class="efa-sa-content">
                                <strong>Marcar como No Spam</strong>
                                <p>Marca este correo como seguro.</p>
                            </div>
                        </div>

                        <div class="efa-spam-action-item" id="unspam-blacklist-btn">
                            <div class="efa-sa-icon" style="background: #dc2626;"><span class="dashicons dashicons-shield"></span></div>
                            <div class="efa-sa-content">
                                <strong>Spam + Bloquear Remitente</strong>
                                <p>Mantiene como spam y añade el email a la lista negra. No recibirás más correos de esta dirección.</p>
                            </div>
                        </div>

                        <div class="efa-spam-action-item" id="unspam-delete-all-btn">
                            <div class="efa-sa-icon" style="background: #7f1d1d;"><span class="dashicons dashicons-trash"></span></div>
                            <div class="efa-sa-content">
                                <strong>Eliminar Todo del Remitente</strong>
                                <p>Borra este correo, TODOS los anteriores y añade el email a la lista negra. Acción irreversible.</p>
                            </div>
                        </div>
                        
                        <div class="efa-spam-action-item cancel" id="cancel-unspam-btn">
                            <div class="efa-sa-content" style="text-align: center; width: 100%;">
                                <strong>Cancelar</strong>
                            </div>
                        </div>
                    </div>
                `,
                showConfirmButton: false,
                showCancelButton: false,
                width: '500px',
                padding: '2em',
                didOpen: () => {
                    // Mark as Not Spam
                    document.getElementById('unspam-only-btn').addEventListener('click', () => {
                        Swal.close();
                        performSpamToggle(badge, row, id, newStatus);
                        Swal.fire({
                            title: 'Marcado como seguro',
                            text: 'El correo ha sido marcado como no spam',
                            icon: 'success',
                            timer: 1500,
                            showConfirmButton: false
                        });
                    });

                    // Keep as spam + blacklist
                    document.getElementById('unspam-blacklist-btn').addEventListener('click', () => {
                        Swal.close();
                        blacklistEmail(email, function (success) {
                            if (success) {
                                // Find and mark all other emails from this sender as spam
                                let affectedCount = 0;
                                currentRows.forEach((r, ridx) => {
                                    if (r.email === email && r.risk !== 2) {
                                        performSpamToggle($(`tr[data-id="${r.id}"] .efa-badge`), $(`tr[data-id="${r.id}"]`), r.id, 'spam');
                                        affectedCount++;
                                    }
                                });

                                Swal.fire({
                                    title: 'Remitente bloqueado',
                                    text: `${email} añadido a la lista negra. ${affectedCount > 0 ? affectedCount + ' correos adicionales marcados como spam.' : ''}`,
                                    icon: 'success',
                                    timer: 2500,
                                    showConfirmButton: false
                                });
                            } else {
                                Swal.fire('Error', 'No se pudo bloquear el remitente', 'error');
                            }
                        });
                    });

                    // Delete all from sender
                    document.getElementById('unspam-delete-all-btn').addEventListener('click', () => {
                        Swal.close();
                        deleteAllFromSender(email, function (success) {
                            if (success) {
                                Swal.fire({
                                    title: 'Emails eliminados',
                                    text: `Todos los correos de ${email} han sido eliminados y el remitente bloqueado`,
                                    icon: 'success',
                                    timer: 2000,
                                    showConfirmButton: false
                                });

                                // Reload data to reflect changes
                                setTimeout(() => {
                                    location.reload();
                                }, 2000);
                            } else {
                                Swal.fire('Error', 'No se pudieron eliminar los correos', 'error');
                            }
                        });
                    });

                    document.getElementById('cancel-unspam-btn').addEventListener('click', () => {
                        Swal.close();
                    });
                }
            });
        }
    });

    // Helper function to perform the actual toggle
    function performSpamToggle(badge, row, id, newStatus) {
        badge.css('opacity', '0.5');

        toggleSpamStatus(id, newStatus, function (success) {
            badge.css('opacity', '1');
            if (success) {
                const showSafe = $('#efa-toggle-safe').is(':checked');
                const showSpam = $('#efa-toggle-spam').is(':checked');
                const newRisk = (newStatus === 'spam') ? 2 : 0;

                let shouldRemove = false;
                if (showSpam && !showSafe && newStatus === 'safe') shouldRemove = true;
                if (showSafe && !showSpam && newStatus === 'spam') shouldRemove = true;

                if (shouldRemove) {
                    row.fadeOut(300, function () { $(this).remove(); });
                    const masterIdx = allFetchedRows.findIndex(r => r.id == id);
                    if (masterIdx > -1) allFetchedRows.splice(masterIdx, 1);
                    const idx = currentRows.findIndex(r => r.id == id);
                    if (idx > -1) currentRows.splice(idx, 1);
                } else {
                    refreshTableRow(id, newRisk);
                    const masterIdx = allFetchedRows.findIndex(r => r.id == id);
                    if (masterIdx > -1) allFetchedRows[masterIdx].risk = newRisk;
                }
            }
        });
    }

    // AJAX helper: Blacklist an email
    function blacklistEmail(email, callback) {
        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_blacklist_email', nonce: efa_vars.nonce, email: email },
            success: function (res) { callback && callback(res.success); },
            error: function () { callback && callback(false); }
        });
    }

    // AJAX helper: Delete all from sender
    function deleteAllFromSender(email, callback) {
        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_delete_all_from_sender', nonce: efa_vars.nonce, email: email },
            success: function (res) {
                callback && callback(res.success, res.data ? res.data.count : 0);
            },
            error: function () { callback && callback(false, 0); }
        });
    }


    // ... (skip unchanged lines) ...

    function refreshTableRow(id, risk) {
        if (!dom.tableBody.length) return;
        const row = $(`tr[data-id="${id}"]`);
        const badge = row.find('.efa-badge');

        // Update classes and HTML for icon-only style
        if (risk === 2) {
            badge.removeClass('safe').addClass('spam');
            badge.html('<span class="dashicons dashicons-warning"></span>');
        } else {
            badge.removeClass('spam').addClass('safe');
            badge.html('<span class="dashicons dashicons-shield"></span>');
        }
    }

    $(document).on('click', '.efa-delete-btn', function (e) {
        e.stopPropagation();
        if (!confirm('¿Estás seguro?')) return;
        const row = $(this).closest('tr'); const id = row.data('id');
        deleteSubmission(id, function (success) {
            if (success) {
                row.fadeOut(300, function () { $(this).remove(); });

                const masterIdx = allFetchedRows.findIndex(r => r.id == id);
                if (masterIdx > -1) allFetchedRows.splice(masterIdx, 1);

                const idx = currentRows.findIndex(r => r.id == id);
                if (idx > -1) currentRows.splice(idx, 1);

                // Refresh data to update sidebar counts
                fetchData();
            }
        });
    });

    // --- BORRAR TODO EL SPAM ---
    dom.btnDeleteAll.on('click', function (e) {
        e.preventDefault();
        if (!confirm('Revisa bien los correos antes de borrar el spam, esto no es reversible. Te aconsejamos que revises primero los correos de spam antes de borrarlos todos.')) return;

        const btn = $(this); btn.prop('disabled', true).text('Borrando...');
        let activeOrigins = []; $('.efa-toggle-btn.active').each(function () { activeOrigins.push($(this).data('origin')); });
        let range = dom.dateRange.val(); let start = dom.startDate.val(), end = dom.endDate.val();

        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_delete_bulk_spam', nonce: efa_vars.nonce, form_name: dom.formFilter.val(), origins: activeOrigins, is_filtering: 1, range_type: range, start_date: start, end_date: end },
            success: function (res) { if (res.success) { alert('Eliminados: ' + res.data.deleted); fetchData(); } },
            complete: function () { btn.prop('disabled', false).text('🗑️ Borrar Spam'); }
        });
    });

    function fetchData(statusOverride, riskOverride, highlightOverride, repliedOverride, unreadOverride) {
        window.currentHighlightFilter = highlightOverride;
        window.currentRepliedFilter = repliedOverride || false;
        window.currentUnreadFilter = unreadOverride || false;
        dom.btnApply.prop('disabled', true).text('...');
        dom.loadingOverlay.css('display', 'flex'); // Show loading
        $('.efa-chart-container').css('opacity', '0.5');

        let activeOrigins = [];

        // 1. DETECCIÓN AUTOMÁTICA DE MODO (Correos vs Dashboard)
        const isMultiselectMode = $('#efa-origin-dropdown').length > 0;
        let activeForms = [];

        if (isMultiselectMode) {
            // Sidebar form filter takes priority
            const sidebarFormVal = $('#efa-current-form-filter').val();
            if (sidebarFormVal) {
                // If sidebar form is selected, use ONLY that form (ignore dropdown)
                activeForms.push(sidebarFormVal);
            } else {
                // Otherwise use dropdown selection
                $('.efa-form-check:checked').each(function () {
                    activeForms.push($(this).val());
                });
            }

            // Origins Dropdown (unchanged)
            $('.efa-origin-check:checked').each(function () {
                activeOrigins.push($(this).val());
            });

        } else {
            // Modo Dashboard: Botones
            const togglesExist = $('.efa-toggle-btn').length > 0;
            if (togglesExist) {
                $('.efa-toggle-btn.active').each(function () { activeOrigins.push($(this).data('origin')); });
            }
            // Dashboard uses select for forms
            const formVal = dom.formFilter.val();
            if (formVal) activeForms.push(formVal);
        }

        // Enviaremos el array 'origins' tal cual. Si está vacío o lleno, el PHP lo maneja.
        // La variable is_filtering ya no es tan crítica aquí si pasamos el array.
        let isFiltering = 0;

        let range = dom.dateRange.val(); let start = dom.startDate.val(), end = dom.endDate.val();

        let status = riskOverride || 'all';

        let showCommercial = $('#efa-toggle-commercial').is(':checked');
        let commercial = showCommercial ? 'accepted' : 'all';

        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: {
                action: 'efa_get_data', nonce: efa_vars.nonce,
                form_name: activeForms, // Now sending array
                origins: activeOrigins,
                is_filtering: isFiltering,
                range_type: range, start_date: start, end_date: end,
                status_filter: statusOverride || $('#efa-current-status-filter').val() || 'active',
                risk_filter: status,
                commercial_filter: commercial,
                replied_filter: repliedOverride ? 'replied' : 'all',
                unread_filter: unreadOverride ? 'unread' : 'all'
            },
            success: function (res) { if (res.success) updateDashboard(res.data); },
            complete: function () {
                dom.btnApply.prop('disabled', false).text('Aplicar');
                dom.loadingOverlay.hide(); // Hide loading
                $('.efa-chart-container').css('opacity', '1');
            }
        });
    }

    function updateDashboard(data) {
        // Store all fetched rows BEFORE filtering
        allFetchedRows = data.table_rows;
        lastDashboardData = data; // Save for report generation
        
        // Now apply filters to currentRows
        currentRows = data.table_rows;
        if (window.currentHighlightFilter) {
            currentRows = currentRows.filter(r => r.highlight);
        }
        if (window.currentRepliedFilter) {
            currentRows = currentRows.filter(r => r.replied_status && r.replied_status !== '');
        }
        if (window.currentUnreadFilter) {
            // Backend already filters by unread, but we apply it again to be safe
            // This ensures consistency even if backend filtering has issues
            currentRows = currentRows.filter(r => {
                // Filter to show only unread emails (read_status is '0', empty, null, or not '1')
                const readStatus = r.read_status;
                return !readStatus || readStatus === '0' || readStatus !== '1';
            });
        }
        if (window.currentCrmStateFilter) {
            currentRows = currentRows.filter(r => r.crm_status === window.currentCrmStateFilter);
        }
        
        // If panel is open and we're in unread filter, update navigation counter
        if (window.currentUnreadFilter && dom.slidePanel.hasClass('open') && currentIndex >= 0 && currentIndex < currentRows.length) {
            updateNavState();
        }

        // Update sidebar counts
        if (data.sidebar_counts) {
            $('#efa-count-all').text(data.sidebar_counts.all || 0);
            $('#efa-count-unread').text(data.sidebar_counts.unread || 0);
            $('#efa-count-starred').text(data.sidebar_counts.starred || 0);
            $('#efa-count-replied').text(data.sidebar_counts.replied || 0);
            $('#efa-count-spam').text(data.sidebar_counts.spam || 0);
            $('#efa-count-trash').text(data.sidebar_counts.trash || 0);

            // Update CRM state counts
            if (data.sidebar_counts.crm_states) {
                for (let stateId in data.sidebar_counts.crm_states) {
                    $(`#efa-count-state-${stateId}`).text(data.sidebar_counts.crm_states[stateId]);
                }
            }

            // Render CRM States
            const crmContainer = $('#efa-crm-states-container');
            crmContainer.empty();

            if (efa_vars.crm_labels && data.sidebar_counts.crm_states) {
                const currentStatus = $('#efa-current-status-filter').val();

                efa_vars.crm_labels.forEach(label => {
                    const count = data.sidebar_counts.crm_states[label.id] || 0;
                    const isActive = currentStatus === label.id;
                    const activeClass = isActive ? 'active' : '';

                    crmContainer.append(`
                        <div class="efa-nav-item ${activeClass}" data-crm-status="${label.id}">
                            <span class="efa-state-dot" style="background-color: ${label.color}"></span>
                            <span class="efa-nav-label">${label.label}</span>
                            <span class="efa-nav-badge">${count}</span>
                        </div>
                    `);
                });

                // Re-attach click handlers for CRM states
                $('.efa-nav-item[data-crm-status]').off('click').on('click', function () {
                    const status = $(this).data('crm-status');

                    // Update UI
                    $('.efa-nav-item').removeClass('active');
                    $(this).addClass('active');

                    // Update filters
                    $('#efa-current-status-filter').val(status);
                    $('#efa-current-form-filter').val(''); // Clear form filter
                    window.currentCrmStateFilter = status; // Set CRM filter to selected status

                    fetchData();
                });
            }

            // Render Forms List
            const formsContainer = $('#efa-forms-list-container');
            formsContainer.empty();

            if (data.sidebar_counts.forms) {
                const currentForm = $('#efa-current-form-filter').val();

                Object.keys(data.sidebar_counts.forms).forEach(formName => {
                    const count = data.sidebar_counts.forms[formName];
                    const isActive = currentForm === formName;
                    const activeClass = isActive ? 'active' : '';

                    formsContainer.append(`
                        <div class="efa-nav-item ${activeClass}" data-form-filter="${formName}">
                            <span class="dashicons dashicons-feedback"></span>
                            <span class="efa-nav-label">${formName}</span>
                            <span class="efa-nav-badge">${count}</span>
                        </div>
                    `);
                });

                // Re-attach click handlers for forms
                $('.efa-nav-item[data-form-filter]').off('click').on('click', function () {
                    const formName = $(this).data('form-filter');

                    // Update UI
                    $('.efa-nav-item').removeClass('active');
                    $(this).addClass('active');

                    // Update filters
                    $('#efa-current-form-filter').val(formName);
                    $('#efa-current-status-filter').val('active'); // Keep active status
                    window.currentCrmStateFilter = null; // Clear CRM filter

                    fetchData();
                });
            }
        }

        if (document.getElementById('kpi-7d-val')) {
            renderKpiCard('kpi-7d', data.kpis.last_7);
            renderKpiCard('kpi-30d', data.kpis.last_30);
            renderKpiCard('kpi-365d', data.kpis.last_365);
        }

        if (document.getElementById('kpi-total-view-val')) {
            $('#kpi-total-view-val').text(data.kpis.total_in_view);
            $('#efa-avg-daily').text(data.kpis.daily_average);
        }

        const monthsContainer = $('#efa-hw-scroll-container');
        if (monthsContainer.length) {
            monthsContainer.empty();
            if (data.kpis.history && data.kpis.history.length > 0) {
                const historyData = data.kpis.history;
                historyData.forEach(item => {
                    const parts = item.label.split(' ');
                    const mes = parts[0].substring(0, 3); const anio = parts[1] || '';
                    monthsContainer.append(`<div class="efa-hw-item"><span class="efa-hw-item-label">${mes}<span class="efa-hw-item-year">${anio}</span></span><span class="efa-hw-item-val">${item.count}</span></div>`);
                });
                renderHistoryChart(historyData);
            } else {
                monthsContainer.html('<span class="efa-no-data" style="font-size:11px;">Sin datos</span>');
                if (charts.history) charts.history.destroy();
            }
        }

        const grid12 = $('#efa-12months-grid');
        if (grid12.length) {
            grid12.empty();
            if (data.kpis.year_grid) {
                data.kpis.year_grid.forEach(m => {
                    let listHtml = ''; const sorted = Object.entries(m.breakdown).sort((a, b) => b[1] - a[1]);
                    sorted.forEach(([org, cnt]) => { const color = getColorForString(org); listHtml += `<div class="efa-mc-row"><span style="color:${color};font-weight:600;">● ${org}</span><span>${cnt}</span></div>`; });
                    if (listHtml === '') listHtml = '<div style="text-align:center;color:#888;">-</div>';
                    grid12.append(`<div class="efa-month-card"><div class="efa-mc-title">${m.label}</div><div class="efa-mc-total">${m.total}</div><div class="efa-mc-breakdown">${listHtml}</div></div>`);
                });
            }
        }

        renderMainChart(data.timeline);
        renderDoughnut('efa-chart-forms', data.forms_distribution);
        renderDoughnut('efa-chart-origins', data.origins_distribution);
        renderDoughnut('efa-chart-status', data.crm_distribution);
        renderDoughnut('efa-chart-read', data.read_distribution);
        renderDoughnut('efa-chart-spam', data.spam_distribution);

        // Update highlighted unread counter
        updateHighlightedUnreadBadge(data.highlighted_unread || 0);

        shownCount = 0;
        dom.tableBody.empty();
        renderNextBatch();
    }

    function renderNextBatch() {
        // Usamos currentRows (que puede estar filtrado) en lugar de allFetchedRows
        const nextBatch = currentRows.slice(shownCount, shownCount + BATCH_SIZE);

        if (nextBatch.length > 0) {
            renderTable(nextBatch, true);
            shownCount += nextBatch.length;
        }

        if (shownCount < currentRows.length) {
            $('#efa-btn-load-more').removeClass('hidden').text(`Cargar más (${currentRows.length - shownCount} restantes)`);
        } else {
            $('#efa-btn-load-more').addClass('hidden');
        }

        // Update records counter
        let totalRecords = 0;
        if (lastDashboardData && lastDashboardData.sidebar_counts) {
            // Determine which count to show based on active filters
            const currentNav = $('.efa-nav-item.active').data('filter');
            const currentCrm = $('.efa-nav-item.active').data('crm-status'); // Changed from 'crm-filter' to 'crm-status'
            const currentForm = $('.efa-nav-item.active').data('form-filter');

            if (currentNav === 'unread') {
                totalRecords = lastDashboardData.sidebar_counts.unread || 0;
            } else if (currentNav === 'starred') {
                totalRecords = lastDashboardData.sidebar_counts.starred || 0;
            } else if (currentNav === 'replied') {
                totalRecords = lastDashboardData.sidebar_counts.replied || 0;
            } else if (currentNav === 'spam') {
                totalRecords = lastDashboardData.sidebar_counts.spam || 0;
            } else if (currentNav === 'trash') {
                totalRecords = lastDashboardData.sidebar_counts.trash || 0;
            } else if ((currentCrm || window.currentCrmStateFilter) && lastDashboardData.sidebar_counts.crm_states) {
                // Check both the active element and the global filter variable
                const crmStatus = currentCrm || window.currentCrmStateFilter;
                totalRecords = lastDashboardData.sidebar_counts.crm_states[crmStatus] || 0;
            } else if (currentForm && lastDashboardData.sidebar_counts.forms) {
                totalRecords = lastDashboardData.sidebar_counts.forms[currentForm] || 0;
            } else {
                totalRecords = lastDashboardData.sidebar_counts.all || 0;
            }
        }
        $('#efa-total-records').text(totalRecords);
        $('#efa-showing-records').text(shownCount); // Currently displayed rows
        $('#efa-filtered-records').text(totalRecords); // Total from database

        // Update highlighted toggle visibility based on current results
        updateHighlightedToggle();
    }

    function renderHistoryChart(historyData) {
        const canvas = document.getElementById('kpi-history-chart');
        if (!canvas) return;

        const ctx = canvas.getContext('2d');
        if (charts.history) charts.history.destroy();
        const labels = historyData.map(i => i.label.split(' ')[0].substring(0, 3)); const counts = historyData.map(i => i.count); const colors = getChartColors();
        charts.history = new Chart(ctx, {
            type: 'bar', data: { labels: labels, datasets: [{ data: counts, backgroundColor: '#ab47bc', borderRadius: 2, barPercentage: 0.6 }] },
            options: {
                responsive: true, maintainAspectRatio: false,
                plugins: { legend: { display: false }, tooltip: { enabled: true }, datalabels: { color: body.hasClass('efa-dark-mode') ? '#fff' : '#666', anchor: 'end', align: 'top', offset: -2, font: { size: 9, weight: 'bold' }, formatter: (val) => val > 0 ? val : '' } },
                scales: { x: { display: true, grid: { display: false, drawBorder: false }, ticks: { color: colors.text, font: { size: 9 }, autoSkip: false } }, y: { display: false, min: 0, grace: '10%' } },
                layout: { padding: { top: 15, bottom: 0 } }
            }
        });
    }

    function renderKpiCard(idBase, kpiData) {
        const valEl = $(`#${idBase}-val`);
        if (!valEl.length) return;

        valEl.text(kpiData.total); const listEl = $(`#${idBase}-list`); listEl.empty();
        if (kpiData.breakdown && Object.keys(kpiData.breakdown).length > 0) {
            const sorted = Object.entries(kpiData.breakdown).sort((a, b) => b[1] - a[1]);
            sorted.forEach(([origin, count]) => { const color = getColorForString(origin); listEl.append(`<div class="efa-kpi-row"><span><span style="color:${color};font-weight:bold;">●</span> ${origin}</span><strong>${count}</strong></div>`); });
        } else { listEl.append('<div>-</div>'); }
    }

    function renderMainChart(data) {
        const canvas = document.getElementById('efa-chart-timeline');
        if (!canvas) return;

        const ctx = canvas.getContext('2d'); if (charts.timeline) charts.timeline.destroy(); const colors = getChartColors();
        const datasets = []; for (const [label, points] of Object.entries(data.series)) { const fixedColor = getColorForString(label); datasets.push({ label: label, data: data.labels.map(date => points[date] || 0), borderColor: fixedColor, backgroundColor: 'rgba(0,0,0,0)', tension: 0.3, borderWidth: 2, pointRadius: 2, spanGaps: true }); }
        charts.timeline = new Chart(ctx, {
            type: 'line', data: { labels: data.labels, datasets: datasets },
            options: {
                responsive: true, maintainAspectRatio: false, interaction: { mode: 'index', intersect: false },
                plugins: { legend: { position: 'top', labels: { boxWidth: 10, font: { size: 11 }, color: colors.text } }, tooltip: { backgroundColor: colors.tooltipBg, titleColor: colors.tooltipText, bodyColor: colors.tooltipText }, datalabels: { display: false } },
                scales: { y: { beginAtZero: true, ticks: { stepSize: 1, color: colors.text }, grid: { color: colors.grid } }, x: { ticks: { autoSkip: true, maxTicksLimit: 10, color: colors.text }, grid: { color: colors.grid } } }
            }
        });
    }

    function renderDoughnut(canvasId, dataObj) {
        const canvas = document.getElementById(canvasId);
        if (!canvas) return;

        const ctx = canvas.getContext('2d'); if (charts[canvasId]) charts[canvasId].destroy(); const colors = getChartColors();
        const keys = Object.keys(dataObj); const bgColors = keys.map(key => getColorForString(key));
        charts[canvasId] = new Chart(ctx, {
            type: 'doughnut', data: { labels: keys, datasets: [{ data: Object.values(dataObj), backgroundColor: bgColors, borderWidth: 0, borderColor: body.hasClass('efa-dark-mode') ? '#2a2a3e' : '#fff' }] },
            options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'right', labels: { boxWidth: 12, font: { size: 11 }, color: colors.text } }, datalabels: { display: true, color: '#fff', font: { weight: 'bold', size: 12 }, formatter: (value) => { return value > 0 ? value : ''; } } }, layout: { padding: 10 } }
        });
    }


    // --- REPORT GENERATION LOGIC ---
    // Inject Report Modal HTML (solo una vez)
    if ($('.efa-report-overlay').length === 0) {
        $('body').append(`
            <div class="efa-report-overlay">
                <div class="efa-report-modal">
                    <div class="efa-report-header">
                        <h2>Vista Previa del Informe</h2>
                        <div class="efa-report-actions">
                            <button class="efa-report-btn print" onclick="window.print()"><span class="dashicons dashicons-printer"></span> Imprimir / PDF</button>
                            <button class="efa-report-btn close"><span class="dashicons dashicons-no-alt"></span> Cerrar</button>
                        </div>
                    </div>
                    <div class="efa-report-content" id="efa-report-body">
                        <!-- Dynamic Content -->
                    </div>
                </div>
            </div>
        `);
    }

    const reportOverlay = $('.efa-report-overlay');
    const reportBody = $('#efa-report-body');
    const closeReportBtn = $('.efa-report-btn.close');

    // Usar delegación de eventos para el botón de informe (puede no existir al cargar)
    $(document).on('click', '#efa-btn-report', function (e) {
        e.preventDefault();
        try {
            generateReport();
        } catch (error) {
            console.error('Error al generar informe:', error);
            alert('Error al generar el informe. Por favor, revisa la consola para más detalles.');
        }
    });

    closeReportBtn.on('click', function () {
        reportOverlay.removeClass('open');
    });

    reportOverlay.on('click', function (e) {
        if ($(e.target).is('.efa-report-overlay')) {
            reportOverlay.removeClass('open');
        }
    });

    function generateReport() {
        try {
            // Get report configuration
            const config = efa_vars.report_config || {};

            // Validar que currentRows existe
            if (!currentRows || !Array.isArray(currentRows)) {
                console.error('currentRows no está definido o no es un array');
                currentRows = [];
            }

            // 1. Gather Data
            const totalLeads = currentRows.length;
        const dateRangeText = $('#efa-date-range option:selected').text();
        const formFilterText = $('#efa-form-filter option:selected').text();

        // Calculate Aggregates for Report
        let originsCount = {};
        let formsCount = {};
        let crmCount = {};
        let readCount = { read: 0, unread: 0 };
        let spamCount = { spam: 0, clean: 0 };

        // Función para normalizar nombres de orígenes (eliminar dominios y unificar mayúsculas)
        function normalizeOriginName(origin) {
            if (!origin) return 'Organico';
            const trimmed = (origin || '').toString().trim();
            if (trimmed === '') return 'Organico';
            
            // Convertir a minúsculas para procesamiento
            let normalized = trimmed.toLowerCase();
            
            // Eliminar terminaciones de dominio comunes (.com, .es, .net, .org, .io, .co, etc.)
            const domainPatterns = [
                /\.com$/i, /\.es$/i, /\.net$/i, /\.org$/i, /\.io$/i, /\.co$/i,
                /\.eu$/i, /\.uk$/i, /\.fr$/i, /\.de$/i, /\.it$/i, /\.pt$/i,
                /\.mx$/i, /\.ar$/i, /\.cl$/i, /\.br$/i, /\.us$/i, /\.ca$/i
            ];
            
            for (const pattern of domainPatterns) {
                normalized = normalized.replace(pattern, '');
            }
            
            // Capitalizar primera letra
            normalized = normalized.charAt(0).toUpperCase() + normalized.slice(1);
            
            return normalized;
        }
        
        currentRows.forEach(row => {
            // Origins - Normalizar nombre (unificar mayúsculas/minúsculas y eliminar dominios)
            let org = row.origin || 'Desconocido';
            const normalizedOrg = normalizeOriginName(org);
            if (!originsCount[normalizedOrg]) originsCount[normalizedOrg] = 0;
            originsCount[normalizedOrg]++;

            // Forms
            let frm = row.form || 'Desconocido';
            if (!formsCount[frm]) formsCount[frm] = 0;
            formsCount[frm]++;

            // CRM States
            let crm = row.crm_status || 'Sin clasificar';
            if (!crmCount[crm]) crmCount[crm] = 0;
            crmCount[crm]++;

            // Read/Unread
            if (row.read_status == '1') {
                readCount.read++;
            } else {
                readCount.unread++;
            }

            // Spam detection
            if (row.spam_score && parseInt(row.spam_score) >= 5) {
                spamCount.spam++;
            } else {
                spamCount.clean++;
            }
        });

        // Map CRM IDs to readable labels for display
        let crmCountLabeled = {};
        let deletedStatesCount = 0;  // Counter for deleted/unknown states

        for (let crmId in crmCount) {
            // Find the label for this CRM ID
            const label = efa_vars.crm_labels.find(l => l.id === crmId);

            if (label) {
                // Label exists - use it
                crmCountLabeled[label.label] = crmCount[crmId];
            } else {
                // Label doesn't exist (deleted) - group under "Estados borrados"
                deletedStatesCount += crmCount[crmId];
            }
        }

        // Add grouped deleted states if any
        if (deletedStatesCount > 0) {
            crmCountLabeled['Estados borrados'] = deletedStatesCount;
        }

        // Generate timeline data from currentRows
        let timelineData = {};
        let timelineOriginsData = {}; // Data for the new line chart
        let allOrigins = new Set();

        currentRows.forEach(row => {
            if (row.date) {
                // Parse date format: "10/11/2025 12:26" -> DD/MM/YYYY HH:mm
                const datePart = row.date.split(' ')[0]; // "10/11/2025"
                const [day, month, year] = datePart.split('/');
                const dateKey = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`; // YYYY-MM-DD for sorting

                // Total count per day
                if (!timelineData[dateKey]) {
                    timelineData[dateKey] = 0;
                }
                timelineData[dateKey]++;

                // Count per origin per day
                const origin = row.origin || 'Desconocido';
                allOrigins.add(origin);

                if (!timelineOriginsData[dateKey]) {
                    timelineOriginsData[dateKey] = {};
                }
                if (!timelineOriginsData[dateKey][origin]) {
                    timelineOriginsData[dateKey][origin] = 0;
                }
                timelineOriginsData[dateKey][origin]++;
            }
        });

        // Convert to array and sort by date (Total Timeline)
        let timelineArray = Object.keys(timelineData)
            .sort()
            .map(dateKey => {
                // Format: YYYY-MM-DD -> DD MMM YY
                const [year, month, day] = dateKey.split('-');
                const months = ['ENE', 'FEB', 'MAR', 'ABR', 'MAY', 'JUN', 'JUL', 'AGO', 'SEP', 'OCT', 'NOV', 'DIC'];
                const monthName = months[parseInt(month) - 1];
                const shortYear = year.substring(2);
                const formattedDate = `${day} ${monthName} ${shortYear}`;

                return {
                    label: formattedDate,
                    originalDate: dateKey, // Keep original for matching
                    count: timelineData[dateKey]
                };
            });

        // Prepare data for Origins Line Chart
        let originsChartData = {
            labels: timelineArray.map(t => t.label),
            datasets: []
        };

        Array.from(allOrigins).forEach(origin => {
            let dataPoints = timelineArray.map(t => {
                const dateKey = t.originalDate;
                return (timelineOriginsData[dateKey] && timelineOriginsData[dateKey][origin]) ? timelineOriginsData[dateKey][origin] : 0;
            });

            originsChartData.datasets.push({
                label: origin,
                data: dataPoints,
                borderColor: getColorForString(origin), // Helper function to get color
                backgroundColor: getColorForString(origin),
                fill: false,
                tension: 0.4,
                borderWidth: 2,
                pointRadius: 3
            });
        });

        // Logo Logic
        let logoHtml = '';
        if (config.show_logo !== false) {
            if (efa_vars.site_logo) {
                logoHtml = `<img src="${efa_vars.site_logo}" alt="Logo">`;
            } else {
                logoHtml = `<h1>Informe de Leads</h1>`;
            }
        } else {
            logoHtml = `<h1>Informe de Leads</h1>`;
        }

        // 2. Build HTML Structure
        let periodText = dateRangeText;
        if (lastDashboardData && lastDashboardData.date_range) {
            periodText = `Periodo: ${lastDashboardData.date_range.start} a ${lastDashboardData.date_range.end} (${lastDashboardData.date_range.days} días)`;
        }

        let html = `
                <div class="efa-rep-container">
                <div class="efa-rep-header-visual">
                    <div class="efa-rep-logo">
                        ${logoHtml}
                    </div>
                    <div class="efa-rep-title-block">
                        <h2>Informe evolución de Leads</h2>
                        <span class="efa-rep-date">${periodText}</span>
                        <span class="efa-rep-subtitle">Total de correos: <strong>${totalLeads}</strong> correos recibidos.</span>
                    </div>
                </div>
                `;

        // Helper for table rows
        const generateTableRows = () => {
            let rowsHtml = '';
            currentRows.slice(0, 20).forEach(row => {
                const date = row.date ? row.date.split(' ')[0] : '-';
                const readIcon = row.read_status == '1' ? '✓' : '✗';
                const readColor = row.read_status == '1' ? '#4caf50' : '#f44336';

                // Map CRM status to readable label
                const crmId = row.crm_status || '';
                const crmLabel = efa_vars.crm_labels.find(l => l.id === crmId);
                const crmDisplay = crmLabel ? crmLabel.label : (crmId ? 'Estado borrado' : 'Sin clasificar');

                rowsHtml += `
                    <tr>
                        <td>${date}</td>
                        <td>${row.email || '-'}</td>
                        <td>${row.form || '-'}</td>
                        <td>${row.origin || '-'}</td>
                        <td>${crmDisplay}</td>
                        <td style="color: ${readColor}; text-align: center;">${readIcon}</td>
                    </tr>`;
            });

            if (currentRows.length > 20) {
                rowsHtml += `
                    <tr>
                        <td colspan="6" style="text-align: center; font-style: italic; color: #666;">
                            ... y ${currentRows.length - 20} correos más
                        </td>
                    </tr>`;
            }
            return rowsHtml;
        };

        // Block Renderers Map
        const blockRenderers = {
            'kpis': () => {
                if (config.show_kpis === false) return '';
                const formFilterValue = $('#efa-form-filter').val();
                const displayFormFilter = formFilterValue ? formFilterText : 'Todos los formularios';
                const originNames = Object.keys(originsCount).join(', ') || 'Ninguna';
                return `
                <div class="efa-rep-section-title">Resumen General</div>
                <div class="efa-rep-meta-grid">
                    <div class="efa-rep-meta-item">
                        <span class="label">Filtro Activo</span>
                        <span class="value">${displayFormFilter}</span>
                    </div>
                    <div class="efa-rep-meta-item">
                        <span class="label">Fuentes Activas</span>
                        <span class="value">${originNames}</span>
                    </div>
                    <div class="efa-rep-meta-item">
                        <span class="label">Promedio Diario</span>
                        <span class="value highlight">${lastDashboardData && lastDashboardData.kpis ? lastDashboardData.kpis.daily_average : '-'}</span>
                    </div>
                </div>`;
            },
            'timeline': () => {
                if (config.show_timeline === false || timelineArray.length === 0) return '';
                return `
                <div class="efa-rep-section-title">Evolución de Leads</div>
                <div class="efa-rep-card full-width">
                    <div class="efa-rep-chart-box" style="height: 300px; margin-bottom: 20px;">
                        <canvas id="efa-rep-chart-vertical"></canvas>
                    </div>
                    <div class="efa-rep-chart-box" style="height: 300px;">
                        <canvas id="efa-rep-chart-origins-line"></canvas>
                    </div>
                </div>`;
            },
            'forms': () => {
                if (config.show_forms === false || Object.keys(formsCount).length === 0) return '';
                
                // Ordenar formularios por cantidad (descendente)
                const sortedForms = Object.entries(formsCount)
                    .map(([name, count]) => ({ name, count }))
                    .sort((a, b) => b.count - a.count);
                
                // Calcular total para porcentajes
                const totalForms = sortedForms.reduce((sum, item) => sum + item.count, 0);
                
                // Generar cards de 3 en 3
                let cardsHtml = '';
                sortedForms.forEach((form) => {
                    const percentage = totalForms > 0 ? ((form.count / totalForms) * 100).toFixed(1) : 0;
                    
                    // Obtener color del formulario usando la misma función que la gráfica del dashboard
                    const formColor = getColorForString(form.name);
                    
                    // Círculo pequeño con el color del formulario
                    const circleHtml = `
                        <div style="width: 12px; height: 12px; border-radius: 50%; background-color: ${formColor}; margin-right: 8px; flex-shrink: 0;"></div>
                    `;
                    
                    // Usar clase genérica para todas las cards
                    const cardClass = 'efa-spam-card efa-spam-card-default';
                    const gradientColor = `linear-gradient(90deg, ${formColor}, ${formColor}dd)`;
                    
                    // Crear card
                    cardsHtml += `
                        <div class="${cardClass}">
                            <div class="efa-spam-card-bg"></div>
                            <div class="efa-spam-content">
                                <div class="efa-spam-label" style="display: flex; align-items: center; margin-bottom: 8px;">
                                    ${circleHtml}
                                    <span>${form.name}</span>
                                </div>
                                <div class="efa-spam-value">${form.count}</div>
                                <div class="efa-spam-desc">${percentage}% del total</div>
                                <div class="efa-spam-bar">
                                    <div class="efa-spam-bar-fill" style="width: ${percentage}%; background: ${gradientColor};"></div>
                                </div>
                            </div>
                        </div>
                    `;
                });
                
                return `
                <div class="efa-rep-section-title">📝 Distribución por Formularios</div>
                <div class="efa-rep-card">
                    <div class="efa-spam-grid" style="grid-template-columns: repeat(3, 1fr);">
                        ${cardsHtml}
                    </div>
                </div>`;
            },
            'origins': () => {
                if (config.show_origins === false || Object.keys(originsCount).length === 0) return '';
                
                // Ordenar orígenes por cantidad (descendente)
                const sortedOrigins = Object.entries(originsCount)
                    .map(([name, count]) => ({ name, count }))
                    .sort((a, b) => b.count - a.count);
                
                // Calcular total para porcentajes
                const totalOrigins = sortedOrigins.reduce((sum, item) => sum + item.count, 0);
                
                // Generar cards de 3 en 3
                let cardsHtml = '';
                sortedOrigins.forEach((origin, index) => {
                    const position = index + 1;
                    const percentage = totalOrigins > 0 ? ((origin.count / totalOrigins) * 100).toFixed(1) : 0;
                    
                    // Obtener color del origen usando la misma función que la gráfica de tendencia
                    const originColor = getColorForString(origin.name);
                    
                    // Círculo pequeño con el color del origen
                    const circleHtml = `
                        <div style="width: 12px; height: 12px; border-radius: 50%; background-color: ${originColor}; margin-right: 8px; flex-shrink: 0;"></div>
                    `;
                    
                    // Usar clase genérica para todas las cards
                    const cardClass = 'efa-spam-card efa-spam-card-default';
                    const gradientColor = `linear-gradient(90deg, ${originColor}, ${originColor}dd)`;
                    
                    // Crear card
                    cardsHtml += `
                        <div class="${cardClass}">
                            <div class="efa-spam-card-bg"></div>
                            <div class="efa-spam-content">
                                <div class="efa-spam-label" style="display: flex; align-items: center; margin-bottom: 8px;">
                                    ${circleHtml}
                                    <span>${origin.name}</span>
                                </div>
                                <div class="efa-spam-value">${origin.count}</div>
                                <div class="efa-spam-desc">${percentage}% del total</div>
                                <div class="efa-spam-bar">
                                    <div class="efa-spam-bar-fill" style="width: ${percentage}%; background: ${gradientColor};"></div>
                                </div>
                            </div>
                        </div>
                    `;
                });
                
                return `
                <div class="efa-rep-section-title">🌍 Distribución por Orígenes</div>
                <div class="efa-rep-card">
                    <div class="efa-spam-grid" style="grid-template-columns: repeat(3, 1fr);">
                        ${cardsHtml}
                    </div>
                </div>`;
            },
            'crm': () => {
                if (config.show_crm === false || Object.keys(crmCountLabeled).length === 0) return '';
                return `
                <div class="efa-rep-section-title">Estados CRM</div>
                <div class="efa-rep-card">
                    <div class="efa-rep-chart-box">
                        <canvas id="efa-rep-chart-crm"></canvas>
                    </div>
                </div>`;
            },
            'read': () => {
                if (config.show_read === false) return '';
                return `
                <div class="efa-rep-section-title">Correos Leídos vs No Leídos</div>
                <div class="efa-rep-card">
                    <div class="efa-rep-chart-box">
                        <canvas id="efa-rep-chart-read"></canvas>
                    </div>
                </div>`;
            },
            'spam': () => {
                if (config.show_spam === false) return '';
                const spamPercentage = totalLeads > 0 ? Math.round((spamCount.spam / totalLeads) * 100) : 0;
                return `
                <div class="efa-rep-section-title">Detección de Spam</div>
                <div class="efa-rep-card">
                    <div class="efa-rep-stats-row">
                        <div class="efa-rep-stat-box clean">
                            <span class="number">${spamCount.clean}</span>
                            <span class="label">Correos Limpios</span>
                        </div>
                        <div class="efa-rep-stat-box spam">
                            <div class="efa-rep-spam-stat">
                                <span class="label">Posible Spam</span>
                                <span class="value" style="color: #f44336;">${spamCount.spam} (${spamPercentage}%)</span>
                            </div>
                        </div>
                    </div>
                </div>`;
            },
        };

        // Default order if not configured
        const defaultOrder = ['kpis', 'origins', 'timeline', 'spam', 'forms', 'crm', 'read'];
        const savedBlocksOrder = config.blocks_order && config.blocks_order.length > 0 ? config.blocks_order : defaultOrder;

        // Helper function to check if a block is enabled
        const isBlockEnabled = (blockId) => {
            switch(blockId) {
                case 'kpis': return config.show_kpis !== false;
                case 'timeline': return config.show_timeline !== false;
                case 'forms': return config.show_forms !== false;
                case 'origins': return config.show_origins !== false;
                case 'crm': return config.show_crm !== false;
                case 'read': return config.show_read !== false;
                case 'spam': return config.show_spam !== false;
                default: return false;
            }
        };

        // Filter blocks order to only include enabled blocks, maintaining the saved order
        const blocksOrder = savedBlocksOrder.filter(blockId => isBlockEnabled(blockId));

        // Append blocks in order (only enabled ones, respecting saved order)
        blocksOrder.forEach(blockId => {
            if (blockRenderers[blockId]) {
                const blockHtml = blockRenderers[blockId]();
                // Only append if block returns content (not empty string)
                if (blockHtml && blockHtml.trim() !== '') {
                    html += blockHtml;
                }
            }
        });

        html += `</div>`;

        reportBody.html(html);
        reportOverlay.addClass('open');

        // 3. Render Charts (Wait for DOM) - only render enabled charts
        setTimeout(() => {
            // Origins and Forms charts removed - now using cards instead
            if (config.show_crm !== false && Object.keys(crmCountLabeled).length > 0) {
                renderReportChart('efa-rep-chart-crm', crmCountLabeled, 'doughnut');
            }
            if (config.show_read !== false) {
                renderReportChart('efa-rep-chart-read', {
                    'Leídos': readCount.read,
                    'No Leídos': readCount.unread
                }, 'doughnut');
            }

            // Render Vertical Bar Chart with timeline from currentRows
            if (config.show_timeline !== false && timelineArray.length > 0) {
                renderReportVerticalChart(timelineArray);

                // Render Origins Line Chart
                if (originsChartData.datasets.length > 0) {
                    renderReportOriginsLineChart(originsChartData);
                }
            }
        }, 100);
        } catch (error) {
            console.error('Error en generateReport:', error);
            alert('Error al generar el informe: ' + error.message);
            if (reportOverlay && reportOverlay.length > 0) {
                reportOverlay.removeClass('open');
            }
        }
    }

    function renderReportOriginsLineChart(chartData) {
        const ctx = document.getElementById('efa-rep-chart-origins-line').getContext('2d');

        new Chart(ctx, {
            type: 'line',
            data: chartData,
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        position: 'top',
                        labels: {
                            usePointStyle: true,
                            boxWidth: 8
                        }
                    },
                    tooltip: {
                        mode: 'index',
                        intersect: false,
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        ticks: {
                            stepSize: 1
                        },
                        grid: {
                            color: '#f0f0f0'
                        }
                    },
                    x: {
                        grid: {
                            display: false
                        }
                    }
                },
                interaction: {
                    mode: 'nearest',
                    axis: 'x',
                    intersect: false
                }
            }
        });
    }

    function renderReportChart(canvasId, dataObj, type) {
        const ctx = document.getElementById(canvasId).getContext('2d');
        const keys = Object.keys(dataObj);
        const values = Object.values(dataObj);
        const colors = keys.map(k => getColorForString(k));

        new Chart(ctx, {
            type: type,
            data: {
                labels: keys,
                datasets: [{
                    data: values,
                    backgroundColor: colors,
                    borderWidth: 0
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: { position: 'right', labels: { boxWidth: 10, font: { size: 10 } } },
                    datalabels: {
                        color: '#fff',
                        font: { weight: 'bold' },
                        formatter: (val) => val > 0 ? val : ''
                    }
                },
                layout: { padding: 10 }
            }
        });
    }

    function renderReportVerticalChart(historyData) {
        const ctx = document.getElementById('efa-rep-chart-vertical');
        if (!ctx) return;

        // Helper to abbreviate month names
        const abbreviateMonth = (label) => {
            const monthMap = {
                'Enero': 'ENE', 'Febrero': 'FEB', 'Marzo': 'MAR',
                'Abril': 'ABR', 'Mayo': 'MAY', 'Junio': 'JUN',
                'Julio': 'JUL', 'Agosto': 'AGO', 'Septiembre': 'SEP',
                'Octubre': 'OCT', 'Noviembre': 'NOV', 'Diciembre': 'DIC'
            };

            for (let [full, abbr] of Object.entries(monthMap)) {
                if (label.includes(full)) {
                    return label.replace(full, abbr);
                }
            }
            return label;
        };

        const labels = historyData.map(i => abbreviateMonth(i.label));
        const counts = historyData.map(i => i.count);

        new Chart(ctx.getContext('2d'), {
            type: 'bar',
            data: {
                labels: labels,
                datasets: [{
                    label: 'Leads',
                    data: counts,
                    backgroundColor: '#ab47bc',
                    borderRadius: 4,
                    barPercentage: 0.6
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: { display: false },
                    tooltip: {
                        backgroundColor: 'rgba(0,0,0,0.8)',
                        padding: 12,
                        titleColor: '#fff',
                        bodyColor: '#fff',
                        callbacks: {
                            label: function (context) {
                                return 'Leads: ' + context.parsed.y;
                            }
                        }
                    },
                    datalabels: {
                        anchor: 'end',
                        align: 'top',
                        color: '#666',
                        font: { size: 11, weight: 'bold' },
                        formatter: (val) => val > 0 ? val : ''
                    }
                },
                scales: {
                    x: {
                        grid: { display: false },
                        ticks: {
                            autoSkip: false,
                            maxRotation: 0,
                            minRotation: 0,
                            font: { size: 10 }
                        }
                    },
                    y: {
                        beginAtZero: true,
                        grid: {
                            display: true,
                            color: 'rgba(0,0,0,0.05)'
                        },
                        ticks: {
                            display: false
                        }
                    }
                },
                layout: {
                    padding: {
                        top: 20
                    }
                }
            },
            plugins: [ChartDataLabels]
        });
    }

    // --- CRM PANEL LOGIC ---

    function renderCrmPanel(data, rowData) {
        const content = $('#efa-crm-content');

        let crmStatus = (data.crm && data.crm.status) ? data.crm.status : 'new';

        // --- FALLBACK LOGIC FOR DELETED STATUSES ---
        let statusExists = false;
        if (typeof efa_vars !== 'undefined' && efa_vars.crm_labels) {
            statusExists = efa_vars.crm_labels.some(l => l.id === crmStatus);
        }

        // If status is invalid (deleted) and we have labels available
        if (!statusExists && efa_vars.crm_labels && efa_vars.crm_labels.length > 0) {
            const defaultStatus = efa_vars.crm_labels[0].id; // Use first available status (default)
            crmStatus = defaultStatus;

            // Auto-assign default status in backend silently
            updateCrmStatus(rowData.id, defaultStatus, function (success) {
                if (success) {
                    // Update local data to reflect the fix
                    const masterIdx = allFetchedRows.findIndex(r => r.id == rowData.id);
                    if (masterIdx > -1) allFetchedRows[masterIdx].crm_status = defaultStatus;
                    const idx = currentRows.findIndex(r => r.id == rowData.id);
                    if (idx > -1) currentRows[idx].crm_status = defaultStatus;

                    // Refresh table row visual
                    refreshTableRowCrm(rowData.id, defaultStatus);
                }
            });
        }
        // -------------------------------------------

        let crmNotes = (data.crm && data.crm.notes) ? data.crm.notes : [];

        // Update Panel Badge
        const badge = $('#efa-notes-badge-panel');
        if (crmNotes.length > 0) {
            badge.text(crmNotes.length).show();
        } else {
            badge.hide();
        }

        // Generate pills dynamically from crm_labels
        let pillsHtml = '';
        if (typeof efa_vars !== 'undefined' && efa_vars.crm_labels) {
            efa_vars.crm_labels.forEach(label => {
                const isActive = crmStatus === label.id;
                pillsHtml += `<button class="efa-crm-pill ${isActive ? 'active' : ''}" data-status="${label.id}" style="--pill-color:${label.color}">${label.label}</button>`;
            });
        }

        let html = `
            <div class="efa-crm-status-wrapper">
                <div class="efa-crm-label">Estado del Lead</div>
                <div class="efa-crm-pills">
                    ${pillsHtml}
                </div>
            </div>

                <div class="efa-crm-notes-wrapper">
                    <div class="efa-crm-label">Historial de Notas</div>
                    <div class="efa-crm-notes-list" id="efa-notes-list">`;

        if (crmNotes.length === 0) {
            html += `<div class="efa-no-notes">
                <span class="dashicons dashicons-edit" style="font-size: 40px; width: 40px; height: 40px; color: #ddd; margin-bottom: 10px;"></span>
                <p>No hay notas registradas.<br>Escribe la primera nota abajo.</p>
            </div>`;
        } else {
            crmNotes.forEach(note => {
                // Get initials
                let initials = note.author ? note.author.substring(0, 2).toUpperCase() : 'YO';

                html += `<div class="efa-crm-note">
                    <div class="efa-note-avatar">${initials}</div>
                    <div class="efa-note-content">
                        <div class="efa-note-header">
                            <span class="efa-note-author">${note.author}</span>
                            <span class="efa-note-date">${note.date}</span>
                        </div>
                        <div class="efa-note-body">${note.text}</div>
                    </div>
                </div>`;
            });
        }

        html += `</div>
                    <div class="efa-crm-input-area">
                        <div class="efa-input-wrapper">
                            <textarea id="efa-note-input" placeholder="Escribe una nota interna... (Enter para enviar)"></textarea>
                            <button id="efa-add-note-btn" class="efa-btn-send" title="Enviar nota">
                                <span class="dashicons dashicons-arrow-right-alt2"></span>
                            </button>
                        </div>
                        <div class="efa-input-hint">Presiona Enter para enviar, Shift+Enter para salto de línea</div>
                    </div>
                </div>`;

        content.html(html);

        // Scroll to bottom of notes
        const list = $('#efa-notes-list');
        list.scrollTop(list[0].scrollHeight);

        setupCrmHandlers(rowData.id);
    }

    function closeAllPanels() {
        $('.efa-modal-overlay').removeClass('open');
        $('#efa-slide-panel').removeClass('open');
        $('#efa-crm-panel').removeClass('open');
        $('#efa-reply-panel').removeClass('open');
        $('#efa-reply-actions').hide();
    }

    // Attach close handlers
    $('#efa-close-panel, .efa-modal-overlay').off('click').on('click', closeAllPanels);
    $('#efa-close-crm-panel').off('click').on('click', function () {
        $('#efa-crm-panel').removeClass('open');
    });
    $('#efa-close-reply-panel').off('click').on('click', function () {
        $('#efa-reply-panel').removeClass('open');
        $('#efa-reply-actions').hide();
    });

    // --- CRM HANDLERS ---

    function setupCrmHandlers(id) {
        // Status Pills
        $('.efa-crm-pill').off('click').on('click', function () {
            const btn = $(this);
            const status = btn.data('status');

            // Optimistic UI
            $('.efa-crm-pill').removeClass('active');
            btn.addClass('active');

            updateCrmStatus(id, status, function (success) {
                if (!success) alert('Error al actualizar estado');
                else {
                    // Update internal data
                    const masterIdx = allFetchedRows.findIndex(r => r.id == id);
                    if (masterIdx > -1) allFetchedRows[masterIdx].crm_status = status;
                    const idx = currentRows.findIndex(r => r.id == id);
                    if (idx > -1) currentRows[idx].crm_status = status;

                    // Refresh table row visual
                    refreshTableRowCrm(id, status);
                }
            });
        });

        // Add Note Logic
        const sendNote = () => {
            const btn = $('#efa-add-note-btn');
            const input = $('#efa-note-input');
            const text = input.val().trim();

            if (!text) return;

            btn.prop('disabled', true).addClass('sending');

            addCrmNote(id, text, function (success, note, count) {
                btn.prop('disabled', false).removeClass('sending');
                if (success && note) {
                    input.val('');

                    // Get initials
                    let initials = note.author ? note.author.substring(0, 2).toUpperCase() : 'YO';

                    const html = `<div class="efa-crm-note">
                        <div class="efa-note-avatar">${initials}</div>
                        <div class="efa-note-content">
                            <div class="efa-note-header">
                                <span class="efa-note-author">${note.author}</span>
                                <span class="efa-note-date">${note.date}</span>
                            </div>
                            <div class="efa-note-body">${note.text}</div>
                        </div>
                    </div > `;

                    const list = $('#efa-notes-list');
                    if (list.find('.efa-no-notes').length) list.empty();
                    list.append(html);
                    list.scrollTop(list[0].scrollHeight);

                    // Update Badge in Panel
                    $('#efa-notes-badge-panel').text(count).show();

                    // Update Data Arrays
                    const masterIdx = allFetchedRows.findIndex(r => r.id == id);
                    if (masterIdx > -1) allFetchedRows[masterIdx].notes_count = count;
                    const idx = currentRows.findIndex(r => r.id == id);
                    if (idx > -1) currentRows[idx].notes_count = count;

                    // Update Table Row Badge (if visible)
                    refreshTableRowCrm(id, currentRows[idx].crm_status);

                } else {
                    alert('Error al guardar nota');
                }
            });
        };

        // Button Click
        $('#efa-add-note-btn').off('click').on('click', sendNote);

        // Enter Key
        $('#efa-note-input').off('keydown').on('keydown', function (e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendNote();
            }
        });
    }

    function updateCrmStatus(id, status, callback) {
        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_update_crm_status', nonce: efa_vars.nonce, id: id, status: status },
            success: function (res) { callback && callback(res.success); },
            error: function () { callback && callback(false); }
        });
    }

    function addCrmNote(id, text, callback) {
        $.ajax({
            url: efa_vars.ajax_url, type: 'POST', dataType: 'json',
            data: { action: 'efa_add_crm_note', nonce: efa_vars.nonce, id: id, note: text },
            success: function (res) { callback && callback(res.success, res.data ? res.data.note : null, res.data ? res.data.notes_count : 0); },
            error: function () { callback && callback(false); }
        });
    }

    function refreshTableRowCrm(id, status) {
        const row = $(`tr[data-id="${id}"]`);
        const badge = row.find('.efa-crm-badge');
        if (badge.length) {
            // Get label and color from dynamic labels
            let label = 'Nuevo';
            let color = '#2271b1';

            if (typeof efa_vars !== 'undefined' && efa_vars.crm_labels) {
                const labelObj = efa_vars.crm_labels.find(l => l.id === status);
                if (labelObj) {
                    label = labelObj.label;
                    color = labelObj.color;
                }
            }

            // Re-construct notes badge
            const rowData = currentRows.find(r => r.id == id);
            let notesBadge = '';
            if (rowData && rowData.notes_count > 0) {
                notesBadge = `<span class="efa-notes-badge-table" title="${rowData.notes_count} notas">${rowData.notes_count}</span>`;
            }

            badge.attr('style', `background-color: ${color}; color: #fff; display:inline-flex;align-items:center;`)
                .html(label + notesBadge);
        }
    }

    // --- REPLY EMAIL FUNCTIONALITY ---
    function openReplyPanel(rowData, submissionData) {
        // Get lead name for subject suggestion
        let leadName = rowData.name || 'Cliente';
        let defaultSubject = 'Re: Consulta desde ' + (rowData.form || 'formulario');
        
        // Get original message if available
        let originalMessage = '';
        if (submissionData && submissionData.values) {
            submissionData.values.forEach(f => {
                let k = f.key.toLowerCase();
                if (k.includes('message') || k.includes('mensaje')) {
                    originalMessage = f.value;
                }
            });
        }

        // Build HTML for reply panel
        let originalMessageHtml = '';
        if (originalMessage) {
            originalMessageHtml = `
                <div class="efa-reply-original-message">
                    <div class="efa-reply-original-message-label">
                        <span class="dashicons dashicons-email"></span>
                        Mensaje Original
                    </div>
                    <div class="efa-reply-original-message-text">${originalMessage}</div>
                </div>
            `;
        }

        let html = `
            <div class="efa-reply-form-wrapper">
                <div class="efa-reply-field">
                    <label>
                        <span class="dashicons dashicons-edit"></span>
                        Asunto:
                    </label>
                    <input type="text" id="efa-reply-subject" placeholder="Asunto del correo" value="${defaultSubject}">
                </div>

                <div class="efa-reply-field">
                    <label>
                        <span class="dashicons dashicons-editor-paragraph"></span>
                        Tu Respuesta:
                    </label>
                    <textarea id="efa-reply-message" placeholder="Escribe tu respuesta aquí..."></textarea>
                    ${originalMessageHtml}
                </div>

                <div class="efa-reply-info">
                    <span class="dashicons dashicons-info"></span>
                    <div>
                        <strong>Nota:</strong> La firma configurada se añadirá automáticamente al final del mensaje.
                    </div>
                </div>
            </div>
        `;

        // Botones de acción (fuera del contenido scrolleable)
        const actionsHtml = `
            <button class="efa-reply-btn send" id="efa-reply-send-btn">
                <span class="dashicons dashicons-email-alt"></span>
                Enviar Correo
            </button>
        `;

        // Set content and actions, then open panel
        $('#efa-reply-content').html(html);
        $('#efa-reply-actions').html(actionsHtml).show();
        $('#efa-reply-panel').addClass('open');

        // Focus on message textarea
        setTimeout(() => {
            $('#efa-reply-message').focus();
        }, 350);

        // Setup handlers
        setupReplyHandlers(rowData.id, rowData.email, rowData);
    }

    function setupReplyHandlers(submissionId, recipientEmail, rowData) {
        // Send button
        $('#efa-reply-send-btn').off('click').on('click', function() {
            const subject = $('#efa-reply-subject').val().trim();
            const message = $('#efa-reply-message').val().trim();

            if (!subject) {
                Swal.fire({
                    title: 'Asunto requerido',
                    text: 'Por favor, introduce un asunto para el correo.',
                    icon: 'warning',
                    confirmButtonText: 'Aceptar',
                    confirmButtonColor: '#e01d75'
                });
                $('#efa-reply-subject').focus();
                return;
            }

            if (!message) {
                Swal.fire({
                    title: 'Mensaje requerido',
                    text: 'Por favor, escribe un mensaje antes de enviar.',
                    icon: 'warning',
                    confirmButtonText: 'Aceptar',
                    confirmButtonColor: '#e01d75'
                });
                $('#efa-reply-message').focus();
                return;
            }

            // Disable button and show loading
            const btn = $(this);
            btn.prop('disabled', true).html('<span class="dashicons dashicons-update" style="animation: spin 1s linear infinite;"></span> Enviando...');

            sendReplyEmail(submissionId, subject, message, recipientEmail, function(success) {
                if (success) {
                    // Update rowData with replied status
                    const currentDate = new Date().toISOString().slice(0, 19).replace('T', ' ');
                    rowData.replied_status = currentDate;
                    
                    // Update replies count
                    const currentRepliesCount = rowData.replies_count || (rowData.replied_status ? 1 : 0);
                    rowData.replies_count = currentRepliesCount + 1;
                    
                    // Update arrays
                    const masterIdx = allFetchedRows.findIndex(r => r.id == submissionId);
                    if (masterIdx > -1) {
                        allFetchedRows[masterIdx].replied_status = currentDate;
                        allFetchedRows[masterIdx].replies_count = rowData.replies_count;
                    }
                    const currentIdx = currentRows.findIndex(r => r.id == submissionId);
                    if (currentIdx > -1) {
                        currentRows[currentIdx].replied_status = currentDate;
                        currentRows[currentIdx].replies_count = rowData.replies_count;
                    }
                    
                    // Update table row to show arrow with count
                    updateTableRowReplied(submissionId);
                    
                    // Update sidebar counter
                    updateRepliedCounter();
                    
                    // If the detail panel is open, refresh it to show the new reply
                    if (dom.slidePanel.hasClass('open') && window.currentRowData && window.currentRowData.id == submissionId) {
                        // Reload details to get updated replies
                        $.ajax({
                            url: efa_vars.ajax_url,
                            type: 'POST',
                            dataType: 'json',
                            data: { action: 'efa_get_submission_details', nonce: efa_vars.nonce, id: submissionId },
                            success: function (res) {
                                if (res.success) {
                                    // Update currentRowData with new reply data
                                    const updatedRowData = currentRows.find(r => r.id == submissionId) || allFetchedRows.find(r => r.id == submissionId);
                                    if (updatedRowData) {
                                        // Update replies count from the response
                                        if (res.data.replies && Array.isArray(res.data.replies)) {
                                            updatedRowData.replies_count = res.data.replies.length;
                                        }
                                        window.currentRowData = updatedRowData;
                                        renderDetails(res.data, updatedRowData);
                                    }
                                }
                            }
                        });
                    }
                    
                    // Close both panels (reply and main)
                    $('#efa-reply-panel').removeClass('open');
                    closeAllPanels();
                    // Clear form
                    $('#efa-reply-subject').val('');
                    $('#efa-reply-message').val('');
                } else {
                    // Re-enable button
                    btn.prop('disabled', false).html('<span class="dashicons dashicons-email-alt"></span> Enviar Correo');
                }
            });
        });

        // Enter key in subject moves to message
        $('#efa-reply-subject').off('keydown').on('keydown', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                $('#efa-reply-message').focus();
            }
        });
    }

    function sendReplyEmail(submissionId, subject, message, recipientEmail, callback) {
        $.ajax({
            url: efa_vars.ajax_url,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'efa_send_reply_email',
                nonce: efa_vars.nonce,
                id: submissionId,
                subject: subject,
                message: message
            },
            success: function(res) {
                if (res.success) {
                    Swal.fire({
                        title: '<div style="display: flex; align-items: center; justify-content: center; gap: 10px;"><span class="dashicons dashicons-yes-alt" style="font-size: 32px; color: #10b981;"></span><span>¡Correo Enviado!</span></div>',
                        html: `
                            <div style="text-align: center; padding: 10px 0;">
                                <p style="margin-bottom: 15px; color: #6b7280; font-size: 14px;">El correo se ha enviado correctamente a:</p>
                                <p style="font-weight: 600; color: #2271b1; font-size: 16px; margin-bottom: 20px;">
                                    <span class="dashicons dashicons-email" style="font-size: 18px; vertical-align: middle; margin-right: 6px;"></span>
                                    ${recipientEmail}
                                </p>
                                <div style="background: #f0fdf4; border: 1px solid #86efac; border-radius: 6px; padding: 12px; font-size: 13px; color: #166534;">
                                    <span class="dashicons dashicons-info" style="font-size: 14px; vertical-align: middle; margin-right: 6px;"></span>
                                    Revisa la bandeja de entrada del destinatario para confirmar la recepción.
                                </div>
                            </div>
                        `,
                        icon: false,
                        confirmButtonText: '<span class="dashicons dashicons-yes-alt" style="font-size: 14px; vertical-align: middle; margin-right: 4px;"></span> Aceptar',
                        confirmButtonColor: '#10b981',
                        timer: 3000,
                        timerProgressBar: true,
                        allowOutsideClick: false
                    });
                    if (callback) callback(true);
                } else {
                    Swal.fire({
                        title: '<div style="display: flex; align-items: center; gap: 10px;"><span class="dashicons dashicons-warning" style="font-size: 32px; color: #dc2626;"></span><span>Error al Enviar</span></div>',
                        html: `
                            <div style="text-align: center; padding: 10px 0;">
                                <p style="margin-bottom: 15px; color: #6b7280; font-size: 14px;">${res.data || 'No se pudo enviar el correo. Verifica tu configuración SMTP.'}</p>
                                <div style="background: #fef2f2; border: 1px solid #fecaca; border-radius: 6px; padding: 12px; font-size: 13px; color: #991b1b;">
                                    <span class="dashicons dashicons-info" style="font-size: 14px; vertical-align: middle; margin-right: 6px;"></span>
                                    Asegúrate de tener un plugin SMTP configurado correctamente.
                                </div>
                            </div>
                        `,
                        icon: false,
                        confirmButtonText: '<span class="dashicons dashicons-no-alt" style="font-size: 14px; vertical-align: middle; margin-right: 4px;"></span> Aceptar',
                        confirmButtonColor: '#dc2626'
                    });
                    if (callback) callback(false);
                }
            },
            error: function() {
                Swal.fire({
                    title: '<div style="display: flex; align-items: center; gap: 10px;"><span class="dashicons dashicons-warning" style="font-size: 32px; color: #dc2626;"></span><span>Error de Conexión</span></div>',
                    html: `
                        <div style="text-align: center; padding: 10px 0;">
                            <p style="margin-bottom: 15px; color: #6b7280; font-size: 14px;">No se pudo conectar con el servidor.</p>
                            <p style="color: #6b7280; font-size: 13px;">Por favor, verifica tu conexión e intenta de nuevo.</p>
                        </div>
                    `,
                    icon: false,
                    confirmButtonText: '<span class="dashicons dashicons-no-alt" style="font-size: 14px; vertical-align: middle; margin-right: 4px;"></span> Aceptar',
                    confirmButtonColor: '#dc2626'
                });
                if (callback) callback(false);
            }
        });
    }

    // Update table row to show replied arrow with count
    function updateTableRowReplied(submissionId) {
        const row = $(`tr[data-id="${submissionId}"]`);
        if (!row.length) return;
        
        const dateCell = row.find('td:first-child');
        if (dateCell.length) {
            const rowData = currentRows.find(r => r.id == submissionId) || allFetchedRows.find(r => r.id == submissionId);
            if (rowData && rowData.date && rowData.replied_status) {
                // Get replies count, default to 1 if not set
                const repliesCount = rowData.replies_count || 1;
                const countText = repliesCount > 1 ? `${repliesCount}` : '';
                const newDateText = `${rowData.date} <span style="color: #e01d75; font-weight: bold; margin-left: 4px;" title="${repliesCount} respuesta${repliesCount > 1 ? 's' : ''} enviada${repliesCount > 1 ? 's' : ''}">${countText}→</span>`;
                dateCell.html(newDateText);
            }
        }
    }

    // Update replied counter in sidebar
    function updateRepliedCounter() {
        // Count all rows with replied_status
        let repliedCount = 0;
        allFetchedRows.forEach(row => {
            if (row.replied_status && row.replied_status !== '') {
                repliedCount++;
            }
        });
        
        // Update sidebar counter
        $('#efa-count-replied').text(repliedCount);
        
        // If we have lastDashboardData, update it too
        if (lastDashboardData && lastDashboardData.sidebar_counts) {
            lastDashboardData.sidebar_counts.replied = repliedCount;
        }
    }

    function updateUnreadCounter() {
        // Use the backend count from lastDashboardData and decrement by 1 when marking as read
        // This is more accurate than counting from allFetchedRows which only contains filtered results
        let unreadCount = 0;
        
        if (lastDashboardData && lastDashboardData.sidebar_counts && lastDashboardData.sidebar_counts.unread !== undefined) {
            // Start with the backend count
            unreadCount = lastDashboardData.sidebar_counts.unread;
            
            // Count how many rows in allFetchedRows are marked as read but weren't in the original count
            // Actually, simpler: just decrement from the last known count
            // But we need to track if we've already decremented for this read action
            
            // For now, we'll use a simpler approach: get the current count from the backend count
            // and only update if we have a valid backend count
            unreadCount = lastDashboardData.sidebar_counts.unread;
        } else {
            // Fallback: count from allFetchedRows if we don't have backend data
            allFetchedRows.forEach(row => {
                if (!row.read_status || row.read_status === '0' || row.read_status !== '1') {
                    unreadCount++;
                }
            });
        }
        
        // Update sidebar counter
        $('#efa-count-unread').text(unreadCount);
        
        // Update lastDashboardData
        if (lastDashboardData && lastDashboardData.sidebar_counts) {
            lastDashboardData.sidebar_counts.unread = unreadCount;
        }
    }

    // Initial load - fetch data to populate sidebar and table
    fetchData();

});
