/**
 * SEO Intelligence Page JavaScript
 *
 * @package Wisewand
 * @since 1.0.0
 */

        jQuery(document).ready(function($) {
            // Modal Helper Functions
            function showModal(title, body, confirmText, confirmCallback) {
                $('#modal-title').text(title);
                $('#modal-body').html(body);
                $('#modal-confirm')
                    .show()  // Always show button when opening modal
                    .text(confirmText || 'Confirm')
                    .prop('disabled', false)  // Reset button state when opening modal
                    .off('click')
                    .on('click', function() {
                        if (confirmCallback) confirmCallback();
                    });
                $('#wisewand-modal').fadeIn(200);
            }

            function closeModal() {
                $('#wisewand-modal').fadeOut(200);
            }

            function showSuccessModal(title, message) {
                showModal(title, '<div class="modal-success">' + message + '</div>', 'Close', closeModal);
            }

            function showErrorModal(title, message) {
                showModal(title, '<div class="modal-error">' + message + '</div>', 'Close', closeModal);
            }

            $('.modal-close, .modal-overlay').on('click', closeModal);

            // Compact card: Run Analysis
            $('#run-analysis-card, #run-analysis').on('click', function() {
                runRealAnalysis();
            });

            // Compact card: Add Keywords Modal
            $('#open-add-keywords-modal').on('click', function() {
                // Auto-detect language from current market selector
                const currentMarket = $('#market-selector').val();
                const [defaultLanguage, defaultLocation] = currentMarket ? currentMarket.split(':') : ['en', '2840'];

                const modalBody = `
                    <div class="modal-form-group">
                        <label>🌍 Language / Market</label>
                        <select id="modal-add-language" class="modal-select">
                            <option value="fr:2250" ${defaultLanguage === 'fr' ? 'selected' : ''}>🇫🇷 France (French)</option>
                            <option value="en:2840" ${defaultLanguage === 'en' && defaultLocation === '2840' ? 'selected' : ''}>🇺🇸 United States (English)</option>
                            <option value="de:2276" ${defaultLanguage === 'de' ? 'selected' : ''}>🇩🇪 Germany (German)</option>
                            <option value="es:2724" ${defaultLanguage === 'es' ? 'selected' : ''}>🇪🇸 Spain (Spanish)</option>
                            <option value="en:2826" ${defaultLanguage === 'en' && defaultLocation === '2826' ? 'selected' : ''}>🇬🇧 United Kingdom (English)</option>
                            <option value="en:2124" ${defaultLanguage === 'en' && defaultLocation === '2124' ? 'selected' : ''}>🇨🇦 Canada (English)</option>
                            <option value="it:2380" ${defaultLanguage === 'it' ? 'selected' : ''}>🇮🇹 Italy (Italian)</option>
                        </select>
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 6px;">
                            Auto-detected from current market. All keywords will be enriched for this language/location.
                        </p>
                    </div>
                    <div class="modal-form-group">
                        <label>💾 Paste Keywords (one per line or comma-separated)</label>
                        <textarea id="modal-add-keywords" class="modal-textarea" rows="6" placeholder="wordpress seo\ncontent marketing\nblogging tips\nbest wordpress plugins"></textarea>
                    </div>
                    <div id="modal-add-feedback"></div>
                `;

                showModal('💾 Add Keywords to Library', modalBody, '💾 Save & Enrich with SEO Data', function() {
                    const keywordsText = $('#modal-add-keywords').val().trim();
                    const [language, location] = $('#modal-add-language').val().split(':');

                    if (!keywordsText) {
                        $('#modal-add-feedback').html('<div class="modal-error">Please enter at least one keyword</div>');
                        return;
                    }

                    // Parse keywords into array
                    const keywordsArray = keywordsText.split(/[\r\n,]+/).map(k => k.trim()).filter(k => k.length > 0);

                    if (keywordsArray.length === 0) {
                        $('#modal-add-feedback').html('<div class="modal-error">Please enter at least one keyword</div>');
                        return;
                    }

                    // If less than 50 keywords, use simple processing (no progress bar needed)
                    if (keywordsArray.length < 50) {
                        $('#modal-confirm').prop('disabled', true).text('💾 Saving & Enriching...');
                        $('#modal-add-feedback').html('<div class="modal-info">⏳ Saving ' + keywordsArray.length + ' keywords for ' + $('#modal-add-language option:selected').text() + '...</div>');

                        $.ajax({
                            url: wisewandSEO.ajaxUrl,
                            type: 'POST',
                            data: {
                                action: 'wisewand_save_keywords_to_library',
                                keywords: keywordsText,
                                language_code: language,
                                location_code: parseInt(location),
                                auto_enrich: 1,
                                nonce: wisewandSEO.nonce
                            },
                            success: function(response) {
                            if (response.success) {
                                const msg = `
                                    <strong>✅ Keywords Saved!</strong><br><br>
                                    💾 Saved: ${response.data.saved_count}<br>
                                    ⏭️ Skipped (duplicates): ${response.data.skipped_count}<br><br>
                                    Keywords will appear in the table below.
                                `;
                                $('#modal-add-feedback').html('<div class="modal-success">' + msg + '</div>');
                                $('#modal-confirm').text('✅ Done').prop('disabled', false);
                                $('#modal-add-keywords').val('');

                                // Update saved keywords count if element exists
                                if (response.data.list_html) {
                                    $('.saved-keywords-count-display').html(response.data.list_html);
                                }

                                setTimeout(function() {
                                    closeModal();
                                    loadLatestSnapshot();
                                }, 2000);
                            } else {
                                $('#modal-add-feedback').html('<div class="modal-error">❌ ' + (response.data?.message || 'Failed') + '</div>');
                                $('#modal-confirm').prop('disabled', false).text('💾 Retry');
                            }
                        },
                        error: function(xhr, status, error) {
                            console.error('Add Keywords AJAX Error:', {
                                status: xhr.status,
                                statusText: xhr.statusText,
                                responseText: xhr.responseText,
                                error: error
                            });
                            let errorMsg = 'Connection error';
                            try {
                                const response = JSON.parse(xhr.responseText);
                                errorMsg = response.data?.message || response.message || errorMsg;
                            } catch(e) {
                                if (xhr.responseText) {
                                    errorMsg = xhr.responseText.substring(0, 200);
                                }
                            }
                                $('#modal-add-feedback').html('<div class="modal-error">❌ ' + errorMsg + '<br><small>Check browser console (F12) for details</small></div>');
                                $('#modal-confirm').prop('disabled', false).text('💾 Retry');
                            }
                        });
                    } else {
                        // Use batch processing with progress bar for 50+ keywords
                        $('#modal-confirm').prop('disabled', true).text('💾 Processing...');

                        const processor = new KeywordsBatchProcessor(keywordsArray, language, parseInt(location));
                        $('#modal-add-feedback').html(processor.getHTML());

                        processor.start();
                    }
                });
            });

            // Select all keywords in table
            $(document).on('change', '#select-all-keywords', function() {
                const isChecked = $(this).is(':checked');
                // CRITICAL FIX: Only select VISIBLE checkboxes (respects filters and search)
                $('.select-keyword-row:visible').prop('checked', isChecked);
                updateBulkActionsBar();
            });

            // Individual checkbox change
            $(document).on('change', '.select-keyword-row', function() {
                updateBulkActionsBar();
            });

            function updateBulkActionsBar() {
                // Count only VISIBLE checked boxes to match what user sees
                const selectedCount = $('.select-keyword-row:visible:checked').length;

                // Update both count displays
                $('.selected-count-display').text(selectedCount);

                if (selectedCount > 0) {
                    $('#bulk-actions-top, #bulk-actions-bottom').slideDown(200);
                } else {
                    $('#bulk-actions-top, #bulk-actions-bottom').slideUp(200);
                }
            }

            // Search functionality
            $('#keyword-search').on('keyup', function() {
                const searchTerm = $(this).val().toLowerCase();
                const $rows = $('.seo-table tbody tr');

                $rows.each(function() {
                    const keyword = $(this).find('.col-keyword strong').text().toLowerCase();
                    if (keyword.indexOf(searchTerm) > -1) {
                        $(this).show();
                    } else {
                        $(this).hide();
                    }
                });
            });

            // Bulk Enrich (works from both top and bottom bars) - WITH PROGRESS BAR
            $(document).on('click', '.bulk-enrich-btn', function() {
                // CRITICAL FIX: Only collect VISIBLE checked keywords (respects filters)
                const selected = $('.select-keyword-row:visible:checked').map(function() {
                    return $(this).val();
                }).get();

                if (selected.length === 0) {
                    alert('Please select keywords to enrich');
                    return;
                }

                // Create processor first to get the HTML
                const processor = new EnrichmentBatchProcessor(selected);

                // Show modal with progress UI already embedded
                const modalBody = `
                    <div style="text-align: center; color: var(--brand-white); margin-bottom: 16px;">
                        <div style="font-size: 48px; margin-bottom: 12px;">📊</div>
                        <div style="font-size: 16px; font-weight: 600; margin-bottom: 8px;">Enriching ${selected.length} Keywords</div>
                        <div style="font-size: 13px; color: var(--brand-gray-light);">
                            Please keep this window open while enrichment is in progress...
                        </div>
                    </div>
                    ${processor.getHTML()}
                `;

                // Open modal and hide confirm button immediately, then start
                $('#modal-title').text('📊 Enriching Keywords');
                $('#modal-body').html(modalBody);
                $('#modal-confirm').hide(); // Hide the button completely
                $('#wisewand-modal').fadeIn(200);

                // Start processing after modal is visible
                setTimeout(function() {
                    processor.start();
                }, 300);
            });

            // Bulk Schedule (works from both bars)
            $(document).on('click', '.bulk-schedule-btn', function() {
                // CRITICAL FIX: Only collect VISIBLE checked keywords (respects filters)
                const selected = $('.select-keyword-row:visible:checked').map(function() {
                    return $(this).val();
                }).get();

                if (selected.length === 0) return;

                const modalBody = `
                    <div class="modal-info">
                        📅 Schedule ${selected.length} keyword(s) for publication?<br><br>
                        Keywords will be added to the Editorial Calendar with smart priority-based scheduling (1 per day).
                    </div>
                `;

                showModal('📅 Schedule Keywords', modalBody, '📅 Schedule ' + selected.length, function() {
                    $('#modal-confirm').prop('disabled', true).text('📅 Scheduling...');

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_schedule_saved_keywords',
                            keyword_ids: selected,
                            nonce: wisewandSEO.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                showSuccessModal('✅ Scheduled', response.data.scheduled + ' keyword(s) scheduled! View them in the Editorial Calendar.');
                                $('.select-keyword-row:visible:checked').prop('checked', false);
                                updateBulkActionsBar();
                            } else {
                                showErrorModal('❌ Scheduling Failed', response.data?.message || 'Failed');
                            }
                        }
                    });
                });
            });

            // Bulk Delete (works from both bars)
            $(document).on('click', '.bulk-delete-btn', function() {
                // CRITICAL FIX: Only collect VISIBLE checked keywords (respects filters)
                const selected = $('.select-keyword-row:visible:checked').map(function() {
                    return $(this).val();
                }).get();

                if (selected.length === 0) return;

                let warningText = '';
                if (selected.length > 1000) {
                    warningText = '<div class="modal-info"><strong>⚠️ Large Operation:</strong><br>Deleting ' + selected.length + ' keywords will be processed in chunks to prevent timeouts.</div>';
                }

                const modalBody = `
                    ${warningText}
                    <div class="modal-error">
                        🗑️ Delete ${selected.length} keyword(s) from library?<br><br>
                        <strong>This action cannot be undone.</strong><br><br>
                        Scheduled publications for these keywords will NOT be affected.
                    </div>
                    <div id="delete-progress" style="display: none;">
                        <div style="background: #f3f4f6; border-radius: 8px; height: 8px; margin: 16px 0;">
                            <div id="delete-progress-bar" style="background: #ef4444; height: 100%; border-radius: 8px; width: 0%; transition: width 0.3s;"></div>
                        </div>
                        <div id="delete-status">Starting deletion...</div>
                    </div>
                `;

                showModal('🗑️ Delete Keywords', modalBody, '🗑️ Delete ' + selected.length, function() {
                    $('#modal-confirm').prop('disabled', true);
                    $('#delete-progress').show();

                    if (selected.length <= 100) {
                        // Small batch - delete directly
                        deleteKeywordsBatch(selected, 0, selected.length);
                    } else {
                        // Large batch - process in chunks
                        deleteKeywordsInChunks(selected);
                    }
                });
            });

            function deleteKeywordsBatch(allIds, processed, total) {
                const chunkSize = 100;
                const chunk = allIds.slice(processed, processed + chunkSize);

                if (chunk.length === 0) {
                    // All done
                    showSuccessModal('✅ Deleted', 'All ' + total + ' keyword(s) deleted successfully');
                    setTimeout(() => location.reload(), 1500);
                    return;
                }

                const progress = Math.round((processed / total) * 100);
                $('#delete-progress-bar').css('width', progress + '%');
                $('#delete-status').text('Deleting ' + (processed + 1) + '-' + Math.min(processed + chunkSize, total) + ' of ' + total + '...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_bulk_delete_saved_keywords',
                        keyword_ids: chunk,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            // Continue with next chunk
                            setTimeout(() => {
                                deleteKeywordsBatch(allIds, processed + chunkSize, total);
                            }, 500);
                        } else {
                            showErrorModal('❌ Delete Failed', 'Failed at batch ' + (Math.floor(processed / chunkSize) + 1));
                        }
                    },
                    error: function(xhr) {
                        console.error('Delete error:', xhr);
                        showErrorModal('❌ Delete Error', 'HTTP ' + xhr.status + ' - Check server logs');
                    }
                });
            }

            function deleteKeywordsInChunks(allIds) {
                deleteKeywordsBatch(allIds, 0, allIds.length);
            }

            // Delete individual keyword
            $(document).on('click', '.btn-delete-keyword', function() {
                const keywordId = $(this).data('keyword-id');
                const keyword = $(this).data('keyword');

                const modalBody = `
                    <div class="modal-error">
                        Delete keyword: <strong>"${keyword}"</strong>?<br><br>
                        This will remove it from your saved library.
                    </div>
                `;

                showModal('🗑️ Delete Keyword', modalBody, '🗑️ Delete', function() {
                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_delete_saved_keyword',
                            keyword_id: keywordId,
                            nonce: wisewandSEO.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                closeModal();
                                $('[data-keyword-id="' + keywordId + '"]').fadeOut();
                                setTimeout(() => loadLatestSnapshot(), 500);
                            }
                        }
                    });
                });
            });

            // Edit keyword inline
            $(document).on('click', '.btn-edit', function() {
                const keywordId = $(this).data('keyword-id');
                const $row = $(this).closest('tr');

                // Get current values
                const currentKeyword = $row.find('.col-keyword strong').text();
                const currentVolume = $row.find('.col-volume').data('volume') || 0;
                const currentDifficulty = $row.find('.col-difficulty').data('difficulty') || '';

                const modalBody = `
                    <div class="modal-form-group">
                        <label>Keyword</label>
                        <input type="text" id="edit-keyword" class="modal-input" value="${currentKeyword}">
                    </div>
                    <div class="modal-form-group">
                        <label>Search Volume</label>
                        <input type="number" id="edit-volume" class="modal-input" value="${currentVolume}">
                    </div>
                    <div class="modal-form-group">
                        <label>Difficulty (0-100)</label>
                        <input type="number" id="edit-difficulty" class="modal-input" value="${currentDifficulty}" min="0" max="100">
                    </div>
                `;

                showModal('✏️ Edit Keyword', modalBody, '💾 Save Changes', function() {
                    const updates = {
                        keyword: $('#edit-keyword').val(),
                        search_volume: parseInt($('#edit-volume').val()) || 0,
                        difficulty: parseInt($('#edit-difficulty').val()) || null,
                    };

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_update_saved_keyword',
                            keyword_id: keywordId,
                            updates: updates,
                            nonce: wisewandSEO.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                showSuccessModal('✅ Updated', 'Keyword updated successfully');
                                setTimeout(() => location.reload(), 1000);
                            } else {
                                showErrorModal('❌ Update Failed', response.data?.message || 'Failed');
                            }
                        }
                    });
                });
            });

            function runRealAnalysis() {
                const [language, location] = $('#market-selector').val().split(':');
                const $btn = $('#run-analysis');

                $btn.prop('disabled', true).text('🔄 Analyzing...');
                $('#analysis-status').show();

                updateProgress(10, 'Fetching current rankings...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_run_real_analysis',
                        domain: wisewandSEO.domain,
                        language_code: language,
                        location_code: parseInt(location),
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            updateProgress(100, 'Analysis complete!');
                            displayResults(response.data);
                            updateMetrics(response.data.metrics);
                        } else {
                            let errorMsg = response.data?.message || 'Unknown error';
                            if (response.data?.debug) {
                                console.log('Debug info:', response.data.debug);
                                if (!response.data.debug.credentials_configured) {
                                    errorMsg = 'Please configure your DataForSEO credentials in Settings';
                                }
                            }
                            updateProgress(0, 'Analysis failed: ' + errorMsg);
                        }
                    },
                    error: function(xhr, status, error) {
                        console.error('AJAX error:', xhr.responseText);
                        let errorMsg = 'Connection error';
                        if (xhr.status === 403) {
                            errorMsg = 'Permission denied - please check your user permissions';
                        } else if (xhr.status === 500) {
                            errorMsg = 'Server error - check the logs for details';
                        } else if (error) {
                            errorMsg += ': ' + error;
                        }
                        updateProgress(0, errorMsg);
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('🚀 Run SEO Analysis');
                        setTimeout(() => $('#analysis-status').hide(), 3000);
                    }
                });
            }

            function updateProgress(percentage, text) {
                $('#progress-fill').css('width', percentage + '%');
                $('#status-text').text(text);
            }

            function displayResults(data) {
                $('#results-content').html(data.html);
            }

            function updateMetrics(metrics) {
                $('#current-rankings').text(metrics.current_rankings || 0);
                $('#new-opportunities').text(metrics.new_opportunities || 0);
                $('#quick-wins').text(metrics.quick_wins || 0);
                $('#top-performers').text(metrics.top_performers || 0);
            }

            // Auto-load latest snapshot on page load
            loadLatestSnapshot();

            function loadLatestSnapshot() {
                const [language, location] = $('#market-selector').val().split(':');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_load_latest_snapshot',
                        domain: wisewandSEO.domain,
                        language_code: language,
                        location_code: parseInt(location),
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            // If show_empty flag is set, keep the empty state visible
                            if (response.data.show_empty) {
                                $('#initial-empty-state').show();
                                return;
                            }

                            // If we have data, display it
                            if (response.data.html) {
                                $('#initial-empty-state').hide();
                                displayResults(response.data);
                                updateMetrics(response.data.metrics);
                            }
                        }
                    }
                });
            }

            // Sortable table headers
            $(document).on('click', '.seo-table th.sortable', function() {
                const $this = $(this);
                const sortBy = $this.data('sort');
                const $table = $this.closest('table');
                const $tbody = $table.find('tbody');
                const $rows = $tbody.find('tr').toArray();

                // Toggle sort direction
                const isAsc = $this.hasClass('sort-asc');
                $table.find('th').removeClass('sort-asc sort-desc');
                $this.addClass(isAsc ? 'sort-desc' : 'sort-asc');

                // Sort rows
                $rows.sort(function(a, b) {
                    let aVal, bVal;

                    switch(sortBy) {
                        case 'keyword':
                            aVal = $(a).find('.col-keyword strong').text().toLowerCase();
                            bVal = $(b).find('.col-keyword strong').text().toLowerCase();
                            break;
                        case 'categories':
                            // Sort by categories (empty first when ascending, last when descending)
                            const aCatIds = $(a).find('.col-categories .open-category-modal').data('category-ids');
                            const bCatIds = $(b).find('.col-categories .open-category-modal').data('category-ids');

                            // Check if empty
                            const aIsEmpty = !aCatIds || aCatIds.length === 0 ||
                                           (Array.isArray(aCatIds) && aCatIds.length === 0) ||
                                           aCatIds === '[]';
                            const bIsEmpty = !bCatIds || bCatIds.length === 0 ||
                                           (Array.isArray(bCatIds) && bCatIds.length === 0) ||
                                           bCatIds === '[]';

                            // Empty sorting logic
                            if (aIsEmpty && !bIsEmpty) return isAsc ? -1 : 1; // Empty first when ascending
                            if (!aIsEmpty && bIsEmpty) return isAsc ? 1 : -1;
                            if (aIsEmpty && bIsEmpty) return 0; // Both empty

                            // Both have categories - sort by first category name alphabetically
                            const aText = $(a).find('.col-categories span').first().text().toLowerCase() || '';
                            const bText = $(b).find('.col-categories span').first().text().toLowerCase() || '';

                            aVal = aText;
                            bVal = bText;
                            break;
                        case 'position':
                            aVal = parseInt($(a).find('.col-position').data('position')) || 999;
                            bVal = parseInt($(b).find('.col-position').data('position')) || 999;
                            break;
                        case 'volume':
                            aVal = parseInt($(a).find('.col-volume').data('volume')) || 0;
                            bVal = parseInt($(b).find('.col-volume').data('volume')) || 0;
                            break;
                        case 'difficulty':
                            aVal = parseInt($(a).find('.col-difficulty').data('difficulty')) || 0;
                            bVal = parseInt($(b).find('.col-difficulty').data('difficulty')) || 0;
                            break;
                        case 'priority':
                            aVal = parseInt($(a).find('.col-priority').data('priority')) || 0;
                            bVal = parseInt($(b).find('.col-priority').data('priority')) || 0;
                            break;
                        default:
                            return 0;
                    }

                    if (aVal < bVal) return isAsc ? 1 : -1;
                    if (aVal > bVal) return isAsc ? -1 : 1;
                    return 0;
                });

                // Reattach rows
                $.each($rows, function(index, row) {
                    $tbody.append(row);
                });

                // Update sort arrow
                $table.find('.sort-arrow').text('');
                $this.find('.sort-arrow').text(isAsc ? ' ▼' : ' ▲');
            });

            // Saved Keywords: Save to library
            $('#save-keywords, #save-and-enrich').on('click', function() {
                const $btn = $(this);
                const keywords = $('#saved-keywords-input').val().trim();
                const autoEnrich = $btn.attr('id') === 'save-and-enrich';

                if (!keywords) {
                    alert('Please enter at least one keyword');
                    return;
                }

                $btn.prop('disabled', true).text(autoEnrich ? '📊 Saving & Enriching...' : '💾 Saving...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_save_keywords_to_library',
                        keywords: keywords,
                        auto_enrich: autoEnrich ? 1 : 0,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $('#saved-keywords-input').val('');
                            $('#saved-keywords-feedback').html(
                                '<div class="feedback-success">✅ Saved ' + response.data.saved_count + ' keyword(s). ' +
                                (response.data.skipped_count > 0 ? response.data.skipped_count + ' skipped (duplicates).' : '') +
                                '</div>'
                            );
                            $('#saved-keywords-list').html(response.data.list_html);

                            // Refresh results if analysis is showing
                            if ($('#results-content table').length > 0) {
                                loadLatestSnapshot();
                            }
                        } else {
                            $('#saved-keywords-feedback').html('<div class="feedback-error">❌ ' + (response.data?.message || 'Failed') + '</div>');
                        }
                    },
                    error: function() {
                        $('#saved-keywords-feedback').html('<div class="feedback-error">❌ Connection error</div>');
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text(autoEnrich ? '📊 Save & Enrich with SEO Data' : '💾 Save to Library');
                    }
                });
            });

            // Select all saved keywords (use event delegation since table is dynamically loaded)
            $(document).on('change', '#select-all-saved', function() {
                const isChecked = $(this).is(':checked');
                $('.select-saved-keyword').prop('checked', isChecked);
                console.log('Select all toggled:', isChecked, 'Found checkboxes:', $('.select-saved-keyword').length);
            });

            // Schedule single saved keyword
            $(document).on('click', '.btn-schedule-saved', function() {
                const keywordId = $(this).data('keyword-id');
                scheduleStyledKeyword(keywordId, $(this));
            });

            // Delete single saved keyword
            $(document).on('click', '.btn-delete-saved', function() {
                const keywordId = $(this).data('keyword-id');

                if (!confirm('Delete this saved keyword?')) return;

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_delete_saved_keyword',
                        keyword_id: keywordId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $('[data-keyword-id="' + keywordId + '"]').fadeOut();
                            setTimeout(() => location.reload(), 500);
                        }
                    }
                });
            });

            // Enrichment Batch Processor for Saved Keywords (Global Scope - defined here before use)
            class EnrichmentBatchProcessor {
                constructor(keywordIds) {
                    this.keywordIds = keywordIds;
                    this.batchSize = 10; // Process 10 keywords per batch (enrichment involves API calls)
                    this.currentBatch = 0;
                    this.totalBatches = Math.ceil(keywordIds.length / this.batchSize);
                    this.totalEnriched = 0;
                    this.totalFailed = 0;
                }

                getHTML() {
                    return `
                        <div id="enrich-progress-container" style="margin-top: 12px;">
                            <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(16, 185, 129, 0.2); border-radius: 16px; padding: 20px; backdrop-filter: blur(10px);">
                                <!-- Progress Bar -->
                                <div style="margin-bottom: 20px;">
                                    <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
                                        <span style="font-size: 13px; font-weight: 600; color: var(--brand-white); letter-spacing: 0.05em; text-transform: uppercase;">Enrichment Progress</span>
                                        <span id="enrich-progress-text" style="font-size: 13px; color: var(--brand-success); font-weight: 600;">0 / ${this.keywordIds.length} keywords</span>
                                    </div>
                                    <div style="background: rgba(160, 168, 184, 0.15); border-radius: 12px; height: 10px; overflow: hidden; border: 1px solid rgba(16, 185, 129, 0.2);">
                                        <div id="enrich-progress-bar" style="background: linear-gradient(90deg, var(--brand-success) 0%, var(--brand-primary) 100%); height: 100%; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(16, 185, 129, 0.5);"></div>
                                    </div>
                                </div>

                                <!-- Current Status -->
                                <div id="enrich-current-status" style="background: rgba(16, 185, 129, 0.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; border-left: 4px solid var(--brand-success); backdrop-filter: blur(10px);">
                                    <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">Starting...</div>
                                    <div id="enrich-status-detail" style="font-size: 13px; color: var(--brand-gray-light);"></div>
                                </div>

                                <!-- Progress Steps Log -->
                                <div id="enrich-progress-steps" style="height: 290px; overflow-y: auto; font-size: 12px; font-family: 'Consolas', 'Monaco', monospace; background: #0A0E27; color: #E2E8F0; padding: 16px; border-radius: 12px; line-height: 1.8; border: 1px solid rgba(16, 185, 129, 0.3); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);">
                                    <div style="color: var(--brand-success);">● Initializing enrichment process...</div>
                                    <div style="color: var(--brand-gray-light);">→ Total keywords: ${this.keywordIds.length}</div>
                                    <div style="color: var(--brand-gray-light);">→ Batch size: ${this.batchSize} keywords per batch</div>
                                    <div style="color: var(--brand-gray-light);">→ Total batches: ${this.totalBatches}</div>
                                    <div style="color: var(--brand-gray-light);">→ Fetching: search volume, difficulty, priority, intent...</div>
                                </div>
                            </div>

                            <!-- Warning at Bottom -->
                            <div style="margin-top: 12px; padding: 10px 14px; background: rgba(245, 158, 11, 0.15); border-left: 3px solid var(--brand-warning); border-radius: 8px; font-size: 11px; color: var(--brand-white); line-height: 1.5; backdrop-filter: blur(10px); border: 1px solid rgba(245, 158, 11, 0.3);">
                                ⚠️ <strong style="color: var(--brand-warning);">Keep window open</strong> - Enriching ${this.keywordIds.length} keywords with DataForSEO metrics (${this.totalBatches} batches)
                            </div>
                        </div>
                    `;
                }

                start() {
                    this.processNextBatch();
                }

                processNextBatch() {
                    if (this.currentBatch >= this.totalBatches) {
                        this.showComplete();
                        return;
                    }

                    const batchNumber = this.currentBatch + 1;
                    const startIdx = this.currentBatch * this.batchSize;
                    const endIdx = Math.min(startIdx + this.batchSize, this.keywordIds.length);
                    const batchIds = this.keywordIds.slice(startIdx, endIdx);

                    const progress = Math.round((startIdx / this.keywordIds.length) * 100);

                    $('#enrich-progress-bar').css('width', progress + '%');
                    $('#enrich-progress-text').text(`${startIdx} / ${this.keywordIds.length} keywords`);
                    $('#enrich-current-status div:first').html(`Processing batch ${batchNumber} of ${this.totalBatches}...`);
                    $('#enrich-status-detail').html(`Enriching keywords ${startIdx + 1} to ${endIdx} with SEO metrics...`);

                    this.addLog(`<span style="color: var(--brand-primary);">● Batch ${batchNumber}/${this.totalBatches}</span> - Enriching ${batchIds.length} keywords...`);

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_enrich_saved_keywords',
                            keyword_ids: batchIds,
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            if (response.success) {
                                const enriched = response.data.enriched || 0;
                                const failed = batchIds.length - enriched;

                                this.totalEnriched += enriched;
                                this.totalFailed += failed;

                                if (failed > 0) {
                                    this.addLog(`  <span style="color: var(--brand-warning);">⚠ Batch ${batchNumber}:</span> ${enriched} enriched, ${failed} failed (may already be enriched)`);
                                } else {
                                    this.addLog(`  <span style="color: var(--brand-success);">✓ Batch ${batchNumber} complete:</span> ${enriched} keywords enriched successfully`);
                                }

                                this.currentBatch++;
                                setTimeout(() => this.processNextBatch(), 500); // 500ms delay between batches
                            } else {
                                this.addLog(`  <span style="color: var(--brand-error);">✗ Batch ${batchNumber} failed:</span> ${response.data?.message || 'Unknown error'}`);
                                this.showError(response.data?.message || 'Failed to enrich batch');
                            }
                        },
                        error: (xhr, status, error) => {
                            console.error('Batch enrichment error:', xhr, error);
                            this.addLog(`  <span style="color: var(--brand-error);">✗ Batch ${batchNumber} error:</span> ${error}`);
                            this.showError('Network error. Please try again.');
                        }
                    });
                }

                addLog(message) {
                    const $log = $('#enrich-progress-steps');
                    $log.append('<div>' + message + '</div>');
                    $log.scrollTop($log[0].scrollHeight);
                }

                showComplete() {
                    $('#enrich-progress-bar').css('width', '100%').css('box-shadow', '0 0 20px rgba(16, 185, 129, 0.6)');
                    $('#enrich-progress-text').text(`${this.keywordIds.length} / ${this.keywordIds.length} keywords`);
                    $('#enrich-current-status div:first').html('✅ Enrichment Complete!');
                    $('#enrich-status-detail').html(`Total: ${this.totalEnriched} enriched successfully`);

                    this.addLog('');
                    this.addLog('<span style="color: var(--brand-success); font-weight: 600;">✅ ENRICHMENT COMPLETE!</span>');
                    this.addLog(`<span style="color: var(--brand-white);">→ Total Processed:</span> ${this.keywordIds.length} keywords`);
                    this.addLog(`<span style="color: var(--brand-success);">→ Successfully Enriched:</span> ${this.totalEnriched}`);

                    if (this.totalFailed > 0) {
                        this.addLog(`<span style="color: var(--brand-warning);">→ Failed/Already Enriched:</span> ${this.totalFailed}`);
                    }

                    $('#modal-confirm').text('✅ Done').prop('disabled', false);

                    // Reload page to show updated data
                    setTimeout(function() {
                        location.reload();
                    }, 2000);
                }

                showError(message) {
                    $('#enrich-current-status').html(`
                        <div style="font-weight: 600; color: var(--brand-error); margin-bottom: 6px; font-size: 15px;">❌ Error</div>
                        <div style="font-size: 13px; color: var(--brand-gray-light);">${message}</div>
                    `);
                    $('#modal-confirm').text('❌ Failed').prop('disabled', false);
                }
            }

            // Schedule selected keywords
            $('#schedule-selected').on('click', function() {
                const selected = $('.select-saved-keyword:checked').map(function() {
                    return $(this).val();
                }).get();

                if (selected.length === 0) {
                    alert('Please select keywords to schedule');
                    return;
                }

                if (!confirm('📅 Schedule ' + selected.length + ' keyword(s) for publication?')) {
                    return;
                }

                const $btn = $(this);
                $btn.prop('disabled', true).text('📅 Scheduling...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_schedule_saved_keywords',
                        keyword_ids: selected,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            alert('✅ Scheduled ' + response.data.scheduled + ' keyword(s)!\n\nView them in the Editorial Calendar.');
                        } else {
                            alert('❌ ' + (response.data?.message || 'Failed'));
                        }
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('📅 Schedule Selected');
                    }
                });
            });

            // Delete selected keywords
            $('#delete-selected').on('click', function() {
                const selected = $('.select-saved-keyword:checked').map(function() {
                    return $(this).val();
                }).get();

                if (selected.length === 0) {
                    alert('Please select keywords to delete');
                    return;
                }

                if (!confirm('🗑️ Delete ' + selected.length + ' keyword(s)?\n\nThis action cannot be undone.')) {
                    return;
                }

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_bulk_delete_saved_keywords',
                        keyword_ids: selected,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            alert('✅ Deleted ' + response.data.deleted + ' keyword(s)');
                            location.reload();
                        }
                    }
                });
            });

            function scheduleStyledKeyword(keywordId, $btn) {
                // First, get the keyword text
                const keyword = $btn.closest('tr').find('.col-keyword strong').text();

                $btn.prop('disabled', true).text('⏳');

                // Check for cannibalization before scheduling
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_check_cannibalization',
                        keyword: keyword,
                        keyword_id: keywordId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success && response.data.has_warnings) {
                            // Show warning modal
                            showCannibalizationWarning(keyword, keywordId, response.data.warnings, $btn);
                        } else {
                            // No warnings, proceed directly
                            proceedWithScheduling(keywordId, $btn);
                        }
                    },
                    error: function() {
                        // If check fails, proceed anyway (don't block user)
                        proceedWithScheduling(keywordId, $btn);
                    }
                });
            }

            function proceedWithScheduling(keywordId, $btn) {
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_schedule_saved_keyword',
                        keyword_id: keywordId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $btn.text('✓').css('background', '#6b7280');
                            alert('✅ Scheduled for ' + response.data.publication_date);
                        } else {
                            alert('❌ ' + (response.data?.message || 'Failed'));
                            $btn.prop('disabled', false).text('📅');
                        }
                    },
                    error: function() {
                        $btn.prop('disabled', false).text('📅');
                    }
                });
            }

            function showCannibalizationWarning(keyword, keywordId, warnings, $originalBtn) {
                const calendarWarnings = warnings.calendar || [];
                const postsWarnings = warnings.posts || [];
                const clustersWarnings = warnings.clusters || [];

                let warningsHTML = '';

                // Calendar conflicts
                if (calendarWarnings.length > 0) {
                    warningsHTML += '<div style="margin-bottom: 16px;"><div style="font-weight: 600; color: var(--brand-warning); margin-bottom: 8px;">📅 Similar Keywords in Calendar:</div>';
                    calendarWarnings.forEach(w => {
                        warningsHTML += `
                            <div style="padding: 8px 12px; background: rgba(245, 158, 11, 0.1); border-left: 3px solid var(--brand-warning); border-radius: 6px; margin-bottom: 6px;">
                                <div style="font-size: 13px; color: var(--brand-white);">"${escapeHtml(w.keyword)}"</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light); margin-top: 2px;">
                                    ${w.similarity}% similar | Scheduled: ${w.date} | Status: ${w.status}
                                </div>
                            </div>
                        `;
                    });
                    warningsHTML += '</div>';
                }

                // Published posts conflicts
                if (postsWarnings.length > 0) {
                    warningsHTML += '<div style="margin-bottom: 16px;"><div style="font-weight: 600; color: var(--brand-error); margin-bottom: 8px;">📝 Similar Keywords in Published Posts:</div>';
                    postsWarnings.forEach(w => {
                        warningsHTML += `
                            <div style="padding: 8px 12px; background: rgba(239, 68, 68, 0.1); border-left: 3px solid var(--brand-error); border-radius: 6px; margin-bottom: 6px;">
                                <div style="font-size: 13px; color: var(--brand-white);">"${escapeHtml(w.title)}"</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light); margin-top: 2px;">
                                    ${w.similarity}% similar | Published: ${w.date.substring(0, 10)} | <a href="${w.edit_url}" target="_blank" style="color: var(--brand-primary);">Edit Post →</a>
                                </div>
                            </div>
                        `;
                    });
                    warningsHTML += '</div>';
                }

                // Cluster conflicts
                if (clustersWarnings.length > 0) {
                    warningsHTML += '<div style="margin-bottom: 16px;"><div style="font-weight: 600; color: var(--brand-purple); margin-bottom: 8px;">🔗 Part of Keyword Cluster:</div>';
                    clustersWarnings.forEach(w => {
                        warningsHTML += `
                            <div style="padding: 8px 12px; background: rgba(139, 92, 246, 0.1); border-left: 3px solid var(--brand-purple); border-radius: 6px;">
                                <div style="font-size: 13px; color: var(--brand-white);">Primary: "${escapeHtml(w.primary_keyword)}"</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light); margin-top: 2px;">
                                    ${w.variant_count} variants in cluster
                                </div>
                            </div>
                        `;
                    });
                    warningsHTML += '</div>';
                }

                const modalBody = `
                    <div style="text-align: center; color: var(--brand-white); margin-bottom: 20px;">
                        <div style="font-size: 48px; margin-bottom: 12px;">⚠️</div>
                        <div style="font-size: 18px; font-weight: 700; margin-bottom: 8px;">Cannibalization Risk Detected</div>
                        <div style="font-size: 13px; color: var(--brand-gray-light);">
                            Scheduling "${keyword}" may compete with existing content
                        </div>
                    </div>

                    ${warningsHTML}

                    <div style="background: rgba(0, 188, 212, 0.1); padding: 12px; border-radius: 8px; border-left: 3px solid var(--brand-primary); margin-top: 16px;">
                        <div style="font-size: 12px; color: var(--brand-white); font-weight: 600; margin-bottom: 4px;">💡 Recommendation:</div>
                        <div style="font-size: 11px; color: var(--brand-gray-light); line-height: 1.6;">
                            Consider reviewing similar keywords before scheduling to avoid content cannibalization.
                            You can still proceed if this keyword targets a different intent or angle.
                        </div>
                    </div>
                `;

                showModal('⚠️ Cannibalization Warning', modalBody, 'Schedule Anyway', function() {
                    // User confirmed, proceed with scheduling
                    proceedWithScheduling(keywordId, $originalBtn);
                    closeModal();
                });
            }

            // Combined filter functionality
            function applyKeywordFilters() {
                const sourceFilter = $('#keyword-filter').val();
                const languageFilter = $('#language-filter').val();
                const $rows = $('.seo-table tbody tr');

                $rows.each(function() {
                    const $row = $(this);
                    let show = true;

                    // Source filter
                    if (sourceFilter !== 'all') {
                        switch(sourceFilter) {
                            case 'current':
                            case 'opportunities':
                            case 'saved':
                            case 'seed':
                            case 'ideas':
                            case 'competitor_spy':
                                if ($row.attr('data-type') !== sourceFilter) show = false;
                                break;
                            case 'quick-wins':
                                const pos = parseInt($row.find('[data-position]').data('position')) || 999;
                                if (pos < 11 || pos > 20) show = false;
                                break;
                            case 'high-volume':
                                const vol = parseInt($row.find('[data-volume]').data('volume')) || 0;
                                if (vol < 1000) show = false;
                                break;
                        }
                    }

                    // Language filter
                    if (languageFilter !== 'all' && show) {
                        const rowLang = $row.attr('data-language') || 'en';
                        if (rowLang !== languageFilter) show = false;
                    }

                    $row.toggle(show);
                });
            }

            $('#keyword-filter').on('change', applyKeywordFilters);
            $('#language-filter').on('change', applyKeywordFilters);

            // Discover keywords button
            $('#discover-keywords').on('click', function() {
                const $btn = $(this);
                const [language, location] = $('#market-selector').val().split(':');

                $btn.prop('disabled', true).text('🔍 Discovering...');
                $('#discovery-results').html('<div class="loading">Loading new keyword opportunities...</div>');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_discover_keywords',
                        domain: wisewandSEO.domain,
                        language_code: language,
                        location_code: parseInt(location),
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $('#discovery-results').html(response.data.html);
                        } else {
                            $('#discovery-results').html('<div class="error-message">❌ ' + (response.data?.message || 'Discovery failed') + '</div>');
                        }
                    },
                    error: function() {
                        $('#discovery-results').html('<div class="error-message">❌ Connection error</div>');
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('🔍 Find New Keywords');
                    }
                });
            });

            // Add discovered keyword to calendar
            $(document).on('click', '.btn-add-discovery', function() {
                const $btn = $(this);
                const keywordData = JSON.parse($btn.attr('data-keyword'));

                $btn.prop('disabled', true).text('Adding...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_schedule_keyword',
                        keyword_data: keywordData,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $btn.text('✓ Added').css('background', '#6b7280');
                            alert('✅ Scheduled for ' + response.data.publication_date);
                        } else {
                            alert('❌ ' + (response.data?.message || 'Failed'));
                            $btn.prop('disabled', false).text('➕ Add');
                        }
                    },
                    error: function() {
                        $btn.prop('disabled', false).text('➕ Add');
                    }
                });
            });

            // Keyword Ideas Progress Manager (Global Scope)
            class KeywordIdeasProgress {
                    constructor(totalSeeds, seedsText, language, location) {
                        this.totalSeeds = totalSeeds;
                        this.seedsText = seedsText;
                        this.language = language;
                        this.location = location;
                        this.currentSeed = 0;
                        this.stats = {
                            totalIdeas: 0,
                            totalEnriched: 0,
                            totalSaved: 0,
                            totalSkipped: 0
                        };
                    }

                    getHTML() {
                        return `
                            <div id="ideas-progress-container" style="margin-top: 12px;">
                                <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(0, 188, 212, 0.2); border-radius: 16px; padding: 20px; backdrop-filter: blur(10px);">
                                    <!-- Progress Bar -->
                                    <div style="margin-bottom: 20px;">
                                        <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
                                            <span style="font-size: 13px; font-weight: 600; color: var(--brand-white); letter-spacing: 0.05em; text-transform: uppercase;">Overall Progress</span>
                                            <span id="overall-progress-text" style="font-size: 13px; color: var(--brand-primary); font-weight: 600;">0 / ${this.totalSeeds} seeds</span>
                                        </div>
                                        <div style="background: rgba(160, 168, 184, 0.15); border-radius: 12px; height: 10px; overflow: hidden; border: 1px solid rgba(0, 188, 212, 0.2);">
                                            <div id="ideas-progress-bar" style="background: linear-gradient(90deg, var(--brand-primary) 0%, var(--brand-success) 100%); height: 100%; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(0, 188, 212, 0.5);"></div>
                                        </div>
                                    </div>

                                    <!-- Current Status -->
                                    <div id="current-status" style="background: rgba(0, 188, 212, 0.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; border-left: 4px solid var(--brand-primary); backdrop-filter: blur(10px);">
                                        <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">Starting process...</div>
                                        <div id="status-detail" style="font-size: 13px; color: var(--brand-gray-light);"></div>
                                    </div>

                                    <!-- Progress Steps Log -->
                                    <div id="progress-steps" style="height: 290px; overflow-y: auto; font-size: 12px; font-family: 'Consolas', 'Monaco', monospace; background: #0A0E27; color: #E2E8F0; padding: 16px; border-radius: 12px; line-height: 1.8; border: 1px solid rgba(0, 188, 212, 0.3); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);">
                                        <div style="color: var(--brand-primary);">● Initializing keyword enrichment...</div>
                                    </div>
                                </div>

                                <!-- Discreet Warning at Bottom -->
                                <div style="margin-top: 12px; padding: 10px 14px; background: rgba(245, 158, 11, 0.15); border-left: 3px solid var(--brand-warning); border-radius: 8px; font-size: 11px; color: var(--brand-white); line-height: 1.5; backdrop-filter: blur(10px); border: 1px solid rgba(245, 158, 11, 0.3);">
                                    ⚠️ <strong style="color: var(--brand-warning);">Keep window open</strong> - Enriching keywords with DataForSEO volume, difficulty & priority metrics
                                </div>
                            </div>
                        `;
                    }

                    start() {
                        this.processNextSeed();
                    }

                    processNextSeed() {
                        if (this.currentSeed >= this.totalSeeds) {
                            this.showComplete();
                            return;
                        }

                        const seedNumber = this.currentSeed + 1;
                        const progress = Math.round((this.currentSeed / this.totalSeeds) * 100);

                        $('#ideas-progress-bar').css('width', progress + '%');
                        $('#overall-progress-text').text(`${seedNumber} / ${this.totalSeeds} seeds`);

                        $.ajax({
                            url: wisewandSEO.ajaxUrl,
                            type: 'POST',
                            data: {
                                action: 'wisewand_get_keyword_ideas',
                                seeds: this.seedsText,
                                seed_index: this.currentSeed,
                                language_code: this.language,
                                location_code: this.location,
                                nonce: wisewandSEO.nonce
                            },
                            success: (response) => {
                                if (response.success) {
                                    this.updateProgress(response.data);
                                    this.stats.totalIdeas += response.data.ideas_found || 0;
                                    this.stats.totalEnriched += response.data.ideas_enriched || 0;
                                    this.stats.totalSaved += response.data.ideas_saved || 0;
                                    this.stats.totalSkipped += response.data.ideas_skipped || 0;

                                    this.currentSeed++;
                                    setTimeout(() => this.processNextSeed(), 500);
                                } else {
                                    this.showError(response.data?.message || 'Unknown error');
                                }
                            },
                            error: (xhr) => {
                                this.showError('HTTP ' + xhr.status + ' - Connection failed');
                            }
                        });
                    }

                    updateProgress(data) {
                        const seed = data.seed || 'unknown';
                        const seedNum = data.seed_number || 0;

                        // Update current status
                        $('#current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">
                                Seed ${seedNum}/${data.total_seeds}: <span style="color: var(--brand-primary);">${this.escapeHtml(seed)}</span>
                            </div>
                            <div style="font-size: 13px; color: var(--brand-gray-light);">
                                <span style="color: var(--brand-primary); font-weight: 600;">${data.ideas_found}</span> ideas found •
                                <span style="color: var(--brand-success); font-weight: 600;">${data.ideas_enriched}</span> enriched •
                                <span style="color: var(--brand-purple); font-weight: 600;">${data.ideas_saved}</span> saved
                            </div>
                        `);

                        // Append detailed steps to log
                        if (data.steps && Array.isArray(data.steps)) {
                            const $log = $('#progress-steps');
                            if ($log.length && $log[0]) {
                                const logWasAtBottom = $log[0].scrollHeight - $log.scrollTop() <= $log.outerHeight() + 50;

                                data.steps.forEach(step => {
                                    const logEntry = this.formatStepLog(step, seedNum);
                                    $log.append(logEntry);
                                });

                                // Auto-scroll to bottom if user was already there
                                if (logWasAtBottom) {
                                    $log.scrollTop($log[0].scrollHeight);
                                }
                            }
                        }
                    }

                    formatStepLog(step, seedNum) {
                        const icons = {
                            started: '▸',
                            processing: '⋯',
                            success: '✓',
                            error: '✗',
                            warning: '⚠',
                            skipped: '○'
                        };

                        const colors = {
                            started: '#00BCD4',
                            processing: '#F59E0B',
                            success: '#10B981',
                            error: '#EF4444',
                            warning: '#F59E0B',
                            skipped: '#A0A8B8'
                        };

                        const icon = icons[step.status] || '●';
                        const color = colors[step.status] || '#E2E8F0';

                        let message = step.message;

                        // Add endpoint info if available
                        if (step.endpoint) {
                            message += ` <span style="color: #8B5CF6; font-size: 10px;">[${step.endpoint}]</span>`;
                        }

                        // Add progress info for enrich steps
                        if (step.progress) {
                            message += ` <span style="color: #A0A8B8;">(${step.progress.current}/${step.progress.total})</span>`;
                        }

                        return `<div style="color: ${color};">${icon} ${this.escapeHtml(message)}</div>`;
                    }

                    showComplete() {
                        $('#ideas-progress-bar').css('width', '100%').css('box-shadow', '0 0 20px rgba(16, 185, 129, 0.6)');
                        $('#overall-progress-text').text(`${this.totalSeeds} / ${this.totalSeeds} seeds completed`);

                        $('#current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-success); margin-bottom: 8px; font-size: 16px;">✅ All Keywords Enriched!</div>
                            <div style="font-size: 13px; color: var(--brand-white);">
                                <span style="color: var(--brand-primary); font-weight: 600;">📊 ${this.stats.totalIdeas}</span> ideas found •
                                <span style="color: var(--brand-success); font-weight: 600;">✓ ${this.stats.totalEnriched}</span> enriched •
                                <span style="color: var(--brand-purple); font-weight: 600;">💾 ${this.stats.totalSaved}</span> saved •
                                <span style="color: var(--brand-gray-light);">○ ${this.stats.totalSkipped}</span> duplicates
                            </div>
                        `).css('border-left-color', 'var(--brand-success)');

                        const $log = $('#progress-steps');
                        if ($log.length && $log[0]) {
                            $log.append(`<div style="color: var(--brand-success); margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(0, 188, 212, 0.3); font-weight: 600;">✓ Process completed - All keywords enriched with volume, difficulty & priority data!</div>`);
                            $log.scrollTop($log[0].scrollHeight);
                        }

                        $('#modal-confirm').text('✅ Done').prop('disabled', false);

                        setTimeout(() => {
                            closeModal();
                            loadLatestSnapshot();
                        }, 2500);
                    }

                    showError(message) {
                        $('#current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-error); margin-bottom: 6px; font-size: 15px;">❌ Error Occurred</div>
                            <div style="font-size: 13px; color: var(--brand-white);">${this.escapeHtml(message)}</div>
                        `).css('border-left-color', 'var(--brand-error)');

                        const $log = $('#progress-steps');
                        if ($log.length && $log[0]) {
                            $log.append(`<div style="color: var(--brand-error); font-weight: 600;">✗ ERROR: ${this.escapeHtml(message)}</div>`);
                            $log.scrollTop($log[0].scrollHeight);
                        }

                        $('#modal-confirm').prop('disabled', false).text('🔍 Retry');
                    }

                    escapeHtml(text) {
                        const div = document.createElement('div');
                        div.textContent = text;
                        return div.innerHTML;
                    }
                }

            // Get Keyword Ideas - Show Modal
            $('#get-keyword-ideas, #get-keyword-ideas-empty').on('click', function() {
                const defaultSeeds = $('#keyword-ideas-seeds').val() || '';

                const modalBody = `
                    <div class="modal-form-group">
                        <label>🔍 Enter Main Topics (one per line or comma-separated)</label>
                        <textarea id="modal-keyword-seeds" class="modal-textarea" rows="3" placeholder="wordpress seo\ncontent marketing\nblogging tips">${defaultSeeds}</textarea>
                        <p style="font-size: 11px; color: #94a3b8; margin-top: 6px;">
                            Each seed fetches 10 best ideas. Processed sequentially with real-time progress.
                        </p>
                    </div>
                    <div class="modal-form-group">
                        <label>🌍 Target Market</label>
                        <select id="modal-keyword-location" class="modal-select">
                            <option value="fr:2250">🇫🇷 France (French)</option>
                            <option value="en:2840" selected>🇺🇸 United States (English)</option>
                            <option value="de:2276">🇩🇪 Germany (German)</option>
                            <option value="es:2724">🇪🇸 Spain (Spanish)</option>
                            <option value="en:2826">🇬🇧 United Kingdom (English)</option>
                            <option value="en:2124">🇨🇦 Canada (English)</option>
                        </select>
                    </div>
                    <div id="modal-feedback"></div>
                `;

                showModal('🔍 Get Keyword Ideas', modalBody, '🔍 Fetch Keyword Ideas', function() {
                    const seeds = $('#modal-keyword-seeds').val().trim();
                    const [language, location] = $('#modal-keyword-location').val().split(':');

                    if (!seeds) {
                        $('#modal-feedback').html('<div class="modal-error">Please enter at least one seed keyword</div>');
                        return;
                    }

                    const seedArray = seeds.split(/[\r\n,]+/).map(s => s.trim()).filter(s => s);

                    $('#modal-confirm').prop('disabled', true).text('🔍 Processing...');

                    const progressUI = new KeywordIdeasProgress(seedArray.length, seeds, language, parseInt(location));
                    $('#modal-feedback').html(progressUI.getHTML());

                    progressUI.start();
                });
            });

            // Keywords Batch Processor for Add to Library (Global Scope)
            class KeywordsBatchProcessor {
                constructor(keywordsArray, language, location) {
                    this.keywordsArray = keywordsArray;
                    this.language = language;
                    this.location = location;
                    this.batchSize = 50; // Process 50 keywords per batch
                    this.currentBatch = 0;
                    this.totalBatches = Math.ceil(keywordsArray.length / this.batchSize);
                    this.totalSaved = 0;
                    this.totalSkipped = 0;
                    this.totalFailed = 0;
                }

                getHTML() {
                    return `
                        <div id="batch-progress-container" style="margin-top: 12px;">
                            <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(139, 92, 246, 0.2); border-radius: 16px; padding: 20px; backdrop-filter: blur(10px);">
                                <!-- Progress Bar -->
                                <div style="margin-bottom: 20px;">
                                    <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
                                        <span style="font-size: 13px; font-weight: 600; color: var(--brand-white); letter-spacing: 0.05em; text-transform: uppercase;">Saving Progress</span>
                                        <span id="batch-progress-text" style="font-size: 13px; color: var(--brand-purple); font-weight: 600;">0 / ${this.keywordsArray.length} keywords</span>
                                    </div>
                                    <div style="background: rgba(160, 168, 184, 0.15); border-radius: 12px; height: 10px; overflow: hidden; border: 1px solid rgba(139, 92, 246, 0.2);">
                                        <div id="batch-progress-bar" style="background: linear-gradient(90deg, var(--brand-purple) 0%, var(--brand-primary) 100%); height: 100%; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(139, 92, 246, 0.5);"></div>
                                    </div>
                                </div>

                                <!-- Current Status -->
                                <div id="batch-current-status" style="background: rgba(139, 92, 246, 0.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; border-left: 4px solid var(--brand-purple); backdrop-filter: blur(10px);">
                                    <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">Starting...</div>
                                    <div id="batch-status-detail" style="font-size: 13px; color: var(--brand-gray-light);"></div>
                                </div>

                                <!-- Progress Steps Log -->
                                <div id="batch-progress-steps" style="height: 290px; overflow-y: auto; font-size: 12px; font-family: 'Consolas', 'Monaco', monospace; background: #0A0E27; color: #E2E8F0; padding: 16px; border-radius: 12px; line-height: 1.8; border: 1px solid rgba(139, 92, 246, 0.3); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);">
                                    <div style="color: var(--brand-purple);">● Initializing batch processing...</div>
                                    <div style="color: var(--brand-gray-light);">→ Total keywords: ${this.keywordsArray.length}</div>
                                    <div style="color: var(--brand-gray-light);">→ Batch size: ${this.batchSize} keywords per batch</div>
                                    <div style="color: var(--brand-gray-light);">→ Total batches: ${this.totalBatches}</div>
                                </div>
                            </div>

                            <!-- Warning at Bottom -->
                            <div style="margin-top: 12px; padding: 10px 14px; background: rgba(245, 158, 11, 0.15); border-left: 3px solid var(--brand-warning); border-radius: 8px; font-size: 11px; color: var(--brand-white); line-height: 1.5; backdrop-filter: blur(10px); border: 1px solid rgba(245, 158, 11, 0.3);">
                                ⚠️ <strong style="color: var(--brand-warning);">Keep window open</strong> - Processing ${this.keywordsArray.length} keywords in ${this.totalBatches} batches
                            </div>
                        </div>
                    `;
                }

                start() {
                    this.processNextBatch();
                }

                processNextBatch() {
                    if (this.currentBatch >= this.totalBatches) {
                        this.showComplete();
                        return;
                    }

                    const batchNumber = this.currentBatch + 1;
                    const startIdx = this.currentBatch * this.batchSize;
                    const endIdx = Math.min(startIdx + this.batchSize, this.keywordsArray.length);
                    const batchKeywords = this.keywordsArray.slice(startIdx, endIdx);

                    const progress = Math.round((startIdx / this.keywordsArray.length) * 100);

                    // CRITICAL FIX: Only auto-enrich for small batches (< 50 keywords total)
                    // Large batches: auto_enrich causes timeout (each keyword = 1 API call + 500ms delay)
                    // 100 keywords × 500ms = 50+ seconds, exceeds PHP timeout
                    const shouldAutoEnrich = this.keywordsArray.length < 50 ? 1 : 0;

                    $('#batch-progress-bar').css('width', progress + '%');
                    $('#batch-progress-text').text(`${startIdx} / ${this.keywordsArray.length} keywords`);
                    $('#batch-current-status div:first').html(`Processing batch ${batchNumber} of ${this.totalBatches}...`);
                    $('#batch-status-detail').html(`Saving keywords ${startIdx + 1} to ${endIdx}...`);

                    this.addLog(`<span style="color: var(--brand-primary);">● Batch ${batchNumber}/${this.totalBatches}</span> - Processing ${batchKeywords.length} keywords...`);

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_save_keywords_to_library',
                            keywords: batchKeywords.join('\n'),
                            language_code: this.language,
                            location_code: this.location,
                            auto_enrich: shouldAutoEnrich,
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            // Validate response structure
                            if (!response || typeof response !== 'object') {
                                console.error('Invalid response format:', response);
                                this.addLog(`  <span style="color: var(--brand-error);">✗ Batch ${batchNumber} error:</span> Invalid response format`);
                                this.showError('Invalid server response. Please try again.');
                                return;
                            }

                            if (response.success) {
                                // Validate response.data exists and has required fields
                                if (!response.data || typeof response.data !== 'object') {
                                    console.error('Response missing data object:', response);
                                    this.addLog(`  <span style="color: var(--brand-error);">✗ Batch ${batchNumber} error:</span> Invalid response data`);
                                    this.showError('Invalid server response data. Please try again.');
                                    return;
                                }

                                const savedCount = parseInt(response.data.saved_count) || 0;
                                const skippedCount = parseInt(response.data.skipped_count) || 0;
                                const failedCount = parseInt(response.data.failed_count) || 0;

                                this.totalSaved += savedCount;
                                this.totalSkipped += skippedCount;
                                this.totalFailed += failedCount;

                                // Log with failure count if any
                                if (failedCount > 0) {
                                    this.addLog(`  <span style="color: var(--brand-warning);">⚠ Batch ${batchNumber} complete:</span> ${savedCount} saved, ${skippedCount} skipped, ${failedCount} failed`);
                                } else {
                                    this.addLog(`  <span style="color: var(--brand-success);">✓ Batch ${batchNumber} complete:</span> ${savedCount} saved, ${skippedCount} skipped`);
                                }

                                this.currentBatch++;
                                setTimeout(() => this.processNextBatch(), 300);
                            } else {
                                const errorMessage = (response.data && response.data.message) || 'Unknown error';
                                this.addLog(`  <span style="color: var(--brand-error);">✗ Batch ${batchNumber} failed:</span> ${errorMessage}`);
                                this.showError(errorMessage);
                            }
                        },
                        error: (xhr, status, error) => {
                            console.error('Batch save error:', xhr, error);
                            this.addLog(`  <span style="color: var(--brand-error);">✗ Batch ${batchNumber} error:</span> ${error}`);
                            this.showError('Network error. Please try again.');
                        }
                    });
                }

                addLog(message) {
                    const $log = $('#batch-progress-steps');
                    $log.append('<div>' + message + '</div>');
                    $log.scrollTop($log[0].scrollHeight);
                }

                showComplete() {
                    $('#batch-progress-bar').css('width', '100%').css('box-shadow', '0 0 20px rgba(139, 92, 246, 0.6)');
                    $('#batch-progress-text').text(`${this.keywordsArray.length} / ${this.keywordsArray.length} keywords`);
                    $('#batch-current-status div:first').html('✅ All Batches Complete!');
                    $('#batch-status-detail').html(`Total: ${this.totalSaved} saved, ${this.totalSkipped} skipped (duplicates), ${this.totalFailed} failed`);

                    this.addLog('');
                    this.addLog('<span style="color: var(--brand-success); font-weight: 600;">✅ COMPLETE!</span>');
                    this.addLog(`<span style="color: var(--brand-white);">→ Total Processed:</span> ${this.keywordsArray.length} keywords`);
                    this.addLog(`<span style="color: var(--brand-success);">→ Successfully Saved:</span> ${this.totalSaved}`);
                    this.addLog(`<span style="color: var(--brand-warning);">→ Skipped (duplicates):</span> ${this.totalSkipped}`);
                    if (this.totalFailed > 0) {
                        this.addLog(`<span style="color: var(--brand-error);">→ Failed:</span> ${this.totalFailed}`);
                    }

                    $('#modal-confirm').text('✅ Done').prop('disabled', false);

                    // Refresh the keywords list
                    setTimeout(function() {
                        loadLatestSnapshot();
                    }, 1500);

                    setTimeout(function() {
                        closeModal();
                    }, 3000);
                }

                showError(message) {
                    $('#batch-current-status').html(`
                        <div style="font-weight: 600; color: var(--brand-error); margin-bottom: 6px; font-size: 15px;">❌ Error</div>
                        <div style="font-size: 13px; color: var(--brand-gray-light);">${message}</div>
                    `);
                    $('#modal-confirm').text('❌ Failed').prop('disabled', false);
                }
            }

            // Competitor Spy Progress Manager (Global Scope)
            class CompetitorSpyProgress {
                    constructor(competitors, analysisType, language, location, filters, userDomain) {
                        this.competitors = competitors;
                        this.analysisType = analysisType;
                        this.language = language;
                        this.location = location;
                        this.filters = filters;
                        this.userDomain = userDomain;
                        this.currentStep = 0;
                        this.totalSteps = 0;
                        this.results = null;
                    }

                    getHTML() {
                        return `
                            <div id="spy-progress-container" style="margin-top: 12px;">
                                <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(0, 188, 212, 0.2); border-radius: 16px; padding: 20px; backdrop-filter: blur(10px);">
                                    <!-- Progress Bar -->
                                    <div style="margin-bottom: 20px;">
                                        <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
                                            <span style="font-size: 13px; font-weight: 600; color: var(--brand-white); letter-spacing: 0.05em; text-transform: uppercase;">Analysis Progress</span>
                                            <span id="spy-progress-text" style="font-size: 13px; color: var(--brand-primary); font-weight: 600;">Initializing...</span>
                                        </div>
                                        <div style="background: rgba(160, 168, 184, 0.15); border-radius: 12px; height: 10px; overflow: hidden; border: 1px solid rgba(0, 188, 212, 0.2);">
                                            <div id="spy-progress-bar" style="background: linear-gradient(90deg, var(--brand-primary) 0%, var(--brand-purple) 100%); height: 100%; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(139, 92, 246, 0.5);"></div>
                                        </div>
                                    </div>

                                    <!-- Current Status -->
                                    <div id="spy-current-status" style="background: rgba(139, 92, 246, 0.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; border-left: 4px solid var(--brand-purple); backdrop-filter: blur(10px);">
                                        <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">Starting analysis...</div>
                                        <div id="spy-status-detail" style="font-size: 13px; color: var(--brand-gray-light);"></div>
                                    </div>

                                    <!-- Progress Steps Log -->
                                    <div id="spy-progress-steps" style="height: 290px; overflow-y: auto; font-size: 12px; font-family: 'Consolas', 'Monaco', monospace; background: #0A0E27; color: #E2E8F0; padding: 16px; border-radius: 12px; line-height: 1.8; border: 1px solid rgba(139, 92, 246, 0.3); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);">
                                        <div style="color: var(--brand-purple);">● Initializing competitor analysis...</div>
                                    </div>
                                </div>

                                <!-- Discreet Warning -->
                                <div style="margin-top: 12px; padding: 10px 14px; background: rgba(139, 92, 246, 0.15); border-left: 3px solid var(--brand-purple); border-radius: 8px; font-size: 11px; color: var(--brand-white); line-height: 1.5; backdrop-filter: blur(10px); border: 1px solid rgba(139, 92, 246, 0.3);">
                                    🕵️ <strong style="color: var(--brand-purple);">Keep window open</strong> - Analyzing ${this.competitors.length} competitor(s) with DataForSEO
                                </div>
                            </div>
                        `;
                    }

                    start() {
                        this.analyzeCompetitors();
                    }

                    analyzeCompetitors() {
                        $.ajax({
                            url: wisewandSEO.ajaxUrl,
                            type: 'POST',
                            dataType: 'json',
                            data: {
                                action: 'wisewand_spy_competitors',
                                competitors: JSON.stringify(this.competitors),
                                analysis_type: this.analysisType,
                                language_code: this.language,
                                location_code: this.location,
                                filters: JSON.stringify(this.filters),
                                user_domain: this.userDomain,
                                nonce: wisewandSEO.nonce
                            },
                            success: (response) => {
                                console.log('Competitor spy response:', response);

                                if (response && response.success) {
                                    this.handleProgress(response.data);
                                } else {
                                    this.showError(response?.data?.message || 'Analysis failed');
                                }
                            },
                            error: (xhr, status, error) => {
                                console.error('Competitor spy AJAX error:', xhr.responseText);

                                // Try to parse error response
                                let errorMsg = 'Connection failed';
                                try {
                                    const response = JSON.parse(xhr.responseText);
                                    errorMsg = response.data?.message || response.message || errorMsg;
                                } catch(e) {
                                    errorMsg = 'HTTP ' + xhr.status + ': ' + (error || 'Unknown error');
                                }

                                this.showError(errorMsg);
                            }
                        });
                    }

                    handleProgress(data) {
                        const progress = data.progress || {};
                        const steps = data.steps || [];

                        // Update progress bar
                        if (progress.percent !== undefined) {
                            $('#spy-progress-bar').css('width', progress.percent + '%');
                            $('#spy-progress-text').text(progress.text || 'Processing...');
                        }

                        // Update current status
                        if (progress.current_task) {
                            $('#spy-current-status').html(`
                                <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">
                                    ${this.escapeHtml(progress.current_task)}
                                </div>
                                <div style="font-size: 13px; color: var(--brand-gray-light);">
                                    ${this.escapeHtml(progress.detail || '')}
                                </div>
                            `);
                        }

                        // Append steps to log
                        const $log = $('#spy-progress-steps');
                        steps.forEach(step => {
                            $log.append(this.formatStepLog(step));
                        });
                        $log.scrollTop($log[0].scrollHeight);

                        // Check if complete
                        if (data.completed) {
                            this.showResults(data.results);
                        }
                    }

                    formatStepLog(step) {
                        const icons = {
                            started: '▸',
                            processing: '⋯',
                            success: '✓',
                            error: '✗',
                            info: '●'
                        };

                        const colors = {
                            started: '#8B5CF6',
                            processing: '#F59E0B',
                            success: '#10B981',
                            error: '#EF4444',
                            info: '#00BCD4'
                        };

                        const icon = icons[step.status] || '●';
                        const color = colors[step.status] || '#E2E8F0';
                        let message = step.message;

                        if (step.endpoint) {
                            message += ` <span style="color: #8B5CF6; font-size: 10px;">[${step.endpoint}]</span>`;
                        }

                        if (step.count !== undefined) {
                            message += ` <span style="color: #A0A8B8;">(${step.count})</span>`;
                        }

                        return `<div style="color: ${color};">${icon} ${this.escapeHtml(message)}</div>`;
                    }

                    showResults(results) {
                        $('#spy-progress-bar').css('width', '100%').css('box-shadow', '0 0 20px rgba(139, 92, 246, 0.6)');
                        $('#spy-progress-text').text('Analysis Complete');

                        const keywords = results.keywords || [];
                        const totalFound = results.total_found || 0;

                        $('#spy-current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-success); margin-bottom: 8px; font-size: 16px;">✅ Analysis Complete!</div>
                            <div style="font-size: 13px; color: var(--brand-white);">
                                <span style="color: var(--brand-primary); font-weight: 600;">🔍 ${totalFound}</span> keywords found •
                                <span style="color: var(--brand-purple); font-weight: 600;">📊 ${keywords.length}</span> top opportunities •
                                <span style="color: var(--brand-success); font-weight: 600;">🎯 ${results.competitors_analyzed}</span> competitors analyzed
                            </div>
                        `).css('border-left-color', 'var(--brand-success)');

                        // Show results table
                        const resultsHTML = this.buildResultsTable(keywords);
                        $('#spy-modal-feedback').html(resultsHTML);

                        $('#modal-confirm').text('💾 Save All to Library').prop('disabled', false).off('click').on('click', () => {
                            this.saveKeywordsToLibrary(keywords, results.analysis_id);
                        });
                    }

                    buildResultsTable(keywords) {
                        if (keywords.length === 0) {
                            return `
                                <div class="modal-info" style="margin-top: 20px;">
                                    <strong>⚠️ No Keywords Found</strong><br><br>
                                    <div style="background: rgba(245, 158, 11, 0.2); padding: 12px; border-radius: 8px; border-left: 3px solid var(--brand-warning); margin: 12px 0;">
                                        <strong style="color: var(--brand-warning);">⚠️ MOST COMMON ISSUE: Language/Country Mismatch!</strong><br><br>
                                        <strong>Examples:</strong><br>
                                        • meshistoiresdusoir.fr (French site) → Select "🇫🇷 France (French)"<br>
                                        • nytimes.com (US site) → Select "🇺🇸 United States (English)"<br>
                                        • bild.de (German site) → Select "🇩🇪 Germany (German)"
                                    </div>
                                    <strong>Other possible reasons:</strong><br>
                                    • Filters too restrictive (default: volume ≥100, difficulty ≤50)<br>
                                    • Competitor has very low traffic or is too new<br>
                                    • Domain not in DataForSEO database yet<br><br>
                                    <strong>Quick Fixes:</strong><br>
                                    1. <strong>Close this modal and retry with correct language/country</strong><br>
                                    2. Open "Advanced Filters" → Set Min Volume to <strong>0</strong><br>
                                    3. Set Max Difficulty to <strong>70-80</strong><br>
                                    4. Try "Best Performers" instead of "Gap Analysis"<br>
                                    5. Test with a well-known competitor first (e.g., nytimes.com for US English)<br><br>
                                    <strong>Debug:</strong> Press F12 → Console tab to see detailed DataForSEO API responses.
                                </div>
                            `;
                        }

                        let html = `
                            <div style="margin-top: 20px; max-height: 400px; overflow-y: auto;">
                                <h4 style="color: var(--brand-white); margin-bottom: 12px;">🎯 Top ${keywords.length} Keywords</h4>
                                <table style="width: 100%; font-size: 12px; border-collapse: collapse;">
                                    <thead>
                                        <tr style="background: rgba(0, 188, 212, 0.1); border-bottom: 2px solid rgba(0, 188, 212, 0.3);">
                                            <th style="padding: 8px; text-align: left; color: var(--brand-white); font-weight: 600;">Keyword</th>
                                            <th style="padding: 8px; text-align: center; color: var(--brand-white); font-weight: 600;">Volume</th>
                                            <th style="padding: 8px; text-align: center; color: var(--brand-white); font-weight: 600;">Diff</th>
                                            <th style="padding: 8px; text-align: center; color: var(--brand-white); font-weight: 600;">Comp Pos</th>
                                            <th style="padding: 8px; text-align: center; color: var(--brand-white); font-weight: 600;">Priority</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                        `;

                        keywords.slice(0, 50).forEach(kw => {
                            const priorityColor = kw.priority_score >= 70 ? '#10B981' : kw.priority_score >= 50 ? '#F59E0B' : '#A0A8B8';
                            html += `
                                <tr style="border-bottom: 1px solid rgba(0, 188, 212, 0.1);">
                                    <td style="padding: 8px; color: var(--brand-white);">${this.escapeHtml(kw.keyword)}</td>
                                    <td style="padding: 8px; text-align: center; color: var(--brand-primary); font-weight: 600;">${this.formatNumber(kw.search_volume)}</td>
                                    <td style="padding: 8px; text-align: center; color: var(--brand-gray-light);">${kw.difficulty || 'N/A'}</td>
                                    <td style="padding: 8px; text-align: center; color: var(--brand-purple); font-weight: 600;">#${kw.competitor_position || 'N/A'}</td>
                                    <td style="padding: 8px; text-align: center; color: ${priorityColor}; font-weight: 700;">${Math.round(kw.priority_score)}</td>
                                </tr>
                            `;
                        });

                        html += `
                                    </tbody>
                                </table>
                                ${keywords.length > 50 ? `<p style="text-align: center; color: var(--brand-gray-light); margin-top: 12px; font-size: 11px;">Showing top 50 of ${keywords.length} keywords</p>` : ''}
                            </div>
                        `;

                        return html;
                    }

                    saveKeywordsToLibrary(keywords, analysisId) {
                        $('#modal-confirm').prop('disabled', true).text('💾 Saving...');

                        $.ajax({
                            url: wisewandSEO.ajaxUrl,
                            type: 'POST',
                            data: {
                                action: 'wisewand_save_spy_keywords',
                                keywords: JSON.stringify(keywords),
                                analysis_id: analysisId,
                                language_code: this.language,
                                location_code: this.location,
                                nonce: wisewandSEO.nonce
                            },
                            success: (response) => {
                                if (response.success) {
                                    $('#spy-modal-feedback').html(`
                                        <div class="modal-success">
                                            ✅ <strong>Saved ${response.data.saved} keywords to library!</strong><br><br>
                                            Skipped ${response.data.skipped} duplicates.<br>
                                            Keywords are now available in the table below.
                                        </div>
                                    `);

                                    setTimeout(() => {
                                        closeModal();
                                        loadLatestSnapshot();
                                    }, 2000);
                                } else {
                                    alert('Failed to save: ' + (response.data?.message || 'Unknown error'));
                                    $('#modal-confirm').prop('disabled', false).text('💾 Retry Save');
                                }
                            },
                            error: () => {
                                alert('Connection error while saving');
                                $('#modal-confirm').prop('disabled', false).text('💾 Retry Save');
                            }
                        });
                    }

                    showError(message) {
                        $('#spy-current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-error); margin-bottom: 6px; font-size: 15px;">❌ Error Occurred</div>
                            <div style="font-size: 13px; color: var(--brand-white);">${this.escapeHtml(message)}</div>
                        `).css('border-left-color', 'var(--brand-error)');

                        const $log = $('#spy-progress-steps');
                        $log.append(`<div style="color: var(--brand-error); font-weight: 600;">✗ ERROR: ${this.escapeHtml(message)}</div>`);

                        $('#modal-confirm').prop('disabled', false).text('🕵️ Retry');
                    }

                    escapeHtml(text) {
                        const div = document.createElement('div');
                        div.textContent = text;
                        return div.innerHTML;
                    }

                    formatNumber(num) {
                        if (num >= 1000) {
                            return (num / 1000).toFixed(1) + 'K';
                        }
                        return num.toString();
                    }
                }

            // Competitor Spy - Show Modal
            $('#spy-competitors').on('click', function() {
                const modalBody = `
                    <div class="modal-form-group">
                        <label>🎯 Analysis Type</label>
                        <select id="spy-analysis-type" class="modal-select">
                            <option value="hybrid" selected>🔄 Hybrid (Gap + Best Performers)</option>
                            <option value="gap">🔍 Gap Analysis Only (They rank, you don't)</option>
                            <option value="best_performers">⭐ Best Performers Only (Their top keywords)</option>
                        </select>
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 6px;">
                            Hybrid mode combines both strategies for maximum keyword discovery.
                        </p>
                    </div>

                    <div class="modal-form-group">
                        <label>🕵️ Competitor Domains (1-3)</label>
                        <input type="text" id="spy-competitor-1" class="modal-input" placeholder="competitor1.com" />
                        <input type="text" id="spy-competitor-2" class="modal-input" placeholder="competitor2.com (optional)" style="margin-top: 8px;" />
                        <input type="text" id="spy-competitor-3" class="modal-input" placeholder="competitor3.com (optional)" style="margin-top: 8px;" />
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 6px;">
                            Enter without http:// or www. Example: nytimes.com
                        </p>
                    </div>

                    <div class="modal-form-group">
                        <label>🌍 Target Market</label>
                        <select id="spy-market" class="modal-select">
                            <option value="fr:2250">🇫🇷 France (French)</option>
                            <option value="en:2840" selected>🇺🇸 United States (English)</option>
                            <option value="de:2276">🇩🇪 Germany (German)</option>
                            <option value="es:2724">🇪🇸 Spain (Spanish)</option>
                            <option value="en:2826">🇬🇧 United Kingdom (English)</option>
                            <option value="en:2124">🇨🇦 Canada (English)</option>
                        </select>
                    </div>

                    <details style="margin-top: 12px;">
                        <summary style="cursor: pointer; color: var(--brand-primary); font-weight: 600; font-size: 13px; margin-bottom: 12px;">⚙️ Advanced Filters (Optional)</summary>
                        <div style="padding: 12px; background: rgba(0, 188, 212, 0.05); border-radius: 8px; margin-top: 8px;">
                            <div class="modal-form-group">
                                <label>Min Search Volume: <span id="vol-value">100</span>/month</label>
                                <input type="range" id="spy-min-volume" min="0" max="5000" value="100" step="50" style="width: 100%;" />
                            </div>
                            <div class="modal-form-group">
                                <label>Max Difficulty: <span id="diff-value">50</span>/100</label>
                                <input type="range" id="spy-max-difficulty" min="0" max="100" value="50" step="5" style="width: 100%;" />
                            </div>
                            <div class="modal-form-group">
                                <label>Competitor Position Range</label>
                                <div style="display: flex; gap: 12px;">
                                    <input type="number" id="spy-pos-min" class="modal-input" value="1" min="1" max="100" style="width: 80px;" />
                                    <span style="color: var(--brand-white); align-self: center;">to</span>
                                    <input type="number" id="spy-pos-max" class="modal-input" value="50" min="1" max="100" style="width: 80px;" />
                                </div>
                            </div>
                            <div class="modal-form-group">
                                <label style="display: flex; align-items: center; gap: 8px; cursor: pointer; text-transform: none;">
                                    <input type="checkbox" id="spy-exclude-branded" checked style="width: auto;" />
                                    <span>Exclude competitor branded terms</span>
                                </label>
                            </div>
                        </div>
                    </details>

                    <div id="spy-modal-feedback"></div>
                `;

                showModal('🕵️ Competitor Spy', modalBody, '🕵️ Start Analysis', function() {
                    const competitors = [
                        $('#spy-competitor-1').val().trim(),
                        $('#spy-competitor-2').val().trim(),
                        $('#spy-competitor-3').val().trim()
                    ].filter(c => c);

                    if (competitors.length === 0) {
                        $('#spy-modal-feedback').html('<div class="modal-error">Please enter at least one competitor domain</div>');
                        return;
                    }

                    const analysisType = $('#spy-analysis-type').val();
                    const [language, location] = $('#spy-market').val().split(':');
                    const filters = {
                        min_volume: parseInt($('#spy-min-volume').val()),
                        max_difficulty: parseInt($('#spy-max-difficulty').val()),
                        position_min: parseInt($('#spy-pos-min').val()),
                        position_max: parseInt($('#spy-pos-max').val()),
                        exclude_branded: $('#spy-exclude-branded').is(':checked')
                    };

                    $('#modal-confirm').prop('disabled', true).text('🕵️ Analyzing...');

                    const spyProgress = new CompetitorSpyProgress(
                        competitors,
                        analysisType,
                        language,
                        parseInt(location),
                        filters,
                        wisewandSEO.domain
                    );

                    $('#spy-modal-feedback').html(spyProgress.getHTML());
                    spyProgress.start();
                });

                // Update slider values in real-time
                $('#spy-min-volume').on('input', function() {
                    $('#vol-value').text($(this).val());
                });

                $('#spy-max-difficulty').on('input', function() {
                    $('#diff-value').text($(this).val());
                });
            });

            // Deduplication - Open Scanner
            $('#open-deduplication').on('click', function() {
                openDeduplicationScanner();
            });

            // AI Match Categories - Open Matcher
            $('#ai-match-categories').on('click', function() {
                // Check if OpenAI is configured via quick AJAX check
                $.ajax({
                    url: wisewandSEO.settingsUrl,
                    type: 'HEAD',
                    complete: function() {
                        // Just trigger the modal - backend will check API key
                        openAICategoryMatcher();
                    }
                });
            });

            function openAICategoryMatcher() {
                const modalBody = `
                    <div style="text-align: center; color: var(--brand-white); margin-bottom: 20px;">
                        <div style="font-size: 56px; margin-bottom: 16px;">🤖</div>
                        <div style="font-size: 18px; font-weight: 700; margin-bottom: 8px;">AI Category Matching</div>
                        <div style="font-size: 13px; color: var(--brand-gray-light); max-width: 500px; margin: 0 auto; line-height: 1.6;">
                            GPT-4o-mini will analyze your keywords and intelligently match them to WordPress categories.
                            This helps organize content and improve SEO structure.
                        </div>
                    </div>

                    <div class="modal-form-group" style="margin-bottom: 20px;">
                        <label style="display: block; margin-bottom: 10px; color: var(--brand-white); font-weight: 600; font-size: 14px;">📋 Keywords to Process</label>
                        <select id="ai-keyword-filter" class="modal-select" style="width: 100%; padding: 10px 14px; border: 1px solid rgba(16, 185, 129, 0.3); border-radius: 8px; background: rgba(10, 14, 39, 0.8); color: var(--brand-white); font-size: 14px;">
                            <option value="uncategorized">🎯 Only Uncategorized Keywords (Recommended)</option>
                            <option value="all">📚 All Keywords (Re-match Everything)</option>
                            <option value="exclude_ranking">🚫 Exclude Already Ranking Keywords</option>
                            <option value="only_ranking">✅ Only Ranking Keywords (Auto-detect from URLs)</option>
                            <option value="without_position">🔍 Only Keywords Without Position Data</option>
                        </select>
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 8px; line-height: 1.5;">
                            💡 <strong>Recommended:</strong> Use "Only Uncategorized" for normal matching. Use "Exclude Ranking" if you have many positioned keywords and want to focus on new opportunities.
                        </p>
                    </div>

                    <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(16, 185, 129, 0.3); border-radius: 12px; padding: 20px; margin-bottom: 20px; backdrop-filter: blur(10px);">
                        <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 16px;">
                            <div style="text-align: center;">
                                <div style="font-size: 32px; font-weight: 700; color: var(--brand-success);" id="ai-total-keywords">-</div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">Keywords to Process</div>
                            </div>
                            <div style="text-align: center;">
                                <div style="font-size: 32px; font-weight: 700; color: var(--brand-primary);" id="ai-categories-count">-</div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">WP Categories</div>
                            </div>
                            <div style="text-align: center;">
                                <div style="font-size: 32px; font-weight: 700; color: var(--brand-warning);" id="ai-estimated-cost">-</div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">Est. Cost (USD)</div>
                            </div>
                        </div>
                    </div>

                    <div id="ai-match-feedback"></div>
                `;

                showModal('🤖 AI Category Matching', modalBody, '🤖 Start AI Matching', function() {
                    startAICategoryMatching();
                });

                // Load stats
                loadAIMatchingStats();

                // Update stats when filter changes
                $('#ai-keyword-filter').on('change', function() {
                    loadAIMatchingStats();
                });
            }

            function loadAIMatchingStats() {
                const filterMode = $('#ai-keyword-filter').val() || 'uncategorized';
                const totalCategories = wisewandSEO.totalCategories || 0;

                // Show loading state
                $('#ai-total-keywords').text('...');
                $('#ai-estimated-cost').text('...');

                // Use AJAX for server-side counting (more accurate for ranking filters)
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_count_keywords_for_matching',
                        nonce: wisewandSEO.nonce,
                        filter_mode: filterMode
                    },
                    success: function(response) {
                        if (response.success && response.data) {
                            const keywordCount = response.data.total_keywords || 0;
                            const autoMatchable = response.data.auto_matchable || 0;
                            const aiNeeded = response.data.ai_needed || 0;

                            // Estimate cost (GPT-4o-mini pricing: ~$0.25 per 1000 keywords)
                            const estimatedCost = (aiNeeded * 0.00025).toFixed(3);

                            // Debug logging
                            console.log('🤖 AI Matching Stats:', {
                                filterMode: filterMode,
                                keywordCount: keywordCount,
                                autoMatchable: autoMatchable,
                                aiNeeded: aiNeeded,
                                totalCategories: totalCategories,
                                estimatedCost: estimatedCost
                            });

                            $('#ai-total-keywords').text(keywordCount);
                            $('#ai-categories-count').text(totalCategories);
                            $('#ai-estimated-cost').text('$' + estimatedCost);

                            // Show helpful message based on count and filter
                            if (keywordCount === 0) {
                                $('#ai-match-feedback').html(`
                                    <div style="padding: 12px; background: rgba(16, 185, 129, 0.15); border-left: 3px solid var(--brand-success); border-radius: 8px; font-size: 12px; color: var(--brand-white);">
                                        ✅ <strong>No keywords match this filter!</strong><br>
                                        Try a different filter option.
                                    </div>
                                `);
                            } else if (autoMatchable > 0 && filterMode === 'only_ranking') {
                                $('#ai-match-feedback').html(`
                                    <div style="padding: 12px; background: rgba(59, 130, 246, 0.15); border-left: 3px solid var(--brand-primary); border-radius: 8px; font-size: 12px; color: var(--brand-white);">
                                        🔗 <strong>${autoMatchable} keywords have ranking URLs</strong><br>
                                        Categories will be auto-detected from existing posts! Save ~$${(autoMatchable * 0.00025).toFixed(3)}
                                    </div>
                                `);
                            } else if (autoMatchable > 0) {
                                $('#ai-match-feedback').html(`
                                    <div style="padding: 12px; background: rgba(59, 130, 246, 0.15); border-left: 3px solid var(--brand-primary); border-radius: 8px; font-size: 12px; color: var(--brand-white);">
                                        🔗 <strong>${autoMatchable} keywords will be auto-matched from URLs</strong><br>
                                        Only ${aiNeeded} keywords need AI processing. Saving ~$${(autoMatchable * 0.00025).toFixed(3)}
                                    </div>
                                `);
                            } else {
                                $('#ai-match-feedback').html('');
                            }
                        } else {
                            // Fallback to client-side counting for backward compatibility
                            $('#ai-total-keywords').text('?');
                            $('#ai-estimated-cost').text('?');
                        }
                    },
                    error: function() {
                        $('#ai-total-keywords').text('?');
                        $('#ai-estimated-cost').text('?');
                    }
                });
            }

            function startAICategoryMatching() {
                const filterMode = $('#ai-keyword-filter').val() || 'uncategorized';

                console.log('🤖 Starting AI matching with filter:', filterMode);

                $('#modal-confirm').prop('disabled', true).text('🤖 Matching...');

                const progressUI = new AICategoryMatcherProgress(filterMode);
                $('#ai-match-feedback').html(progressUI.getHTML());

                progressUI.start();
            }

            function openDeduplicationScanner() {
                const modalBody = `
                    <div style="text-align: center; color: var(--brand-white); margin-bottom: 20px;">
                        <div style="font-size: 56px; margin-bottom: 16px;">🔗</div>
                        <div style="font-size: 18px; font-weight: 700; margin-bottom: 8px;">Keyword Deduplication Scanner</div>
                        <div style="font-size: 13px; color: var(--brand-gray-light); max-width: 500px; margin: 0 auto; line-height: 1.6;">
                            Detect and group similar keywords to prevent content cannibalization.
                            The scanner uses multi-algorithm fuzzy matching to find duplicates, reorders, and singular/plural variants.
                        </div>
                    </div>

                    <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 12px; padding: 20px; margin-bottom: 20px; backdrop-filter: blur(10px);">
                        <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 16px;">
                            <div style="text-align: center;">
                                <div style="font-size: 32px; font-weight: 700; color: var(--brand-purple);" id="dedup-total-keywords">-</div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">Total Keywords</div>
                            </div>
                            <div style="text-align: center;">
                                <div style="font-size: 32px; font-weight: 700; color: var(--brand-success);" id="dedup-clusters-count">-</div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">Clusters Found</div>
                            </div>
                            <div style="text-align: center;">
                                <div style="font-size: 32px; font-weight: 700; color: var(--brand-primary);" id="dedup-variants-count">-</div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">Variants Detected</div>
                            </div>
                        </div>
                    </div>

                    <div id="dedup-scanner-feedback"></div>
                `;

                showModal('🔗 Keyword Deduplication', modalBody, '🔍 Start Scan', function() {
                    startDeduplicationScan();
                });

                // Load current stats
                loadDeduplicationStats();
            }

            function loadDeduplicationStats() {
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_get_clusters',
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success && response.data.stats) {
                            $('#dedup-total-keywords').text(response.data.stats.total_keywords || 0);
                            $('#dedup-clusters-count').text(response.data.stats.total_clusters || 0);
                            $('#dedup-variants-count').text(response.data.stats.total_variants || 0);
                        }
                    }
                });
            }

            function startDeduplicationScan() {
                $('#modal-confirm').prop('disabled', true).text('🔍 Scanning...');

                const progressUI = new DeduplicationScanner();
                $('#dedup-scanner-feedback').html(progressUI.getHTML());

                progressUI.start();
            }

            // Deduplication Scanner Progress Manager (Global Scope)
            class DeduplicationScanner {
                constructor() {
                    this.startTime = Date.now();
                }

                getHTML() {
                    return `
                        <div id="dedup-progress-container" style="margin-top: 12px;">
                            <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(139, 92, 246, 0.2); border-radius: 16px; padding: 20px; backdrop-filter: blur(10px);">
                                <!-- Progress Bar -->
                                <div style="margin-bottom: 20px;">
                                    <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
                                        <span style="font-size: 13px; font-weight: 600; color: var(--brand-white); letter-spacing: 0.05em; text-transform: uppercase;">Scan Progress</span>
                                        <span id="dedup-progress-text" style="font-size: 13px; color: var(--brand-purple); font-weight: 600;">Initializing...</span>
                                    </div>
                                    <div style="background: rgba(160, 168, 184, 0.15); border-radius: 12px; height: 10px; overflow: hidden; border: 1px solid rgba(139, 92, 246, 0.2);">
                                        <div id="dedup-progress-bar" style="background: linear-gradient(90deg, var(--brand-purple) 0%, var(--brand-primary) 100%); height: 100%; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(139, 92, 246, 0.5);"></div>
                                    </div>
                                </div>

                                <!-- Current Status -->
                                <div id="dedup-current-status" style="background: rgba(139, 92, 246, 0.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; border-left: 4px solid var(--brand-purple); backdrop-filter: blur(10px);">
                                    <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">Preparing scan...</div>
                                    <div id="dedup-status-detail" style="font-size: 13px; color: var(--brand-gray-light);"></div>
                                </div>

                                <!-- Progress Steps Log -->
                                <div id="dedup-progress-steps" style="height: 290px; overflow-y: auto; font-size: 12px; font-family: 'Consolas', 'Monaco', monospace; background: #0A0E27; color: #E2E8F0; padding: 16px; border-radius: 12px; line-height: 1.8; border: 1px solid rgba(139, 92, 246, 0.3); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);">
                                    <div style="color: var(--brand-purple);">● Initializing deduplication scanner...</div>
                                    <div style="color: var(--brand-gray-light);">→ Loading keyword library...</div>
                                </div>
                            </div>

                            <!-- Warning at Bottom -->
                            <div style="margin-top: 12px; padding: 10px 14px; background: rgba(245, 158, 11, 0.15); border-left: 3px solid var(--brand-warning); border-radius: 8px; font-size: 11px; color: var(--brand-white); line-height: 1.5; backdrop-filter: blur(10px); border: 1px solid rgba(245, 158, 11, 0.3);">
                                ⚠️ <strong style="color: var(--brand-warning);">Keep window open</strong> - Thorough scanning may take 15-30 seconds for large libraries
                            </div>
                        </div>
                    `;
                }

                start() {
                    this.addLog('→ Algorithm: Multi-phase fuzzy matching (Token, Levenshtein, Jaro-Winkler, Phonetic)');
                    this.addLog('→ Threshold: 75% similarity (strict mode)');
                    this.addLog('→ Metrics validation: volume ±20%, difficulty ±15%, same intent');
                    this.addLog(' ');

                    this.runScan();
                }

                runScan() {
                    $('#dedup-progress-bar').css('width', '5%');
                    $('#dedup-progress-text').text('Checking enrichment...');
                    $('#dedup-current-status div:first').html('🔍 Preparing scan...');
                    $('#dedup-status-detail').html('Checking keyword enrichment status...');

                    this.addLog('<span style="color: var(--brand-primary);">● Preparation:</span> Checking enrichment status...');

                    // Step 1: Check if enrichment is needed
                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_scan_duplicates',
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            if (response.success) {
                                if (response.data.needs_enrichment) {
                                    // Need to enrich first
                                    this.addLog(`<span style="color: var(--brand-warning);">  ⚠ Found ${response.data.unenriched_count} unenriched keywords</span>`);
                                    this.addLog(' ');
                                    this.enrichKeywords(response.data.unenriched_ids);
                                } else {
                                    // Already enriched, proceed to clustering
                                    this.addLog('<span style="color: var(--brand-success);">  ✓ All keywords enriched</span>');
                                    this.addLog(' ');
                                    this.runClustering();
                                }
                            } else {
                                this.showError(response.data.message || 'Scan failed');
                            }
                        },
                        error: (xhr) => {
                            this.handleAjaxError(xhr, 'Scan preparation failed');
                        }
                    });
                }

                enrichKeywords(keywordIds) {
                    this.totalEnrich = keywordIds.length;
                    this.currentEnrich = 0;
                    this.batchSize = 10; // DataForSEO safe batch size

                    $('#dedup-progress-bar').css('width', '10%');
                    $('#dedup-current-status div:first').html('📊 Enriching Keywords...');

                    this.addLog('<span style="color: var(--brand-success);">● PHASE 1: ENRICHMENT</span>');
                    this.addLog(`<span style="color: var(--brand-gray-light);">  → Enriching ${this.totalEnrich} keywords with SEO data...</span>`);
                    this.addLog(`<span style="color: var(--brand-gray-light);">  → Batch size: 10 keywords (DataForSEO optimized)</span>`);
                    this.addLog(`<span style="color: var(--brand-gray-light);">  → Delay: 500ms between batches (rate limit safe)</span>`);
                    this.addLog(' ');

                    this.enrichNextBatch(keywordIds);
                }

                enrichNextBatch(keywordIds) {
                    const batchNumber = Math.floor(this.currentEnrich / this.batchSize) + 1;
                    const totalBatches = Math.ceil(this.totalEnrich / this.batchSize);
                    const startIdx = this.currentEnrich;
                    const endIdx = Math.min(startIdx + this.batchSize, this.totalEnrich);
                    const batchIds = keywordIds.slice(startIdx, endIdx);

                    if (batchIds.length === 0) {
                        // Enrichment complete, proceed to clustering
                        this.addLog('<span style="color: var(--brand-success);">  ✅ Enrichment complete!</span>');
                        this.addLog(' ');
                        this.runClustering();
                        return;
                    }

                    const enrichProgress = Math.round((this.currentEnrich / this.totalEnrich) * 40); // 40% of total
                    $('#dedup-progress-bar').css('width', (10 + enrichProgress) + '%');
                    $('#dedup-progress-text').text(`Enriching ${this.currentEnrich}/${this.totalEnrich}...`);
                    $('#dedup-status-detail').html(`Batch ${batchNumber}/${totalBatches} - Fetching SEO metrics...`);

                    this.addLog(`<span style="color: var(--brand-primary);">  ● Batch ${batchNumber}/${totalBatches}:</span> Enriching ${batchIds.length} keywords...`);

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_enrich_saved_keywords',
                            keyword_ids: batchIds,
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            if (response.success) {
                                this.addLog(`<span style="color: var(--brand-success);">    ✓ Enriched ${response.data.enriched || batchIds.length} keywords</span>`);
                                this.currentEnrich += batchIds.length;

                                // Continue with next batch after delay (DataForSEO rate limit safe)
                                setTimeout(() => this.enrichNextBatch(keywordIds), 500);
                            } else {
                                this.addLog(`<span style="color: var(--brand-warning);">    ⚠ Batch ${batchNumber} had issues, continuing...</span>`);
                                this.currentEnrich += batchIds.length;
                                setTimeout(() => this.enrichNextBatch(keywordIds), 500);
                            }
                        },
                        error: () => {
                            this.addLog(`<span style="color: var(--brand-warning);">    ⚠ Batch ${batchNumber} failed, continuing...</span>`);
                            this.currentEnrich += batchIds.length;
                            setTimeout(() => this.enrichNextBatch(keywordIds), 500);
                        }
                    });
                }

                runClustering() {
                    $('#dedup-progress-bar').css('width', '50%');
                    $('#dedup-current-status div:first').html('🔍 Scanning for duplicates...');
                    $('#dedup-status-detail').html('Running multi-algorithm fuzzy matching...');

                    this.addLog('<span style="color: var(--brand-success);">● PHASE 2: DEDUPLICATION SCAN</span>');
                    this.addLog('<span style="color: var(--brand-primary);">  ● Pre-filtering:</span> Grouping by language, first letter, word count...');

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_run_clustering_scan',
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            if (response.success) {
                                const stats = response.data.stats;

                                this.addLog('<span style="color: var(--brand-success);">    ✓ Pre-filtering complete</span>');
                                this.addLog(' ');
                                this.addLog('<span style="color: var(--brand-primary);">  ● Fuzzy Matching:</span> Calculating similarity scores...');

                                $('#dedup-progress-bar').css('width', '70%');

                                setTimeout(() => {
                                    this.addLog('<span style="color: var(--brand-success);">    ✓ Similarity calculation complete</span>');
                                    this.addLog(' ');
                                    this.addLog('<span style="color: var(--brand-primary);">  ● Clustering:</span> Building clusters (graph algorithm)...');
                                    $('#dedup-progress-bar').css('width', '85%');

                                    setTimeout(() => {
                                        this.addLog('<span style="color: var(--brand-success);">    ✓ Clusters built successfully</span>');
                                        this.addLog(' ');
                                        this.addLog('<span style="color: var(--brand-primary);">  ● Selection:</span> Choosing primary keywords...');
                                        $('#dedup-progress-bar').css('width', '95%');

                                        setTimeout(() => {
                                            this.showComplete(stats, response.data);
                                        }, 500);
                                    }, 500);
                                }, 500);
                            } else {
                                this.showError(response.data.message || 'Clustering failed');
                            }
                        },
                        error: (xhr) => {
                            this.handleAjaxError(xhr, 'Clustering scan failed');
                        }
                    });
                }

                handleAjaxError(xhr, defaultMsg) {
                    console.error('Deduplication error:', xhr);

                    let errorMsg = defaultMsg || 'Network error. Please try again.';

                    if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
                        errorMsg = xhr.responseJSON.data.message;
                    } else if (xhr.responseText) {
                        const match = xhr.responseText.match(/Fatal error:(.+?)in/i);
                        if (match) {
                            errorMsg = 'PHP Error: ' + match[1].trim();
                        } else if (xhr.status === 500) {
                            errorMsg = 'Server error (500). The deduplication tables may not be created yet. Please deactivate and reactivate the plugin to run database migrations.';
                        }
                    }

                    this.showError(errorMsg);
                }

                addLog(message) {
                    const $log = $('#dedup-progress-steps');
                    $log.append('<div>' + message + '</div>');
                    $log.scrollTop($log[0].scrollHeight);
                }

                showComplete(stats, data) {
                    const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);

                    $('#dedup-progress-bar').css('width', '100%').css('box-shadow', '0 0 20px rgba(139, 92, 246, 0.6)');
                    $('#dedup-progress-text').text('Complete!');
                    $('#dedup-current-status div:first').html('✅ Scan Complete!');
                    $('#dedup-status-detail').html(`Found ${stats.clusters} clusters with ${stats.variants} variants in ${elapsed}s`);

                    this.addLog(' ');
                    this.addLog('<span style="color: var(--brand-success); font-weight: 600;">✅ DEDUPLICATION COMPLETE!</span>');
                    this.addLog(' ');
                    this.addLog(`<span style="color: var(--brand-white);">📊 Results Summary:</span>`);
                    this.addLog(`<span style="color: var(--brand-gray-light);">  → Total Keywords Scanned:</span> ${stats.total_keywords}`);
                    this.addLog(`<span style="color: var(--brand-success);">  → Clusters Detected:</span> ${stats.clusters}`);
                    this.addLog(`<span style="color: var(--brand-primary);">  → Variant Keywords:</span> ${stats.variants}`);
                    this.addLog(`<span style="color: var(--brand-purple);">  → Unique Keywords:</span> ${stats.unique}`);
                    this.addLog(`<span style="color: var(--brand-warning);">  → Potential Reduction:</span> ${stats.total_keywords} → ${stats.reduction} (${Math.round(((stats.total_keywords - stats.reduction) / stats.total_keywords) * 100)}% less cannibalization)`);
                    this.addLog(' ');
                    this.addLog(`<span style="color: var(--brand-gray-light);">⏱️  Processing Time:</span> ${elapsed} seconds`);

                    // Update modal stats
                    $('#dedup-clusters-count').text(stats.clusters);
                    $('#dedup-variants-count').text(stats.variants);

                    $('#modal-confirm').text('📋 View Clusters').prop('disabled', false).off('click').on('click', function() {
                        closeModal();
                        showClustersInterface();
                    });
                }

                showError(message) {
                    // Check if it's a table/migration error
                    const isMigrationError = message.includes('table') || message.includes('reactivate') || message.includes('column');

                    if (isMigrationError) {
                        $('#dedup-current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-warning); margin-bottom: 8px; font-size: 15px;">⚠️ Database Setup Required</div>
                            <div style="font-size: 13px; color: var(--brand-white); line-height: 1.6; margin-bottom: 12px;">${message}</div>
                            <div style="background: rgba(139, 92, 246, 0.1); padding: 12px; border-radius: 8px; border-left: 3px solid var(--brand-purple);">
                                <div style="font-size: 12px; color: var(--brand-white); font-weight: 600; margin-bottom: 8px;">🔧 How to Fix:</div>
                                <ol style="margin: 0; padding-left: 20px; font-size: 12px; color: var(--brand-gray-light); line-height: 1.8;">
                                    <li>Go to <strong style="color: var(--brand-white);">Plugins</strong> page</li>
                                    <li><strong style="color: var(--brand-warning);">Deactivate</strong> Wisewand Plugin</li>
                                    <li><strong style="color: var(--brand-success);">Reactivate</strong> Wisewand Plugin</li>
                                    <li>Return here and scan again</li>
                                </ol>
                                <div style="margin-top: 8px; font-size: 11px; color: var(--brand-gray-light);">
                                    This triggers database migrations that create the deduplication tables.
                                </div>
                            </div>
                        `);
                        this.addLog('<span style="color: var(--brand-warning);">⚠️ Database migration required</span>');
                        this.addLog('<span style="color: var(--brand-gray-light);">→ Please deactivate and reactivate the plugin</span>');
                        $('#modal-confirm').text('✓ Got It').prop('disabled', false);
                    } else {
                        $('#dedup-current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-error); margin-bottom: 6px; font-size: 15px;">❌ Error</div>
                            <div style="font-size: 13px; color: var(--brand-gray-light);">${message}</div>
                        `);
                        $('#modal-confirm').text('❌ Failed').prop('disabled', false);
                        this.addLog('<span style="color: var(--brand-error);">✗ Scan failed: ' + message + '</span>');
                    }
                }
            }

            // AI Category Matcher Progress Manager (Global Scope)
            class AICategoryMatcherProgress {
                constructor(filterMode = 'uncategorized') {
                    this.startTime = Date.now();
                    this.filterMode = filterMode;
                }

                getHTML() {
                    return `
                        <div id="ai-match-progress-container" style="margin-top: 12px;">
                            <div style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(16, 185, 129, 0.2); border-radius: 16px; padding: 20px; backdrop-filter: blur(10px);">
                                <!-- Progress Bar -->
                                <div style="margin-bottom: 20px;">
                                    <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
                                        <span style="font-size: 13px; font-weight: 600; color: var(--brand-white); letter-spacing: 0.05em; text-transform: uppercase;">AI Matching Progress</span>
                                        <span id="ai-match-progress-text" style="font-size: 13px; color: var(--brand-success); font-weight: 600;">Initializing...</span>
                                    </div>
                                    <div style="background: rgba(160, 168, 184, 0.15); border-radius: 12px; height: 10px; overflow: hidden; border: 1px solid rgba(16, 185, 129, 0.2);">
                                        <div id="ai-match-progress-bar" style="background: linear-gradient(90deg, var(--brand-success) 0%, var(--brand-primary) 100%); height: 100%; width: 0%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(16, 185, 129, 0.5);"></div>
                                    </div>
                                </div>

                                <!-- Current Status -->
                                <div id="ai-match-current-status" style="background: rgba(16, 185, 129, 0.1); border-radius: 12px; padding: 16px; margin-bottom: 16px; border-left: 4px solid var(--brand-success); backdrop-filter: blur(10px);">
                                    <div style="font-weight: 600; color: var(--brand-white); margin-bottom: 6px; font-size: 15px;">Starting AI analysis...</div>
                                    <div id="ai-match-status-detail" style="font-size: 13px; color: var(--brand-gray-light);"></div>
                                </div>

                                <!-- Progress Steps Log -->
                                <div id="ai-match-progress-steps" style="height: 290px; overflow-y: auto; font-size: 12px; font-family: 'Consolas', 'Monaco', monospace; background: #0A0E27; color: #E2E8F0; padding: 16px; border-radius: 12px; line-height: 1.8; border: 1px solid rgba(16, 185, 129, 0.3); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.3);">
                                    <div style="color: var(--brand-success);">● Initializing AI category matcher...</div>
                                    <div style="color: var(--brand-gray-light);">→ Model: gpt-4o-mini (temperature: 0.3)</div>
                                    <div style="color: var(--brand-gray-light);">→ Batch size: 20 keywords per API call</div>
                                </div>
                            </div>

                            <!-- Info Banner -->
                            <div style="margin-top: 12px; padding: 10px 14px; background: rgba(16, 185, 129, 0.15); border-left: 3px solid var(--brand-success); border-radius: 8px; font-size: 11px; color: var(--brand-white); line-height: 1.5; backdrop-filter: blur(10px); border: 1px solid rgba(16, 185, 129, 0.3);">
                                🤖 <strong style="color: var(--brand-success);">AI-Powered Matching</strong> - Categories will be intelligently matched based on semantic relevance
                            </div>
                        </div>
                    `;
                }

                start() {
                    this.addLog('→ Checking OpenAI API configuration...');
                    this.addLog(' ');

                    this.runMatching();
                }

                runMatching() {
                    console.log('🤖 AI Matching: Getting keyword list with filter:', this.filterMode);

                    this.addLog('<span style="color: var(--brand-success);">● Initializing</span>');
                    this.addLog('<span style="color: var(--brand-gray-light);">  → Fetching keyword list...</span>');

                    if (this.filterMode === 'uncategorized') {
                        this.addLog('<span style="color: var(--brand-primary);">  → Filter: Only uncategorized keywords</span>');
                    } else {
                        this.addLog('<span style="color: var(--brand-gray-light);">  → Filter: All keywords</span>');
                    }

                    // Step 1: Get all keyword IDs
                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_ai_match_categories',
                            filter_mode: this.filterMode,
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            if (response.success && response.data.mode === 'init') {
                                console.log('🤖 Initialization:', response.data);

                                this.keywordIds = response.data.keyword_ids;
                                this.totalKeywords = response.data.total_keywords;
                                this.batchSize = 10; // Reduced to 10 for better reliability
                                this.totalBatches = Math.ceil(this.totalKeywords / this.batchSize);
                                this.currentBatch = 0;
                                this.totalMatched = 0;
                                this.totalSaved = 0;
                                this.failedBatches = [];
                                this.retryCount = {};

                                this.addLog(`<span style="color: var(--brand-success);">  ✓ Found ${this.totalKeywords} keywords</span>`);
                                this.addLog(`<span style="color: var(--brand-gray-light);">  → Will process in ${this.totalBatches} batches (10 per batch)</span>`);
                                this.addLog(`<span style="color: var(--brand-gray-light);">  → Auto-retry on failure (max 3 attempts)</span>`);
                                this.addLog(' ');

                                // Start processing
                                this.processNextBatch();
                            } else {
                                this.showError(response.data.message || 'Initialization failed');
                            }
                        },
                        error: (xhr) => {
                            console.error('Init error:', xhr);
                            this.handleError(xhr);
                        }
                    });
                }

                processNextBatch() {
                    if (this.currentBatch >= this.totalBatches) {
                        // All done!
                        this.showComplete({
                            matched_count: this.totalMatched,
                            saved_count: this.totalSaved,
                        });
                        return;
                    }

                    const batchNumber = this.currentBatch + 1;
                    const startIdx = this.currentBatch * this.batchSize;
                    const endIdx = Math.min(startIdx + this.batchSize, this.totalKeywords);
                    const batchIds = this.keywordIds.slice(startIdx, endIdx);

                    const progress = Math.round((startIdx / this.totalKeywords) * 100);

                    $('#ai-match-progress-bar').css('width', progress + '%');
                    $('#ai-match-progress-text').text(`Batch ${batchNumber}/${this.totalBatches}`);
                    $('#ai-match-current-status div:first').html(`🤖 Processing batch ${batchNumber}/${this.totalBatches}...`);
                    $('#ai-match-status-detail').html(`Matching keywords ${startIdx + 1} to ${endIdx}...`);

                    this.addLog(`<span style="color: var(--brand-primary);">● Batch ${batchNumber}/${this.totalBatches}:</span> Processing ${batchIds.length} keywords...`);

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_ai_match_categories',
                            keyword_ids: batchIds,
                            nonce: wisewandSEO.nonce
                        },
                        success: (response) => {
                            if (response.success && response.data.mode === 'batch_complete') {
                                this.totalMatched += response.data.matched_count || 0;
                                this.totalSaved += response.data.saved_count || 0;

                                this.addLog(`<span style="color: var(--brand-success);">  ✓ Batch ${batchNumber}:</span> ${response.data.matched_count}/${response.data.batch_size} matched`);

                                this.currentBatch++;

                                // Continue with next batch
                                setTimeout(() => this.processNextBatch(), 500);
                            } else {
                                console.warn('Batch response issue:', response);
                                this.addLog(`<span style="color: var(--brand-warning);">  ⚠ Batch ${batchNumber} issue, continuing...</span>`);
                                this.currentBatch++;
                                setTimeout(() => this.processNextBatch(), 500);
                            }
                        },
                        error: (xhr) => {
                            // Retry logic (max 3 attempts)
                            const batchKey = `batch_${batchNumber}`;
                            this.retryCount[batchKey] = (this.retryCount[batchKey] || 0) + 1;

                            if (this.retryCount[batchKey] < 3) {
                                console.warn(`Batch ${batchNumber} error, retry ${this.retryCount[batchKey]}/3:`, xhr);
                                this.addLog(`<span style="color: var(--brand-warning);">  ⚠ Batch ${batchNumber} error, retrying (${this.retryCount[batchKey]}/3)...</span>`);

                                // Retry same batch after delay
                                setTimeout(() => this.processNextBatch(), 1000);
                            } else {
                                // Failed after 3 retries
                                console.error(`Batch ${batchNumber} failed after 3 retries`);
                                this.addLog(`<span style="color: var(--brand-error);">  ✗ Batch ${batchNumber} failed after 3 retries, skipping...</span>`);
                                this.failedBatches.push(batchNumber);

                                this.currentBatch++;
                                setTimeout(() => this.processNextBatch(), 500);
                            }
                        }
                    });
                }

                addLog(message) {
                    const $log = $('#ai-match-progress-steps');
                    $log.append('<div>' + message + '</div>');
                    $log.scrollTop($log[0].scrollHeight);
                }

                showComplete(data) {
                    const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);

                    console.log('🤖 showComplete called with data:', data);
                    console.log('🤖 matched_count:', data.matched_count);
                    console.log('🤖 saved_count:', data.saved_count);

                    // Check if actually got matches
                    if (data.matched_count === 0 || data.saved_count === 0) {
                        console.warn('⚠️ AI Matching returned 0 results!');
                        console.warn('⚠️ This usually means:');
                        console.warn('  1. OpenAI API error (check debug.log)');
                        console.warn('  2. No categories match keywords');
                        console.warn('  3. All matches filtered out (invalid IDs)');
                        console.warn('⚠️ Check wp-content/debug.log for details!');

                        this.addLog(' ');
                        this.addLog('<span style="color: var(--brand-warning);">⚠️ No matches found!</span>');
                        this.addLog('<span style="color: var(--brand-gray-light);">  → Check wp-content/debug.log for details</span>');
                        this.addLog('<span style="color: var(--brand-gray-light);">  → Possible: API error, no category matches, or validation filtered all</span>');
                    }

                    $('#ai-match-progress-text').text('Complete!');
                    $('#ai-match-current-status div:first').html('✅ AI Matching Complete!');
                    $('#ai-match-status-detail').html(`Matched ${data.saved_count} keywords to categories`);

                    const completionRate = ((data.saved_count / this.totalKeywords) * 100).toFixed(1);

                    this.addLog(' ');
                    this.addLog('<span style="color: var(--brand-success); font-weight: 600;">✅ AI MATCHING COMPLETE!</span>');
                    this.addLog(' ');
                    this.addLog(`<span style="color: var(--brand-white);">📊 Results:</span>`);
                    this.addLog(`<span style="color: var(--brand-success);">  → Keywords Processed:</span> ${this.totalKeywords}`);
                    this.addLog(`<span style="color: var(--brand-success);">  → Successfully Matched:</span> ${data.matched_count}`);
                    this.addLog(`<span style="color: var(--brand-primary);">  → Saved to Database:</span> ${data.saved_count}`);
                    this.addLog(`<span style="color: var(--brand-purple);">  → Completion Rate:</span> ${completionRate}%`);

                    if (this.failedBatches.length > 0) {
                        this.addLog(' ');
                        this.addLog(`<span style="color: var(--brand-warning);">  ⚠️ Failed Batches:</span> ${this.failedBatches.length} (after 3 retries each)`);
                        this.addLog(`<span style="color: var(--brand-gray-light);">     Batches: ${this.failedBatches.join(', ')}</span>`);
                    }

                    this.addLog(' ');
                    this.addLog(`<span style="color: var(--brand-gray-light);">⏱️  Processing Time:</span> ${elapsed} seconds`);
                    this.addLog(`<span style="color: var(--brand-gray-light);">🤖 Model:</span> gpt-4o-mini (temp: 0.3)`);
                    this.addLog(`<span style="color: var(--brand-gray-light);">📦 Batch Size:</span> 10 keywords`);

                    if (data.matched_count === 0) {
                        this.addLog(' ');
                        this.addLog('<span style="color: var(--brand-warning);">⚠️ Debug: Check browser console (F12) and wp-content/debug.log</span>');
                    }

                    $('#modal-confirm').text('✅ Done').prop('disabled', false).off('click').on('click', function() {
                        closeModal();
                        // Always reload to show updated data (even if 0 matches shown, data might exist)
                        location.reload();
                    });
                }

                showError(message) {
                    // Check if it's an API key error
                    if (message.includes('API key') || message.includes('OpenAI')) {
                        $('#ai-match-current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-warning); margin-bottom: 8px; font-size: 15px;">⚠️ OpenAI Not Configured</div>
                            <div style="font-size: 13px; color: var(--brand-white); line-height: 1.6; margin-bottom: 12px;">${message}</div>
                            <a href="" + wisewandSEO.settingsUrl + "" class="button button-primary" style="background: var(--brand-success); border: none;">
                                ⚙️ Go to Settings
                            </a>
                        `);
                        this.addLog('<span style="color: var(--brand-warning);">⚠️ API key not configured</span>');
                        this.addLog('<span style="color: var(--brand-gray-light);">→ Please add your OpenAI API key in Settings</span>');
                    } else {
                        $('#ai-match-current-status').html(`
                            <div style="font-weight: 600; color: var(--brand-error); margin-bottom: 6px; font-size: 15px;">❌ Error</div>
                            <div style="font-size: 13px; color: var(--brand-gray-light);">${message}</div>
                        `);
                        this.addLog('<span style="color: var(--brand-error);">✗ AI matching failed: ' + message + '</span>');
                    }

                    $('#modal-confirm').text('✓ Got It').prop('disabled', false);
                }

                handleError(xhr) {
                    console.error('AI matching error:', xhr);

                    let errorMsg = 'Network error. Please try again.';

                    if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
                        errorMsg = xhr.responseJSON.data.message;
                    }

                    this.showError(errorMsg);
                }
            }

            // Show Clusters Interface
            function showClustersInterface() {
                // Fetch clusters and display
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_get_clusters',
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            displayClustersModal(response.data.clusters, response.data.stats);
                        } else {
                            showErrorModal('Error', response.data.message || 'Failed to load clusters');
                        }
                    },
                    error: function() {
                        showErrorModal('Error', 'Network error loading clusters');
                    }
                });
            }

            function displayClustersModal(clusters, stats) {
                const modalBody = `
                    <div style="color: var(--brand-white);">
                        <!-- Stats Header -->
                        <div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 20px;">
                            <div style="background: rgba(139, 92, 246, 0.15); padding: 12px; border-radius: 8px; text-align: center; border: 1px solid rgba(139, 92, 246, 0.3);">
                                <div style="font-size: 24px; font-weight: 700; color: var(--brand-purple);">${stats.total_clusters || 0}</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light);">Clusters</div>
                            </div>
                            <div style="background: rgba(16, 185, 129, 0.15); padding: 12px; border-radius: 8px; text-align: center; border: 1px solid rgba(16, 185, 129, 0.3);">
                                <div style="font-size: 24px; font-weight: 700; color: var(--brand-success);">${stats.total_variants || 0}</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light);">Variants</div>
                            </div>
                            <div style="background: rgba(0, 188, 212, 0.15); padding: 12px; border-radius: 8px; text-align: center; border: 1px solid rgba(0, 188, 212, 0.3);">
                                <div style="font-size: 24px; font-weight: 700; color: var(--brand-primary);">${stats.unique_keywords || 0}</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light);">Unique</div>
                            </div>
                            <div style="background: rgba(245, 158, 11, 0.15); padding: 12px; border-radius: 8px; text-align: center; border: 1px solid rgba(245, 158, 11, 0.3);">
                                <div style="font-size: 24px; font-weight: 700; color: var(--brand-warning);">${Math.round(stats.avg_similarity * 100) || 0}%</div>
                                <div style="font-size: 11px; color: var(--brand-gray-light);">Avg Similarity</div>
                            </div>
                        </div>

                        <!-- Bulk Actions -->
                        ${clusters.length > 0 ? `
                        <div style="display: flex; gap: 12px; justify-content: center; margin-bottom: 20px; padding: 16px; background: rgba(139, 92, 246, 0.1); border-radius: 12px; border: 1px solid rgba(139, 92, 246, 0.3);">
                            <button type="button" id="accept-all-delete-variants" data-total-clusters="${clusters.length}" style="background: var(--brand-success); color: white; border: none; padding: 10px 20px; border-radius: 8px; font-size: 13px; cursor: pointer; font-weight: 600; box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3); transition: all 0.2s;">
                                ✅ Accept All & Delete Variants
                            </button>
                            <button type="button" id="expand-all-clusters" style="background: var(--brand-purple); color: white; border: none; padding: 10px 20px; border-radius: 8px; font-size: 13px; cursor: pointer; font-weight: 600; box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3); transition: all 0.2s;">
                                ▼ Expand All
                            </button>
                            <button type="button" id="collapse-all-clusters" style="background: var(--brand-gray); color: white; border: none; padding: 10px 20px; border-radius: 8px; font-size: 13px; cursor: pointer; font-weight: 600; display: none;">
                                ▲ Collapse All
                            </button>
                        </div>
                        ` : ''}

                        <!-- Clusters List -->
                        <div id="clusters-list" style="max-height: 500px; overflow-y: auto; padding-right: 8px;">
                            ${clusters.length === 0 ? '<div style="text-align: center; padding: 40px; color: var(--brand-gray-light);">No clusters found. All keywords are unique!</div>' : ''}
                        </div>
                    </div>
                `;

                // Show in larger modal
                $('#modal-title').html('🔗 Keyword Clusters (' + clusters.length + ')');
                $('#modal-body').html(modalBody);
                $('#modal-confirm').hide();
                $('#wisewand-modal').fadeIn(200);

                // Render each cluster
                if (clusters.length > 0) {
                    clusters.forEach((cluster, index) => {
                        const clusterCard = buildClusterCard(cluster, index + 1);
                        $('#clusters-list').append(clusterCard);
                    });
                }
            }

            function buildClusterCard(cluster, index) {
                const similarityPercent = Math.round((cluster.cluster_metrics.avg_similarity || 0) * 100);
                const similarityColor = similarityPercent >= 95 ? 'var(--brand-success)' :
                                       similarityPercent >= 85 ? 'var(--brand-warning)' :
                                       'var(--brand-error)';

                const variants = cluster.variants || [];
                const primary = cluster.primary_data || {};

                // Build ranking badge for primary keyword
                let rankingBadge = '';
                if (primary.is_ranking) {
                    const position = primary.position_abs || '?';
                    rankingBadge = `
                        <span style="background: linear-gradient(135deg, #f59e0b, #ef4444); color: white; padding: 4px 10px; border-radius: 12px; font-size: 11px; font-weight: 700; display: inline-block; margin-left: 8px; box-shadow: 0 2px 8px rgba(245, 158, 11, 0.4);">
                            🏆 #${position}
                        </span>
                    `;
                }

                // Build tier badge for primary keyword
                let tierBadge = '';
                const tierMap = {
                    'ranking': { emoji: '🏆', label: 'Ranking', color: '#f59e0b', bg: 'rgba(245, 158, 11, 0.15)' },
                    'published': { emoji: '✅', label: 'Published', color: '#10b981', bg: 'rgba(16, 185, 129, 0.15)' },
                    'scheduled': { emoji: '📅', label: 'Scheduled', color: '#3b82f6', bg: 'rgba(59, 130, 246, 0.15)' },
                    'planned': { emoji: '📝', label: 'Planned', color: '#8b5cf6', bg: 'rgba(139, 92, 246, 0.15)' },
                };

                const tier = tierMap[primary.priority_tier] || tierMap['planned'];
                tierBadge = `
                    <span style="background: ${tier.bg}; color: ${tier.color}; padding: 3px 8px; border-radius: 10px; font-size: 10px; font-weight: 700; display: inline-block; margin-left: 6px; border: 1px solid ${tier.color};">
                        ${tier.emoji} ${tier.label}
                    </span>
                `;

                // Build protection warning if primary is ranking
                let protectionWarning = '';
                if (primary.is_ranking && primary.is_protected) {
                    protectionWarning = `
                        <div style="background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.5); border-radius: 8px; padding: 10px; margin-bottom: 12px;">
                            <div style="font-size: 12px; color: #fbbf24; font-weight: 600; margin-bottom: 4px;">
                                🛡️ Protected Ranking Keyword
                            </div>
                            <div style="font-size: 11px; color: var(--brand-gray-light); line-height: 1.4;">
                                This keyword is currently ranking at position #${primary.position_abs || '?'}. It's protected from being deleted to prevent losing your ranking.
                            </div>
                        </div>
                    `;
                }

                let variantsHTML = '';
                variants.forEach(variant => {
                    // Build variant ranking badge
                    let variantRankingBadge = '';
                    if (variant.is_ranking) {
                        variantRankingBadge = `<span style="background: #ef4444; color: white; padding: 2px 6px; border-radius: 8px; font-size: 10px; font-weight: 700; margin-left: 6px;">🏆 #${variant.position_abs || '?'}</span>`;
                    }

                    // Build variant tier badge
                    let variantTierBadge = '';
                    if (variant.priority_tier) {
                        const vTier = tierMap[variant.priority_tier] || tierMap['planned'];
                        variantTierBadge = `<span style="background: ${vTier.bg}; color: ${vTier.color}; padding: 2px 6px; border-radius: 8px; font-size: 9px; font-weight: 700; margin-left: 4px; border: 1px solid ${vTier.color};">${vTier.emoji}</span>`;
                    }

                    // Disable radio if variant is protected ranking
                    const isProtected = variant.is_ranking && variant.is_protected;
                    const disabledAttr = isProtected ? 'disabled' : '';
                    const protectedWarningIcon = isProtected ? '<span style="color: #fbbf24; font-size: 14px; margin-left: 4px;" title="Protected ranking keyword">🛡️</span>' : '';

                    variantsHTML += `
                        <label style="display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: rgba(139, 92, 246, 0.05); border-radius: 6px; cursor: ${isProtected ? 'not-allowed' : 'pointer'}; margin-bottom: 6px; border: 1px solid rgba(139, 92, 246, 0.2); transition: all 0.2s; opacity: ${isProtected ? '0.6' : '1'};">
                            <input type="radio" name="cluster-${cluster.id}-primary" value="${variant.id}" data-cluster-id="${cluster.id}" class="cluster-primary-radio" style="width: auto; margin: 0;" ${disabledAttr}>
                            <div style="flex: 1;">
                                <div style="font-weight: 600; color: var(--brand-white); font-size: 13px;">
                                    ${escapeHtml(variant.keyword)}${variantRankingBadge}${variantTierBadge}${protectedWarningIcon}
                                </div>
                                <div style="font-size: 11px; color: var(--brand-gray-light); margin-top: 2px;">
                                    Vol: ${formatNumber(variant.search_volume)} | Priority: ${variant.priority_score || 0} | Difficulty: ${variant.difficulty || '-'}%
                                </div>
                            </div>
                        </label>
                    `;
                });

                return `
                    <div class="cluster-card" data-cluster-id="${cluster.id}" style="background: rgba(10, 14, 39, 0.6); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 12px; padding: 16px; margin-bottom: 16px; backdrop-filter: blur(10px);">
                        ${protectionWarning}

                        <!-- Header -->
                        <div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 16px;">
                            <div style="flex: 1;">
                                <div style="font-size: 11px; color: var(--brand-gray-light); margin-bottom: 4px;">CLUSTER #${index}</div>
                                <div style="font-size: 15px; font-weight: 700; color: var(--brand-white); margin-bottom: 6px;">
                                    🔗 ${escapeHtml(cluster.primary_keyword)}${rankingBadge}${tierBadge}
                                </div>
                                <div style="font-size: 12px; color: var(--brand-gray-light);">
                                    Vol: ${formatNumber(cluster.search_volume)} | Priority: ${cluster.priority_score || 0} | Intent: ${cluster.search_intent || 'N/A'}
                                </div>
                            </div>
                            <div style="text-align: right;">
                                <div style="background: ${similarityColor}; color: white; padding: 4px 12px; border-radius: 12px; font-size: 12px; font-weight: 700; display: inline-block;">
                                    ${similarityPercent}%
                                </div>
                                <div style="font-size: 10px; color: var(--brand-gray-light); margin-top: 4px;">
                                    ${variants.length} variant${variants.length > 1 ? 's' : ''}
                                </div>
                            </div>
                        </div>

                        <!-- Variants (Collapsible) -->
                        <div class="cluster-variants-toggle" data-cluster-id="${cluster.id}" style="cursor: pointer; padding: 8px; background: rgba(139, 92, 246, 0.1); border-radius: 6px; margin-bottom: 12px; transition: all 0.2s;">
                            <span class="toggle-arrow" style="color: var(--brand-white); font-weight: 600; font-size: 13px;">▼ Show ${variants.length} Variant${variants.length > 1 ? 's' : ''}</span>
                            <span style="color: var(--brand-gray-light); font-size: 11px; margin-left: 8px;">(click to expand)</span>
                        </div>

                        <div class="cluster-variants-list" data-cluster-id="${cluster.id}" style="display: none; margin-bottom: 16px;">
                            <div style="font-size: 12px; color: var(--brand-gray-light); margin-bottom: 8px;">Select a variant to make it the primary keyword:</div>
                            ${variantsHTML}
                        </div>

                        <!-- Actions -->
                        <div style="display: flex; gap: 8px; flex-wrap: wrap;">
                            <button type="button" class="btn-accept-delete-cluster" data-cluster-id="${cluster.id}" data-variant-count="${variants.length}" data-variants='${JSON.stringify(variants.map(v => v.keyword))}' style="background: var(--brand-success); color: white; border: none; padding: 6px 12px; border-radius: 6px; font-size: 12px; cursor: pointer; font-weight: 600;">
                                ✓ Accept & Delete Variants
                            </button>
                            <button type="button" class="btn-schedule-cluster" data-cluster-id="${cluster.id}" data-keyword="${escapeHtml(cluster.primary_keyword)}" style="background: var(--brand-primary); color: white; border: none; padding: 6px 12px; border-radius: 6px; font-size: 12px; cursor: pointer; font-weight: 600;">
                                📅 Schedule Primary
                            </button>
                            <button type="button" class="btn-ungroup-cluster" data-cluster-id="${cluster.id}" style="background: var(--brand-gray); color: white; border: none; padding: 6px 12px; border-radius: 6px; font-size: 12px; cursor: pointer; font-weight: 600;">
                                ❌ Not Duplicates
                            </button>
                        </div>
                    </div>
                `;
            }

            // Toggle cluster variants (event delegation)
            $(document).on('click', '.cluster-variants-toggle', function() {
                const clusterId = $(this).data('cluster-id');
                const $variantsList = $('.cluster-variants-list[data-cluster-id="' + clusterId + '"]');
                const $arrow = $(this).find('.toggle-arrow');

                $variantsList.slideToggle(200, function() {
                    // Update arrow direction
                    if ($variantsList.is(':visible')) {
                        $arrow.html($arrow.html().replace('▼ Show', '▲ Hide'));
                    } else {
                        $arrow.html($arrow.html().replace('▲ Hide', '▼ Show'));
                    }
                });
            });

            function escapeHtml(text) {
                const div = document.createElement('div');
                div.textContent = text;
                return div.innerHTML;
            }

            function formatNumber(num) {
                if (!num) return '0';
                return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
            }

            // Cluster Action: Change Primary
            $(document).on('change', '.cluster-primary-radio', function() {
                const newPrimaryId = $(this).val();
                const clusterId = $(this).data('cluster-id');

                if (!confirm('Set this keyword as the cluster primary?')) {
                    return;
                }

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_set_cluster_primary',
                        cluster_id: clusterId,
                        new_primary_id: newPrimaryId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            showSuccessModal('✅ Updated', 'Primary keyword updated successfully');
                            setTimeout(() => {
                                closeModal();
                                showClustersInterface(); // Refresh
                            }, 1500);
                        } else {
                            alert('❌ ' + (response.data?.message || 'Failed'));
                        }
                    }
                });
            });

            // Cluster Action: Ungroup (Not Duplicates)
            $(document).on('click', '.btn-ungroup-cluster', function() {
                const clusterId = $(this).data('cluster-id');

                if (!confirm('Mark these keywords as NOT duplicates? They won\'t be clustered together in future scans.')) {
                    return;
                }

                const $btn = $(this);
                $btn.prop('disabled', true).text('Ungrouping...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_ungroup_cluster',
                        cluster_id: clusterId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $('[data-cluster-id="' + clusterId + '"]').fadeOut(300);
                            setTimeout(() => {
                                showClustersInterface(); // Refresh
                            }, 500);
                        } else {
                            alert('❌ ' + (response.data?.message || 'Failed'));
                            $btn.prop('disabled', false).text('❌ Not Duplicates');
                        }
                    }
                });
            });

            // Cluster Action: Accept & Delete Variants
            $(document).on('click', '.btn-accept-delete-cluster', function() {
                const clusterId = $(this).data('cluster-id');
                const variantCount = $(this).data('variant-count');
                const variants = $(this).data('variants');
                const $btn = $(this);

                // Build variants list for confirmation
                let variantsList = '';
                if (Array.isArray(variants)) {
                    variants.forEach((v, i) => {
                        if (i < 10) { // Show max 10 in confirmation
                            variantsList += `\n  • ${v}`;
                        }
                    });
                    if (variants.length > 10) {
                        variantsList += `\n  • ... and ${variants.length - 10} more`;
                    }
                }

                // Strong confirmation dialog
                const confirmMessage = `⚠️ PERMANENT ACTION

This will DELETE ${variantCount} variant keyword${variantCount > 1 ? 's' : ''} from your library.
Only the primary keyword will be kept.

Variants to delete:${variantsList}

This cannot be undone. Are you sure?`;

                if (!confirm(confirmMessage)) {
                    return;
                }

                $btn.prop('disabled', true).text('⏳ Processing...');

                // First approve, then delete
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_approve_cluster',
                        cluster_id: clusterId,
                        nonce: wisewandSEO.nonce
                    },
                    success: () => {
                        // Now delete variants
                        $.ajax({
                            url: wisewandSEO.ajaxUrl,
                            type: 'POST',
                            data: {
                                action: 'wisewand_delete_cluster_variants',
                                cluster_id: clusterId,
                                nonce: wisewandSEO.nonce
                            },
                            success: function(response) {
                                if (response.success) {
                                    $btn.text('✅ Accepted').css('background', '#6b7280').prop('disabled', false);
                                    showSuccessModal('✅ Complete', `Cluster accepted. ${response.data.deleted} variant(s) deleted from library.`);

                                    setTimeout(() => {
                                        closeModal();
                                        loadLatestSnapshot(); // Refresh keywords table
                                    }, 2000);
                                } else {
                                    alert('❌ ' + (response.data?.message || 'Failed to delete variants'));
                                    $btn.prop('disabled', false).text('✓ Accept & Delete Variants');
                                }
                            }
                        });
                    },
                    error: () => {
                        alert('❌ Failed to approve cluster');
                        $btn.prop('disabled', false).text('✓ Accept & Delete Variants');
                    }
                });
            });

            // Cluster Action: Schedule Primary
            $(document).on('click', '.btn-schedule-cluster', function() {
                const keyword = $(this).data('keyword');
                const clusterId = $(this).data('cluster-id');

                // Find the keyword in the table and schedule it
                const $keywordRow = $('.col-keyword strong').filter(function() {
                    return $(this).text() === keyword;
                }).closest('tr');

                if ($keywordRow.length > 0) {
                    const $scheduleBtn = $keywordRow.find('.btn-schedule-saved');
                    if ($scheduleBtn.length > 0) {
                        $scheduleBtn.trigger('click');
                        closeModal();
                    }
                }
            });

            // Bulk Action: Accept All & Delete All Variants
            $(document).on('click', '#accept-all-delete-variants', function() {
                const clusterCards = $('.cluster-card');
                const totalClusters = clusterCards.length;
                let totalVariants = 0;
                const variantsList = [];

                // Count total variants and build list
                clusterCards.each(function() {
                    const $btn = $(this).find('.btn-accept-delete-cluster');
                    const variantCount = $btn.data('variant-count') || 0;
                    const variants = $btn.data('variants') || [];

                    totalVariants += variantCount;

                    if (Array.isArray(variants)) {
                        variants.forEach(v => {
                            if (variantsList.length < 15) { // Show max 15 in confirmation
                                variantsList.push(v);
                            }
                        });
                    }
                });

                // Build confirmation message
                let variantsListText = '';
                variantsList.forEach(v => {
                    variantsListText += `\n  • ${v}`;
                });
                if (totalVariants > 15) {
                    variantsListText += `\n  • ... and ${totalVariants - 15} more`;
                }

                const confirmMessage = `⚠️ PERMANENT BULK ACTION

This will:
1. Accept all ${totalClusters} clusters
2. DELETE ${totalVariants} variant keywords from your library
3. Keep only the ${totalClusters} primary keywords

Sample variants to delete:${variantsListText}

Total keywords removed: ${totalVariants}
This cannot be undone. Are you absolutely sure?`;

                if (!confirm(confirmMessage)) {
                    return;
                }

                const $btn = $(this);
                $btn.prop('disabled', true).text('⏳ Processing...');

                // Collect all cluster IDs
                const clusterIds = [];
                clusterCards.each(function() {
                    clusterIds.push($(this).data('cluster-id'));
                });

                let completed = 0;
                let approvedCount = 0;
                let deletedCount = 0;
                let errors = 0;

                // Process each cluster: approve then delete
                clusterIds.forEach(clusterId => {
                    // First approve
                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_approve_cluster',
                            cluster_id: clusterId,
                            nonce: wisewandSEO.nonce
                        },
                        success: () => {
                            approvedCount++;

                            // Then delete variants
                            $.ajax({
                                url: wisewandSEO.ajaxUrl,
                                type: 'POST',
                                data: {
                                    action: 'wisewand_delete_cluster_variants',
                                    cluster_id: clusterId,
                                    nonce: wisewandSEO.nonce
                                },
                                success: function(response) {
                                    if (response.success) {
                                        deletedCount += response.data.deleted || 0;
                                        $('.cluster-card[data-cluster-id="' + clusterId + '"] .btn-accept-delete-cluster')
                                            .text('✅ Accepted').css('background', '#6b7280');
                                    } else {
                                        errors++;
                                    }

                                    completed++;
                                    if (completed === clusterIds.length) {
                                        $btn.text(`✅ Complete (${deletedCount} deleted)`).prop('disabled', false);

                                        showSuccessModal('✅ All Clusters Accepted', `
                                            <strong>Bulk action complete!</strong><br><br>
                                            ✓ Approved: ${approvedCount} clusters<br>
                                            🗑️ Deleted: ${deletedCount} variant keywords<br>
                                            ${errors > 0 ? `⚠️ Errors: ${errors}<br>` : ''}
                                            <br>
                                            Your keyword library has been optimized.
                                        `);

                                        setTimeout(() => {
                                            closeModal();
                                            loadLatestSnapshot();
                                        }, 3000);
                                    }
                                },
                                error: () => {
                                    errors++;
                                    completed++;
                                }
                            });
                        },
                        error: () => {
                            errors++;
                            completed++;
                        }
                    });
                });
            });

            // Bulk Action: Expand All
            $(document).on('click', '#expand-all-clusters', function() {
                $('.cluster-variants-list').slideDown(200);
                $('.toggle-arrow').each(function() {
                    $(this).html($(this).html().replace('▼ Show', '▲ Hide'));
                });
                $('#expand-all-clusters').hide();
                $('#collapse-all-clusters').show();
            });

            // Bulk Action: Collapse All
            $(document).on('click', '#collapse-all-clusters', function() {
                $('.cluster-variants-list').slideUp(200);
                $('.toggle-arrow').each(function() {
                    $(this).html($(this).html().replace('▲ Hide', '▼ Show'));
                });
                $('#collapse-all-clusters').hide();
                $('#expand-all-clusters').show();
            });

            // Inline Edit: Author Dropdown (auto-save on change)
            $(document).on('change', '.keyword-author-select', function() {
                const $select = $(this);
                const keywordId = $select.data('keyword-id');
                const authorId = $select.val();

                console.log('Saving author:', keywordId, authorId);

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_save_keyword_author_categories',
                        keyword_id: keywordId,
                        author_id: authorId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            $select.css('background', '#d1fae5'); // Green flash
                            setTimeout(() => $select.css('background', '#ffffff'), 1000);
                        } else {
                            alert('Failed to save author');
                        }
                    }
                });
            });

            // Open Category Selection Modal (click on badges)
            $(document).on('click', '.open-category-modal', function() {
                const keywordId = $(this).data('keyword-id');
                const currentIds = $(this).data('category-ids') || [];
                openCategorySelectionModal(keywordId, currentIds);
            });

            function openCategorySelectionModal(keywordId, currentCategoryIds) {
                const allCats = wisewandSEO.allCategories || [];

                const modalBody = `<div style="color: var(--brand-white);"><input type="search" id="cat-search" placeholder="🔍 Search categories..." style="width: 100%; padding: 10px; border: 1px solid rgba(0, 188, 212, 0.3); border-radius: 6px; background: rgba(10, 14, 39, 0.6); color: #fff; font-size: 14px; margin-bottom: 16px;"><div id="sel-cats" style="margin-bottom: 16px; padding: 12px; background: rgba(16, 185, 129, 0.1); border-radius: 8px; border-left: 3px solid var(--brand-success); min-height: 50px;"><div style="font-size: 12px; font-weight: 600; margin-bottom: 8px; color: var(--brand-success);">✓ Selected (<span id="sel-count">0</span>)</div><div id="sel-badges" style="display: flex; gap: 6px; flex-wrap: wrap;"><span style="font-size: 11px; color: #94a3b8;">Click checkboxes below</span></div></div><div id="all-cats" style="max-height: 400px; overflow-y: auto; padding: 12px; background: rgba(10, 14, 39, 0.6); border-radius: 8px; border: 1px solid rgba(0, 188, 212, 0.2);"></div></div>`;

                showModal('📁 Select Categories', modalBody, '💾 Save', function() {
                    const sel = $('.cat-cb:checked').map(function() { return parseInt($(this).data('cat-id')); }).get();
                    $('#modal-confirm').prop('disabled', true).text('💾 Saving...');
                    $.ajax({ url: wisewandSEO.ajaxUrl, type: 'POST', data: { action: 'wisewand_save_keyword_author_categories', keyword_id: keywordId, category_ids: sel, nonce: wisewandSEO.nonce }, success: (r) => { if (r.success) { $('#modal-confirm').text('✅ Saved!'); setTimeout(() => { closeModal(); location.reload(); }, 800); } else { alert('Failed'); $('#modal-confirm').prop('disabled', false).text('💾 Save'); } } });
                });

                const $list = $('#all-cats');
                allCats.forEach(c => {
                    const chk = currentCategoryIds.includes(c.id) ? 'checked' : '';
                    const nm = c.parent_name ? c.parent_name + ' > ' + c.name : c.name;
                    $list.append(`<label class="cat-item" data-name="${nm.toLowerCase()}" style="display: flex; align-items: center; gap: 10px; padding: 10px; cursor: pointer; border-radius: 6px; margin-bottom: 2px; border: 1px solid transparent;"><input type="checkbox" class="cat-cb" data-cat-id="${c.id}" data-cat-name="${c.name}" ${chk} style="width: auto; margin: 0;"><span style="font-size: 13px; color: #fff;">${nm}</span></label>`);
                });

                $(document).on('mouseenter', '.cat-item', function() { $(this).css({'background': 'rgba(0, 188, 212, 0.1)', 'border-color': 'rgba(0, 188, 212, 0.3)'}); });
                $(document).on('mouseleave', '.cat-item', function() { $(this).css({'background': 'transparent', 'border-color': 'transparent'}); });
                $(document).on('change', '.cat-cb', upSel);
                $('#cat-search').on('input', function() { const s = $(this).val().toLowerCase(); $('.cat-item').each(function() { $(this).toggle(($(this).data('name') || '').includes(s)); }); });

                upSel();

                function upSel() {
                    const $s = $('.cat-cb:checked');
                    const cnt = $s.length;
                    $('#sel-count').text(cnt);
                    const $b = $('#sel-badges');
                    if (cnt === 0) {
                        $b.html('<span style="font-size: 11px; color: #94a3b8;">Click checkboxes below</span>');
                    } else {
                        $b.empty();
                        $s.each(function() {
                            const n = $(this).data('cat-name');
                            const i = $(this).data('cat-id');
                            $b.append(`<span style="font-size: 11px; color: #1e293b; background: #e0f2fe; padding: 4px 8px; border-radius: 4px; display: inline-flex; align-items: center; gap: 4px;">${n} <button type="button" onclick="$('.cat-cb[data-cat-id=${i}]').prop('checked', false).trigger('change')" style="background: none; border: none; color: #64748b; cursor: pointer; padding: 0;">×</button></span>`);
                        });
                    }
                }
            }

            // Column Visibility Toggle
            $('#toggle-columns-btn').on('click', function() {
                $('#column-visibility-panel').slideToggle(200);
            });

            // Load saved column preferences
            function loadColumnPreferences() {
                const savedPrefs = localStorage.getItem('wisewand_column_prefs');
                if (savedPrefs) {
                    try {
                        const prefs = JSON.parse(savedPrefs);
                        Object.keys(prefs).forEach(column => {
                            const isVisible = prefs[column];
                            $(`.column-toggle[data-column="${column}"]`).prop('checked', isVisible);
                            toggleColumn(column, isVisible);
                        });
                    } catch(e) {
                        console.error('Error loading column preferences:', e);
                    }
                }
            }

            // Toggle column visibility
            function toggleColumn(columnName, isVisible) {
                const $table = $('.seo-table');
                if (isVisible) {
                    $table.find(`[data-column="${columnName}"]`).show();
                    $table.find(`[data-column-target="${columnName}"]`).show();
                } else {
                    $table.find(`[data-column="${columnName}"]`).hide();
                    $table.find(`[data-column-target="${columnName}"]`).hide();
                }
            }

            // Save column preferences
            function saveColumnPreferences() {
                const prefs = {};
                $('.column-toggle').each(function() {
                    const column = $(this).data('column');
                    prefs[column] = $(this).is(':checked');
                });

                localStorage.setItem('wisewand_column_prefs', JSON.stringify(prefs));

                // Also save to database for cross-device sync
                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_save_column_preferences',
                        preferences: JSON.stringify(prefs),
                        nonce: wisewandSEO.nonce
                    }
                });
            }

            // Handle column toggle clicks
            $('.column-toggle').on('change', function() {
                const column = $(this).data('column');
                const isVisible = $(this).is(':checked');

                toggleColumn(column, isVisible);
                saveColumnPreferences();
            });

            // Load preferences on page ready
            loadColumnPreferences();

            // Generate Smart Roadmap - Enhanced Modal with Two Buttons

            // Update "Schedule Selected" button visibility based on checkbox selections
            function updateScheduleSelectedButton() {
                // Count only VISIBLE checked boxes to match what user sees
                const selectedCount = $('.select-keyword-row:visible:checked').length;

                if (selectedCount > 0) {
                    $('#schedule-selected-roadmap')
                        .show()
                        .find('.selected-keywords-count')
                        .text(selectedCount);
                } else {
                    $('#schedule-selected-roadmap').hide();
                }
            }

            // Update button visibility when checkboxes change
            $('.seo-table').on('change', '.select-keyword-row', updateScheduleSelectedButton);
            $('.select-all-keywords').on('change', function() {
                setTimeout(updateScheduleSelectedButton, 100);
            });

            // Button A: Generate All Keywords
            $('#generate-all-roadmap').on('click', function() {
                console.log('=== ROADMAP: Generate All clicked ===');
                openRoadmapModal('all');
            });

            // Button B: Schedule Selected Keywords
            $('#schedule-selected-roadmap').on('click', function() {
                console.log('=== ROADMAP: Schedule Selected clicked ===');
                // Count only VISIBLE checked boxes to match what user sees
                const selectedCount = $('.select-keyword-row:visible:checked').length;
                if (selectedCount === 0) {
                    alert('Please select keywords first');
                    return;
                }
                openRoadmapModal('selected');
            });

            // Extract modal opening logic to function
            function openRoadmapModal(selectionMode) {
                console.log('=== ROADMAP: Opening modal with mode:', selectionMode, '===');

                const marketValue = $('#market-selector').val();
                console.log('Market selector value:', marketValue);

                if (!marketValue) {
                    alert('Error: Market selector not found');
                    return;
                }

                const [language, location] = marketValue.split(':');
                console.log('Language:', language, 'Location:', location);

                // Count selected keywords in table
                // Count only VISIBLE checked boxes to match what user sees
                const selectedCount = $('.select-keyword-row:visible:checked').length;
                const totalKeywords = $('.seo-table tbody tr').length;

                console.log('Selected:', selectedCount, 'Total:', totalKeywords);
                // Phase 5: Part D - Allow today as start date
                const today = new Date();
                const todayStr = today.toISOString().split('T')[0];

                // Build modal title based on selection mode
                let modalTitle = '🚀 Generate Smart Roadmap';
                if (selectionMode === 'selected') {
                    modalTitle += ` (${selectedCount} Selected Keywords)`;
                }

                const modalBody = `
                    <div class="modal-form-group">
                        <label>📊 Keyword Selection</label>
                        <select id="roadmap-keyword-source" class="modal-select">
                            <option value="auto" ${selectionMode === 'all' ? 'selected' : ''}>🤖 Auto-Select Best Keywords (Smart AI Selection)</option>
                            <option value="selected" ${selectionMode === 'selected' ? 'selected' : ''} ${selectedCount === 0 ? 'disabled' : ''}>✅ Use Selected from Table (${selectedCount} selected)</option>
                            <option value="all" ${selectionMode === 'all' ? '' : ''}>📚 All Keywords in Table (${totalKeywords} total)</option>
                        </select>
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 6px;">
                            ${selectionMode === 'selected' ? '✅ Using your selected keywords from the table' : (selectedCount === 0 ? '💡 Tip: Select keywords in the table to enable "Use Selected" option' : 'Choose how to select keywords')}
                        </p>
                    </div>

                    <div class="modal-form-group">
                        <label>🌍 Language Filter</label>
                        <select id="roadmap-language-filter" class="modal-select">
                            <option value="loading">⏳ Loading available languages...</option>
                        </select>
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 6px;">
                            Select a specific language or choose "All Languages" to mix multiple languages in one roadmap
                        </p>
                    </div>

                    <div class="modal-form-group">
                        <label>📅 Publishing Frequency</label>
                        <div style="display: flex; gap: 12px; align-items: center;">
                            <input type="number" id="roadmap-posts-count" min="1" max="50" value="1" class="modal-input" style="width: 80px;">
                            <span style="color: var(--brand-white);">posts per</span>
                            <select id="roadmap-period-type" class="modal-select" style="flex: 1;">
                                <option value="day">Day</option>
                                <option value="week">Week</option>
                            </select>
                        </div>
                        <div id="roadmap-duration-preview" style="margin-top: 10px; padding: 10px; background: rgba(0, 188, 212, 0.1); border-radius: 8px; border-left: 3px solid var(--brand-primary);">
                            <span style="color: var(--brand-primary); font-weight: 600; font-size: 13px;">
                                📊 Roadmap Duration: <span id="duration-text">Calculating...</span>
                            </span>
                        </div>
                    </div>

                    <div class="modal-form-group">
                        <label>🗓️ Start Date</label>
                        <input type="date" id="roadmap-start-date" class="modal-input" value="${todayStr}" min="${todayStr}">
                    </div>

                    <div class="modal-form-group" style="margin-top: 16px;">
                        <label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
                            <input type="checkbox" id="roadmap-generate-ai-instructions"
                                   ${wisewandSEO.defaultAutoGenerateInstructions ? 'checked' : ''}
                                   ${wisewandSEO.openaiConfigured ? '' : 'disabled'}
                                   style="width: auto;">
                            <span style="font-weight: 600;">🤖 Generate AI Instructions with ChatGPT</span>
                            ${!wisewandSEO.openaiConfigured ? '<span style="color: #f59e0b; font-size: 10px;">⚠️ No API Key</span>' : '<span style="color: #10b981; font-size: 10px;">~$0.0001 per entry</span>'}
                        </label>
                        <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 6px; margin-left: 24px;">
                            ${wisewandSEO.openaiConfigured ? 'Generates specific Search Intention, Additional Instructions, and Avoid Information for each entry. Adds ~2-3 seconds per keyword to generation time.' : 'Configure OpenAI API key in Settings → OpenAI to enable'}
                        </p>
                    </div>

                    <details style="margin-top: 12px;">
                        <summary style="cursor: pointer; color: var(--brand-primary); font-weight: 600; font-size: 13px; margin-bottom: 12px;">⚙️ Advanced Settings</summary>
                        <div style="padding: 12px; background: rgba(0, 188, 212, 0.05); border-radius: 8px; margin-top: 8px;">
                            <div class="modal-form-group">
                                <label style="display: flex; align-items: center; gap: 8px; cursor: pointer; text-transform: none;">
                                    <input type="checkbox" id="roadmap-detect-cannibalisation" checked style="width: auto;">
                                    <span>🔍 Detect Content Cannibalisation (Recommended)</span>
                                </label>
                                <p style="font-size: 11px; color: var(--brand-gray-light); margin-top: 4px; margin-left: 24px;">
                                    Checks if keywords already have existing content and suggests updates instead of duplicates
                                </p>
                            </div>
                        </div>
                    </details>

                    <div id="roadmap-modal-feedback"></div>
                `;

                showModal(modalTitle, modalBody, '🚀 Generate Roadmap', function() {
                    generateEnhancedRoadmap(selectionMode);
                });

                // Load available languages dynamically
                loadAvailableLanguages();

                function loadAvailableLanguages() {
                    console.log('Loading available languages...');

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_get_available_languages',
                            domain: wisewandSEO.domain,
                            language_code: language, // Current language from market selector
                            location_code: parseInt(location),
                            nonce: wisewandSEO.nonce
                        },
                        success: function(response) {
                            if (response.success && response.data.languages) {
                                const languages = response.data.languages;
                                const $select = $('#roadmap-language-filter');
                                $select.empty();

                                // Add "All Languages" option first
                                $select.append(`<option value="all">🌍 All Languages (${response.data.total_keywords} keywords)</option>`);

                                // Add each detected language with count
                                languages.forEach(lang => {
                                    $select.append(`<option value="${lang.code}">${lang.name} (${lang.count} keywords)</option>`);
                                });

                                // Update duration preview when language changes
                                $select.on('change', updateDurationPreview);

                                console.log('Languages loaded:', languages);
                            } else {
                                console.error('Failed to load languages:', response);
                                $('#roadmap-language-filter').html('<option value="all">🌍 All Languages</option>');
                            }
                        },
                        error: function(xhr, status, error) {
                            console.error('Error loading languages:', error);
                            $('#roadmap-language-filter').html('<option value="all">🌍 All Languages</option>');
                        }
                    });
                }

                // Real-time duration calculation with language filtering
                function updateDurationPreview() {
                    const postsPerPeriod = parseInt($('#roadmap-posts-count').val()) || 1;
                    const periodType = $('#roadmap-period-type').val();
                    const keywordSource = $('#roadmap-keyword-source').val();
                    const selectedLang = $('#roadmap-language-filter').val();

                    // Get keyword count based on language filter
                    let keywordCount = totalKeywords;

                    // If specific language selected, count matching rows
                    if (selectedLang && selectedLang !== 'all' && selectedLang !== 'loading') {
                        keywordCount = $(`.seo-table tbody tr[data-language="${selectedLang}"]`).length;
                    }

                    // Apply keyword selection strategy
                    if (keywordSource === 'selected') {
                        // Count selected keywords (optionally filtered by language)
                        if (selectedLang && selectedLang !== 'all' && selectedLang !== 'loading') {
                            // Count only VISIBLE checked boxes to match what user sees
                            keywordCount = $(`.seo-table tbody tr[data-language="${selectedLang}"] .select-keyword-row:visible:checked`).length;
                        } else {
                            keywordCount = selectedCount;
                        }
                    } else if (keywordSource === 'auto') {
                        keywordCount = Math.min(keywordCount, 180); // Max 6 months
                    }

                    let duration = 0;
                    if (periodType === 'day') {
                        duration = Math.ceil(keywordCount / postsPerPeriod);
                    } else if (periodType === 'week') {
                        duration = Math.ceil((keywordCount / postsPerPeriod) * 7);
                    }

                    const durationText = periodType === 'day'
                        ? `${duration} days (${keywordCount} keywords ÷ ${postsPerPeriod} per day)`
                        : `${duration} days (${keywordCount} keywords ÷ ${postsPerPeriod} per week)`;

                    $('#duration-text').text(durationText);
                }

                $('#roadmap-posts-count, #roadmap-period-type, #roadmap-keyword-source, #roadmap-language-filter').on('change input', updateDurationPreview);
                updateDurationPreview();

                function generateEnhancedRoadmap() {
                    const postsPerPeriod = parseInt($('#roadmap-posts-count').val()) || 1;
                    const periodType = $('#roadmap-period-type').val();
                    const startDate = $('#roadmap-start-date').val();
                    const keywordSource = $('#roadmap-keyword-source').val();
                    const detectCannibalisation = $('#roadmap-detect-cannibalisation').is(':checked');
                    const generateAIInstructions = $('#roadmap-generate-ai-instructions').is(':checked');
                    const selectedLanguage = $('#roadmap-language-filter').val() || 'all';

                    console.log('🌍 Generating roadmap for language:', selectedLanguage);
                    console.log('🤖 Generate AI Instructions:', generateAIInstructions);

                    // Validate language is loaded
                    if (selectedLanguage === 'loading') {
                        $('#roadmap-modal-feedback').html('<div class="modal-error">⏳ Please wait for languages to load...</div>');
                        return;
                    }

                    // Get selected keywords if applicable
                    let selectedKeywords = [];
                    if (keywordSource === 'selected') {
                        // CRITICAL FIX: Only collect VISIBLE checked keywords (respects filters)
                        selectedKeywords = $('.select-keyword-row:visible:checked').map(function() {
                            return $(this).closest('tr').find('.col-keyword strong').text();
                        }).get();

                        if (selectedKeywords.length === 0) {
                            $('#roadmap-modal-feedback').html('<div class="modal-error">No keywords selected. Please select keywords from the table first.</div>');
                            return;
                        }
                    }

                    $('#modal-confirm').prop('disabled', true).text('🚀 Generating...');
                    $('#roadmap-modal-feedback').html('<div class="modal-info">⏳ Analyzing keywords and generating roadmap...</div>');

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_generate_smart_roadmap',
                            domain: wisewandSEO.domain,
                            language_code: selectedLanguage, // Use selected language from filter!
                            location_code: parseInt(location),
                            posts_per_period: postsPerPeriod,
                            period_type: periodType,
                            start_date: startDate, // Phase 5: Part C - Send start date
                            keyword_selection: keywordSource,
                            selected_keywords: JSON.stringify(selectedKeywords),
                            detect_cannibalisation: detectCannibalisation,
                            generate_ai_instructions: generateAIInstructions ? 1 : 0, // Send explicit integer (0 or 1)
                            nonce: wisewandSEO.nonce
                        },
                        success: function(response) {
                            console.log('Roadmap AJAX success callback:', response);
                            console.log('Response type:', typeof response);
                            console.log('Response.success:', response?.success);
                            console.log('Response.data:', response?.data);

                            if (response && response.success) {
                                const data = response.data;

                                // Check if AI instructions should be generated
                                if (data.generate_ai_instructions && data.created_entry_ids && data.created_entry_ids.length > 0) {
                                    console.log('🤖 Starting AI Instructions generation for', data.created_entry_ids.length, 'entries');

                                    // Show initial success + start AI generation
                                    const msg = `
                                        <strong>✅ Roadmap Created! (${data.total_scheduled} entries)</strong><br><br>
                                        <strong>🤖 Now generating AI Instructions...</strong><br>
                                        This will take ~2-3 seconds per entry.
                                    `;
                                    $('#roadmap-modal-feedback').html('<div class="modal-info">' + msg + '</div>');
                                    $('#modal-confirm').text('⏳ Generating AI Instructions...').prop('disabled', true);

                                    // Start client-side batch processing
                                    processAIInstructionsBatch(data.created_entry_ids, data);
                                } else {
                                    // No AI generation - show standard success
                                    const msg = `
                                        <strong>✅ Roadmap Generated Successfully!</strong><br><br>
                                        📊 Total Scheduled: <strong>${data.total_scheduled}</strong> keywords<br>
                                        🆕 New Content: <strong>${data.creates}</strong><br>
                                        🔄 Updates: <strong>${data.updates}</strong><br>
                                        ${data.skipped > 0 ? `⏭️ Skipped: <strong>${data.skipped}</strong><br>` : ''}
                                        <br>
                                        🎯 Cannibalisation Risk:<br>
                                        • None: ${data.by_risk.none}<br>
                                        • Low: ${data.by_risk.low}<br>
                                        • Medium: ${data.by_risk.medium}<br>
                                        • High: ${data.by_risk.high}<br>
                                        <br>
                                        📅 Date Range: ${data.date_start} to ${data.date_end}<br>
                                        ⏱️ Duration: ${data.total_days} days
                                    `;
                                    $('#roadmap-modal-feedback').html('<div class="modal-success">' + msg + '</div>');
                                    $('#modal-confirm').text('✅ Done').prop('disabled', false);

                                    setTimeout(() => {
                                        closeModal();
                                    }, 3000);
                                }
                            } else {
                                console.error('Roadmap generation failed:', response);
                                const errorDetail = response?.data?.message || 'Unknown error';
                                $('#roadmap-modal-feedback').html(`
                                    <div class="modal-error">
                                        ❌ Failed to generate roadmap<br><br>
                                        <strong>Error:</strong> ${errorDetail}<br><br>
                                        <strong>Debug Info:</strong><br>
                                        • Check browser console (F12) for response details<br>
                                        • Check WordPress Admin → Wisewand → Logs<br>
                                        • Response logged above in console
                                    </div>
                                `);
                                $('#modal-confirm').prop('disabled', false).text('🚀 Retry');
                            }
                        },
                        error: function(xhr, status, error) {
                            console.error('Roadmap AJAX error:', {
                                status: xhr.status,
                                statusText: xhr.statusText,
                                responseText: xhr.responseText,
                                error: error,
                                fullXHR: xhr
                            });

                            let errorMsg = 'Connection error';
                            try {
                                const parsed = JSON.parse(xhr.responseText);
                                errorMsg = parsed.data?.message || parsed.message || errorMsg;
                            } catch(e) {
                                errorMsg = xhr.responseText || ('HTTP ' + xhr.status);
                            }

                            $('#roadmap-modal-feedback').html(`
                                <div class="modal-error">
                                    ❌ AJAX Error<br><br>
                                    <strong>Status:</strong> ${xhr.status} ${xhr.statusText}<br>
                                    <strong>Error:</strong> ${errorMsg}<br><br>
                                    <strong>Full error logged in console</strong> - Press F12 to view
                                </div>
                            `);
                            $('#modal-confirm').prop('disabled', false).text('🚀 Retry');
                        }
                    });
                }

                // AI Instructions Batch Processing (client-side to avoid timeout)
                function processAIInstructionsBatch(entryIds, roadmapData) {
                    const totalEntries = entryIds.length;
                    let currentIndex = 0;
                    let successful = 0;
                    let failed = 0;
                    const startTime = Date.now();

                    console.log('🤖 AI Instructions Batch: Starting for', totalEntries, 'entries');

                    // OpenAI GPT-4o-mini pricing: $0.150 per 1M input tokens, $0.600 per 1M output tokens
                    // Estimated: ~500 input + ~300 output tokens per request = ~$0.00027 per entry
                    const estimatedCost = (totalEntries * 0.00027).toFixed(3);
                    const estimatedTime = Math.ceil(totalEntries * 2.5); // ~2.5 sec per entry with delays

                    // Format seconds to "Xm Ys" or "Xs"
                    function formatTime(seconds) {
                        if (seconds < 60) {
                            return seconds + 's';
                        }
                        const minutes = Math.floor(seconds / 60);
                        const secs = seconds % 60;
                        return minutes + 'm ' + secs + 's';
                    }

                    function processNext() {
                        if (currentIndex >= totalEntries) {
                            showBatchComplete();
                            return;
                        }

                        const entryId = entryIds[currentIndex];
                        const progress = Math.round(((currentIndex + 1) / totalEntries) * 100);
                        const elapsed = Math.round((Date.now() - startTime) / 1000);
                        const avgTimePerEntry = currentIndex > 0 ? elapsed / currentIndex : 2.5;
                        const remaining = Math.ceil((totalEntries - currentIndex) * avgTimePerEntry);

                        updateBatchProgress(currentIndex + 1, totalEntries, progress, elapsed, remaining);

                        console.log(`🤖 Processing entry ${currentIndex + 1}/${totalEntries} (ID: ${entryId})`);

                        $.ajax({
                            url: wisewandSEO.ajaxUrl,
                            type: 'POST',
                            timeout: 30000,
                            data: {
                                action: 'wisewand_generate_instructions_ai',
                                entry_id: entryId,
                                nonce: wisewandSEO.calendarNonce
                            },
                            success: function(response) {
                                if (response.success) {
                                    successful++;
                                    console.log(`✅ Entry ${entryId}: AI instructions generated`);
                                } else {
                                    failed++;
                                    console.warn(`⚠️ Entry ${entryId}: Generation failed -`, response.data?.message);
                                }

                                currentIndex++;
                                setTimeout(processNext, 1000); // 1 sec delay between calls (rate limiting)
                            },
                            error: function(xhr, status, error) {
                                failed++;
                                console.error(`❌ Entry ${entryId}: AJAX error -`, error);

                                currentIndex++;
                                setTimeout(processNext, 1000);
                            }
                        });
                    }

                    function updateBatchProgress(current, total, percent, elapsed, remaining) {
                        const msg = `
                            <div style="background: rgba(59, 130, 246, 0.1); border: 1px solid rgba(59, 130, 246, 0.3); border-radius: 12px; padding: 20px;">
                                <div style="font-size: 16px; font-weight: 600; color: var(--brand-white); margin-bottom: 16px;">
                                    ✅ Roadmap Created - 🤖 Generating AI Instructions
                                </div>

                                <div style="margin-bottom: 16px;">
                                    <div style="display: flex; justify-content: space-between; margin-bottom: 8px; font-size: 13px; color: var(--brand-white);">
                                        <span>Processing entry ${current} of ${total}</span>
                                        <span style="color: var(--brand-primary); font-weight: 600;">${percent}%</span>
                                    </div>
                                    <div style="background: rgba(160, 168, 184, 0.2); border-radius: 12px; height: 12px; overflow: hidden; border: 1px solid rgba(59, 130, 246, 0.3);">
                                        <div style="background: linear-gradient(90deg, #10b981 0%, #3b82f6 100%); height: 100%; width: ${percent}%; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 0 12px rgba(59, 130, 246, 0.5);"></div>
                                    </div>
                                </div>

                                <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; font-size: 12px;">
                                    <div style="text-align: center; padding: 8px; background: rgba(16, 185, 129, 0.1); border-radius: 6px;">
                                        <div style="color: var(--brand-success); font-weight: 600;">${successful}</div>
                                        <div style="color: var(--brand-gray-light);">Successful</div>
                                    </div>
                                    <div style="text-align: center; padding: 8px; background: rgba(59, 130, 246, 0.1); border-radius: 6px;">
                                        <div style="color: var(--brand-primary); font-weight: 600;">${formatTime(elapsed)}</div>
                                        <div style="color: var(--brand-gray-light);">Elapsed</div>
                                    </div>
                                    <div style="text-align: center; padding: 8px; background: rgba(251, 191, 36, 0.1); border-radius: 6px;">
                                        <div style="color: var(--brand-warning); font-weight: 600;">~${formatTime(remaining)}</div>
                                        <div style="color: var(--brand-gray-light);">Remaining</div>
                                    </div>
                                </div>

                                <div style="margin-top: 12px; padding: 10px; background: rgba(59, 130, 246, 0.05); border-radius: 6px; font-size: 11px; color: var(--brand-gray-light);">
                                    💡 Estimated cost: ~$${estimatedCost} | GPT-4o-mini
                                </div>
                            </div>
                        `;
                        $('#roadmap-modal-feedback').html(msg);
                    }

                    function showBatchComplete() {
                        const elapsed = Math.round((Date.now() - startTime) / 1000);
                        const actualCost = (successful * 0.00027).toFixed(4);

                        const msg = `
                            <div style="background: rgba(16, 185, 129, 0.1); border: 2px solid #10b981; border-radius: 12px; padding: 20px;">
                                <div style="font-size: 18px; font-weight: 700; color: #10b981; margin-bottom: 16px;">
                                    ✅ Roadmap Complete with AI Instructions!
                                </div>

                                <div style="color: var(--brand-white); line-height: 1.8; font-size: 13px;">
                                    <strong>📊 Roadmap Summary:</strong><br>
                                    • Total Entries: <strong>${roadmapData.total_scheduled}</strong><br>
                                    • Date Range: ${roadmapData.date_start} to ${roadmapData.date_end} (${roadmapData.total_days} days)<br>
                                    <br>
                                    <strong>🤖 AI Instructions:</strong><br>
                                    • Successfully Generated: <strong style="color: #10b981;">${successful}</strong><br>
                                    ${failed > 0 ? `• Failed: <strong style="color: #f59e0b;">${failed}</strong> (entries will have blank instructions)<br>` : ''}
                                    • Processing Time: <strong>${formatTime(elapsed)}</strong><br>
                                    • Actual Cost: ~$${actualCost}<br>
                                    <br>
                                    <strong>✨ All entries now have context-aware AI instructions!</strong><br>
                                    View Editorial Calendar to review and edit entries.
                                </div>
                            </div>
                        `;

                        $('#roadmap-modal-feedback').html(msg);
                        $('#modal-confirm').text('✅ Done').prop('disabled', false).off('click').on('click', () => {
                            closeModal();
                            location.reload(); // Reload to show updated calendar
                        });

                        console.log('🤖 AI Instructions Batch Complete:', {
                            total: totalEntries,
                            successful: successful,
                            failed: failed,
                            elapsed: elapsed + 's',
                            cost: '$' + actualCost
                        });
                    }

                    processNext(); // Start processing
                }
            } // End of openRoadmapModal function


            // Remove keyword from calendar
            $(document).on('click', '.btn-remove-from-calendar', function(e) {
                e.stopPropagation();
                const calendarId = $(this).data('calendar-id');
                const keyword = $(this).data('keyword');

                if (!confirm(`Remove "${keyword}" from calendar?\n\nThis will cancel the scheduled article but keep the keyword in your library.`)) {
                    return;
                }

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_remove_from_calendar',
                        calendar_id: calendarId,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            loadLatestSnapshot(); // Refresh table
                        } else {
                            alert('Failed: ' + (response.data?.message || 'Unknown error'));
                        }
                    }
                });
            });

            // Clear all calendar entries
            $('#clear-all-calendar-btn').on('click', function() {
                // Count all entries in calendar (check via AJAX first)
                const $btn = $(this);

                if (!confirm('🗑️ Clear ALL Calendar Entries?\n\nThis will:\n• Delete all scheduled, generating, and pending articles\n• Keep already published posts\n• Keep keywords in your library\n• Cannot be undone\n\nAre you sure?')) {
                    return;
                }
                $btn.prop('disabled', true).text('🗑️ Clearing...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_clear_all_calendar',
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            alert(`✅ ${response.data.deleted_count} entries cleared from calendar`);
                            loadLatestSnapshot(); // Refresh table
                        } else {
                            alert('Failed: ' + (response.data?.message || 'Unknown error'));
                        }
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('🗑️ Clear Calendar');
                    }
                });
            });

            // Manual keywords - Add to calendar
            $('#add-manual-keywords').on('click', function() {
                const keywords = $('#manual-keywords').val().trim();
                if (!keywords) {
                    alert('Please enter at least one keyword');
                    return;
                }

                const $btn = $(this);
                $btn.prop('disabled', true).text('📅 Adding...');

                $.ajax({
                    url: wisewandSEO.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'wisewand_add_manual_keywords',
                        keywords: keywords,
                        nonce: wisewandSEO.nonce
                    },
                    success: function(response) {
                        if (response.success) {
                            alert('✅ Added ' + response.data.success_count + ' keyword(s) to calendar!\n\n' + response.data.message);
                            $('#manual-keywords').val('');
                            $('#manual-results').html(response.data.summary_html || '');
                        } else {
                            alert('❌ ' + (response.data?.message || 'Failed'));
                        }
                    },
                    error: function() {
                        alert('❌ Connection error');
                    },
                    complete: function() {
                        $btn.prop('disabled', false).text('📅 Add to Calendar');
                    }
                });
            });

            // Schedule keyword button click handler
            $(document).on('click', '.btn-schedule', function(e) {
                e.preventDefault();
                const $btn = $(this);
                const keywordData = JSON.parse($btn.attr('data-keyword-data'));

                if (confirm('Schedule "' + keywordData.keyword + '" for publication?\n\nThis will add it to the Editorial Calendar where you can set the publication date and customize the article settings.')) {
                    $btn.prop('disabled', true).text('📅 Scheduling...');

                    $.ajax({
                        url: wisewandSEO.ajaxUrl,
                        type: 'POST',
                        data: {
                            action: 'wisewand_schedule_keyword',
                            keyword_data: keywordData,
                            nonce: wisewandSEO.nonce
                        },
                        success: function(response) {
                            if (response.success) {
                                alert('✅ Keyword scheduled successfully!\n\nPublication Date: ' + response.data.publication_date + '\n\nYou can view and edit it in the Editorial Calendar.');
                                $btn.text('✓ Scheduled').css('background', '#6b7280');
                            } else {
                                alert('❌ Failed to schedule keyword:\n' + (response.data?.message || 'Unknown error'));
                                $btn.prop('disabled', false).text('📅 Schedule');
                            }
                        },
                        error: function(xhr, status, error) {
                            console.error('Schedule error:', xhr.responseText);
                            alert('❌ Schedule failed: ' + error);
                            $btn.prop('disabled', false).text('📅 Schedule');
                        }
                    });
                }
            });

        });
