<?php
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.Security.EscapeOutput.ExceptionNotEscaped,WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQuery,PluginCheck.Security.DirectDB.UnescapedDBParameter,WordPress.WP.AlternativeFunctions.file_system_operations_fopen,WordPress.WP.AlternativeFunctions.file_system_operations_fclose,WordPress.WP.AlternativeFunctions.file_system_operations_is_writable,WordPress.WP.AlternativeFunctions.file_system_operations_chmod,WordPress.WP.AlternativeFunctions.file_system_operations_rmdir,WordPress.DateTime.RestrictedFunctions.date_date,WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.MissingTranslatorsComment,WordPress.WP.I18n.MissingArgDomain,WordPressVIPMinimum.Performance.WPQueryParams.SuppressFilters_suppress_filters,WordPress.WP.EnqueuedResources.NonEnqueuedScript,WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet -- WordPress.org PCP audit pass: legacy controlled-beta surfaces require targeted follow-up hardening.
// If this file is called directly, abort.
if (!defined('WPINC')) {
    die;
}

$aysa_saved_keyword_subtab = 'gsc_v2';
if (isset($this) && is_object($this) && method_exists($this, 'aysa_get_last_keyword_discovery_subtab')) {
    $aysa_saved_keyword_subtab = (string) $this->aysa_get_last_keyword_discovery_subtab();
}
$aysa_allowed_keyword_v2_tabs = array('gsc_v2', 'dataforseo_v2', 'competitor_gap_v2', 'keyword_mapping_v2');
$requested_keyword_v2_tab = isset($_GET['kdv2_tab']) ? sanitize_key((string) $_GET['kdv2_tab']) : '';
if ($requested_keyword_v2_tab !== '' && in_array($requested_keyword_v2_tab, $aysa_allowed_keyword_v2_tabs, true)) {
    $aysa_saved_keyword_subtab = $requested_keyword_v2_tab;
}
if (!in_array($aysa_saved_keyword_subtab, $aysa_allowed_keyword_v2_tabs, true)) {
    $aysa_saved_keyword_subtab = 'gsc_v2';
}

// Function to display the typing text section (copied from aysa-setup-wizard.php)
if (!function_exists('aysa_display_typing_text_section')) {
    function aysa_display_typing_text_section($text_to_type, $element_id_suffix) {
        ob_start();
        ?>
        <div class="aysa-chat-container aysa-wizard-intro-text">
            <div class="aysa-chat-message aysa-ai-message">
                <p id="aysa-dynamic-text-<?php echo esc_attr($element_id_suffix); ?>"></p>
            </div>
        </div>
        <script type="text/javascript">
            document.addEventListener('DOMContentLoaded', function() {
                const uniqueSuffix = '<?php echo esc_js($element_id_suffix); ?>';
                const targetElementId = 'aysa-dynamic-text-' + uniqueSuffix;
                console.log('[Aysa Typing Effect DEBUG] Trying to initialize for suffix: ' + uniqueSuffix + ', Target ID: ' + targetElementId);

                const textElement = document.getElementById(targetElementId);
                const textToType = <?php echo json_encode($text_to_type); ?>;
                let currentIndex = 0;
                const typingSpeed = 30; // Milliseconds per character

                console.log('[Aysa Typing Effect DEBUG ' + uniqueSuffix + '] Target Element:', textElement);
                console.log('[Aysa Typing Effect DEBUG ' + uniqueSuffix + '] Text to type:', textToType);

                function typeWriter() {
                    if (textElement && currentIndex < textToType.length) {
                        textElement.innerHTML += textToType.charAt(currentIndex);
                        currentIndex++;
                        setTimeout(typeWriter, typingSpeed);
                    } else if (textElement) {
                        textElement.classList.add('typing-done');
                        console.log('[Aysa Typing Effect DEBUG ' + uniqueSuffix + '] Typing complete.');
                    } else {
                        console.error('[Aysa Typing Effect DEBUG ' + uniqueSuffix + '] Target element became null during typing.');
                    }
                }

                if (textElement) {
                    textElement.innerHTML = ''; // Clear initial content
                    console.log('[Aysa Typing Effect DEBUG ' + uniqueSuffix + '] Starting typewriter.');
                    typeWriter();
                } else {
                    console.error('[Aysa Typing Effect DEBUG ' + uniqueSuffix + '] Target element NOT FOUND at initialization for ID: ' + targetElementId);
                }
            });
        </script>
        <?php
        return ob_get_clean();
    }
}

/**
 * Counts internal links on a given URL from the same domain
 * 
 * @param string $url The URL to analyze (must be from the same domain)
 * @return int Number of internal links found, or 0 if there was an error
 */
function aysa_count_internal_links($url) {
    // Validate URL
    if (!filter_var($url, FILTER_VALIDATE_URL)) {
        return 0;
    }

    // Get the site URL for comparison
    $site_url = get_site_url();
    $site_domain = wp_parse_url($site_url, PHP_URL_HOST);

    // Verify URL is from the same domain
    $url_domain = wp_parse_url($url, PHP_URL_HOST);
    if ($url_domain !== $site_domain) {
        return 0;
    }

    // Fetch the page content
    $response = wp_remote_get($url, array(
        'timeout' => 15,
        'sslverify' => true
    ));

    // Check for errors
    if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
        return 0;
    }

    // Get the HTML content
    $html = wp_remote_retrieve_body($response);
    if (empty($html)) {
        return 0;
    }

    // Create a DOM document
    $dom = new DOMDocument();
    
    // Suppress warnings from potentially malformed HTML
    libxml_use_internal_errors(true);
    $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    libxml_clear_errors();

    // Find all links
    $links = $dom->getElementsByTagName('a');
    $internal_count = 0;

    foreach ($links as $link) {
        $href = $link->getAttribute('href');
        
        // Skip empty links and anchors
        if (empty($href) || $href === '#') {
            continue;
        }

        // Check if it's a relative URL
        if (strpos($href, '/') === 0) {
            $internal_count++;
            continue;
        }

        // Check if it's an absolute URL from the same domain
        if (filter_var($href, FILTER_VALIDATE_URL)) {
            $link_domain = wp_parse_url($href, PHP_URL_HOST);
            if ($link_domain === $site_domain) {
                $internal_count++;
            }
        }
    }

    return $internal_count;
}

// Add WordPress AJAX action handler
add_action('wp_ajax_aysa_count_internal_links', 'aysa_ajax_count_internal_links');
function aysa_ajax_count_internal_links() {
    // Verify nonce for security
    check_ajax_referer('aysa_ajax_nonce', 'nonce');

    if (!current_user_can('manage_options')) {
        wp_send_json_error('Insufficient permissions');
        return;
    }

    // Get the URL from the request
    $url = isset($_POST['url']) ? sanitize_text_field($_POST['url']) : '';
    
    if (empty($url)) {
        wp_send_json_error('URL is required');
        return;
    }

    // Count internal links
    $count = aysa_count_internal_links($url);
    
    // Send the response
    wp_send_json_success($count);
}

// Ensure dashicons are loaded
wp_enqueue_style('dashicons');
?>

<div class="aysa-admin aysa-keyword-discovery">
    <!-- Page Title -->
    <div class="aysa-page-title">
        <h1>Keyword Discovery</h1>
        <div class="aysa-title-right">
            <?php
            // Use the credits component
            if (class_exists('Aysa_Credits_Component')) {
                Aysa_Credits_Component::display();
            } else {
                echo '<div class="aysa-credits-component"><span class="aysa-credits-value">Credits: <span class="aysa-credits-amount"><span class="aysa-loading-spinner"></span></span></span></div>';
            }
            ?>
        </div>
    </div>

    <!-- Top Tabs -->
    <div class="aysa-top-tabs">
        <a href="admin.php?page=aysa-research&tab=keyword-discovery&kdv2_tab=gsc_v2" class="aysa-tab <?php echo $aysa_saved_keyword_subtab === 'gsc_v2' ? 'active' : ''; ?>">Google Search Console</a>
        <a href="admin.php?page=aysa-research&tab=keyword-discovery&kdv2_tab=dataforseo_v2" class="aysa-tab <?php echo $aysa_saved_keyword_subtab === 'dataforseo_v2' ? 'active' : ''; ?>">Sugestii keywords</a>
        <a href="admin.php?page=aysa-research&tab=keyword-discovery&kdv2_tab=competitor_gap_v2" class="aysa-tab <?php echo $aysa_saved_keyword_subtab === 'competitor_gap_v2' ? 'active' : ''; ?>">Competitor Gap</a>
        <a href="admin.php?page=aysa-research&tab=keyword-discovery&kdv2_tab=keyword_mapping_v2" class="aysa-tab <?php echo $aysa_saved_keyword_subtab === 'keyword_mapping_v2' ? 'active' : ''; ?>">Keyword Mapping</a>
        <a href="admin.php?page=aysa-research&tab=competitor-identification" class="aysa-tab">Competitor Identification</a>
        <a href="admin.php?page=aysa-research&tab=competitor-backlinks" class="aysa-tab">Competitor Backlink Analysis</a>
        <a href="admin.php?page=aysa-research&tab=missing-pages" class="aysa-tab">Missing Pages</a>
        <a href="admin.php?page=aysa-research&tab=content-strategy" class="aysa-tab">Content Strategy</a>
        <a href="admin.php?page=aysa-research&tab=sitemap-competition" class="aysa-tab">Sitemap Competition</a>
    </div>

    <!-- Main Content -->
    <div class="aysa-content">
        <div class="aysa-keyword-discovery-content">
            <!-- AI Message commented out -->
            <!--
            <div class="aysa-global-intro-text">
                <img src="<?php echo plugin_dir_url(dirname(__FILE__, 2)); ?>assets/images/aysa-eyes.png" alt="Aysa Eyes" class="aysa-eyes-img" />
                <div class="aysa-chat-message aysa-ai-message">
                    <p id="aysa-dynamic-text-keyword-discovery-intro" class="aysa-intro-dynamic-text"></p>
                </div>
            </div>
            -->
            <script type="text/javascript">
                document.addEventListener('DOMContentLoaded', function() {
                    const textElement = document.getElementById('aysa-dynamic-text-keyword-discovery-intro');
                    const textToType = "Keyword Discovery is about finding the exact words your customers are searching for. This insight is the key to creating perfectly optimized content, driving high-quality traffic to your site, and boosting your search engine visibility. Ready to uncover the keywords that will grow your business? Let's get started!";
                    let currentIndex = 0;
                    const typingSpeed = 30;
                    function typeWriter() {
                        if (textElement && currentIndex < textToType.length) {
                            textElement.innerHTML += textToType.charAt(currentIndex);
                            currentIndex++;
                            setTimeout(typeWriter, typingSpeed);
                        } else if (textElement) {
                            textElement.classList.add('typing-done');
                        }
                    }
                    if (textElement) {
                        textElement.innerHTML = '';
                        typeWriter();
                    }
                });
            </script>
            <!-- Keyword Discovery Header -->
            <div class="aysa-section-header">
                <div class="aysa-header-icon">🔍</div>
                <div>
                    <h2>Keyword Discovery & Analysis</h2>
                    <p class="aysa-section-subtitle">Start with <strong>Refresh Suggested Keywords</strong>, then connect the most relevant keywords to the right pages.</p>
                </div>
            </div>

            <div class="aysa-kd-subtabs aysa-hidden" role="tablist" aria-label="Keyword Discovery Subsections">
                <button type="button" class="aysa-kd-subtab <?php echo $aysa_saved_keyword_subtab === 'gsc_v2' ? 'is-active' : ''; ?>" data-subtab="gsc_v2" aria-selected="<?php echo $aysa_saved_keyword_subtab === 'gsc_v2' ? 'true' : 'false'; ?>">Google Search Console</button>
                <button type="button" class="aysa-kd-subtab <?php echo $aysa_saved_keyword_subtab === 'dataforseo_v2' ? 'is-active' : ''; ?>" data-subtab="dataforseo_v2" aria-selected="<?php echo $aysa_saved_keyword_subtab === 'dataforseo_v2' ? 'true' : 'false'; ?>">Sugestii keywords</button>
                <button type="button" class="aysa-kd-subtab <?php echo $aysa_saved_keyword_subtab === 'competitor_gap_v2' ? 'is-active' : ''; ?>" data-subtab="competitor_gap_v2" aria-selected="<?php echo $aysa_saved_keyword_subtab === 'competitor_gap_v2' ? 'true' : 'false'; ?>">Competitor Gap</button>
                <button type="button" class="aysa-kd-subtab <?php echo $aysa_saved_keyword_subtab === 'keyword_mapping_v2' ? 'is-active' : ''; ?>" data-subtab="keyword_mapping_v2" aria-selected="<?php echo $aysa_saved_keyword_subtab === 'keyword_mapping_v2' ? 'true' : 'false'; ?>">Keyword Mapping</button>
                <button type="button" class="aysa-kd-subtab aysa-hidden" data-subtab="dashboard" aria-selected="false">Dashboard</button>
                <button type="button" class="aysa-kd-subtab aysa-hidden" data-subtab="gsc_plus_data" aria-selected="false">GSC + DATA</button>
                <button type="button" class="aysa-kd-subtab aysa-hidden" data-subtab="keyword_suggestions" aria-selected="false">Keyword Suggestions</button>
            </div>

            <div id="aysa-kd-v2-panel" class="aysa-kd-v2-panel">
                <div class="aysa-kd-v2-toolbar">
                    <div>
                        <h3 id="aysa-kd-v2-title">Keyword Discovery V2</h3>
                        <p id="aysa-kd-v2-meta" class="description">DB snapshots with manual live refresh.</p>
                        <p id="aysa-kd-v2-build" class="description" style="margin-top:4px;font-weight:600;">UI Build: KDUX1-20260329-01</p>
                    </div>
                    <div class="aysa-kd-v2-actions">
                        <label id="aysa-km-status-filter-wrap" class="aysa-hidden" style="display:none;align-items:center;gap:8px;margin-right:10px;">
                            <span style="font-size:12px;color:#5e6675;font-weight:600;">Mapping filter</span>
                            <select id="aysa-km-status-filter" style="min-width:180px;">
                                <option value="all">All</option>
                                <option value="mapped">Mapped</option>
                                <option value="review">Review</option>
                                <option value="not_mapped">Not mapped</option>
                            </select>
                        </label>
                        <button type="button" class="button button-primary" id="aysa-kd-v2-refresh">Refresh Live</button>
                    </div>
                </div>
                <div class="aysa-kd-v2-status" id="aysa-kd-v2-status">Ready.</div>
                <div id="aysa-km-workspace" class="aysa-km-workspace aysa-hidden"></div>
                <div class="aysa-table-responsive">
                    <table class="widefat striped" id="aysa-kd-v2-table">
                        <thead></thead>
                        <tbody></tbody>
                    </table>
                </div>
            </div>

            <div class="aysa-kd-dashboard-panel aysa-hidden">
                <div class="aysa-kd-dashboard-empty">
                    <h3>Dashboard</h3>
                    <p>Work in progress.</p>
                </div>
            </div>
            
            <!-- Table Controls -->
            <div class="aysa-kd-data-panel">
            <div class="aysa-table-controls">
                <div class="aysa-controls-left">
                    <div class="aysa-search-container">
                        <input type="text" placeholder="Search keywords..." class="aysa-search-input">
                        <button class="aysa-search-btn">Search</button>
                    </div>
                    <div class="aysa-add-keyword-container">
                        <input type="text" placeholder="Add keyword manually..." class="aysa-add-keyword-input">
                        <button class="aysa-add-keyword-btn">Add</button>
                    </div>
                    <div class="aysa-google-data-status-wrap">
                        <div id="aysa-google-data-status" class="aysa-google-data-status">Google data status: checking...</div>
                        <button type="button" id="aysa-google-reconnect-btn" class="button button-secondary aysa-google-reconnect-btn aysa-hidden">Reconnect Google</button>
                    </div>
                </div>
                <div class="aysa-filter-container">
                    <div class="aysa-banned-keywords-link-container">
                        <a href="admin.php?page=aysa-adjustment-improvement&tab=banned-keywords" class="aysa-banned-keywords-link" title="Manage deleted keywords">View deleted keywords</a>
                    </div>
                    <div class="aysa-filter-controls">
                        <div class="aysa-rows-per-page-container">
                            <label for="aysa-rows-per-page">Rows per page:</label>
                            <select id="aysa-rows-per-page" class="aysa-rows-select">
                                <option value="15">15</option>
                                <option value="20">20</option>
                                <option value="25">25</option>
                                <option value="50">50</option>
                                <option value="100">100</option>
                            </select>
                        </div>
                        <button class="aysa-generate-more-btn aysa-btn-primary-cta">Refresh Suggested Keywords</button>
                        <button class="aysa-generate-strategy-btn" title="Build keyword strategy from seed keywords">Generate Strategy</button>
                        <button class="aysa-reassociate-btn">Reconnect Unlinked Keywords</button>
                        <button class="aysa-triage-unlinked-btn" title="Review unlinked keywords and choose the next best action">Review Unlinked Keywords</button>
                        <button id="aysa-toggle-columns-btn" class="aysa-columns-toggle-btn" aria-pressed="true" title="Show or hide advanced columns">Show full columns</button>
                    </div>
                </div>
            </div>

            <div id="aysa-keyword-strategy-panel" class="aysa-keyword-strategy-panel aysa-hidden">
                <div class="aysa-keyword-strategy-header">
                    <h3>Keyword Strategy From Seed Keywords</h3>
                    <div id="aysa-keyword-strategy-meta" class="aysa-keyword-strategy-meta"></div>
                </div>
                <div id="aysa-keyword-strategy-summary" class="aysa-keyword-strategy-summary"></div>
                <div id="aysa-keyword-strategy-list" class="aysa-keyword-strategy-list"></div>
            </div>
            
            <!-- Pagination Controls (Top) -->
            <div class="aysa-pagination-top">
                <div class="aysa-pagination-info">
                    <span class="aysa-showing-info">Showing <span id="aysa-showing-from">0</span> to <span id="aysa-showing-to">0</span> of <span id="aysa-total-items">0</span> entries</span>
                </div>
                <div class="aysa-pagination-controls">
                    <button class="aysa-pagination-btn" id="aysa-prev-btn" disabled>Previous</button>
                    <div class="aysa-pagination-numbers" id="aysa-pagination-numbers"></div>
                    <button class="aysa-pagination-btn" id="aysa-next-btn" disabled>Next</button>
                </div>
            </div>

            <div id="aysa-gsc-data-clusters" class="aysa-gsc-data-clusters aysa-hidden"></div>
            
            <!-- Keywords Table -->
            <div class="aysa-table-responsive">
                <table class="aysa-keywords-table aysa-association-panel-mode">
                    <thead>
                        <tr>
                            <th class="aysa-keyword-col">Keyword <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-intent-col">Intent <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-volume-col">Volume <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-difficulty-col">KD % <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-cpc-col">CPC (USD) <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-serp-col">SERP Features</th>
                            <th class="aysa-updated-col">Updated <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-traffic-col">Traffic <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-traffic-pct-col">Traffic % <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-url-col">Matched Page URL <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-page-type-col">Page Type <span class="aysa-sort-icon">↕</span></th>
                            <th class="aysa-desired-col">Desired Target <span class="aysa-sort-icon">↕</span></th>
                        </tr>
                    </thead>
                    <tbody>
                        <!-- Initial loading state -->
                        <tr class="aysa-loading-message-row">
                            <td colspan="12" class="aysa-loading-cell">
                                <div class="aysa-loading-container">
                                    <span class="dashicons dashicons-update aysa-spinning"></span>
                                    <span class="aysa-loading-text">Initializing keyword data...</span>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            
            <!-- Pagination Controls (Bottom) -->
            <div class="aysa-pagination-bottom">
                <div class="aysa-pagination-info">
                    <span class="aysa-showing-info">Showing <span id="aysa-showing-from-bottom">0</span> to <span id="aysa-showing-to-bottom">0</span> of <span id="aysa-total-items-bottom">0</span> entries</span>
                </div>
                <div class="aysa-pagination-controls">
                    <button class="aysa-pagination-btn" id="aysa-prev-btn-bottom" disabled>Previous</button>
                    <div class="aysa-pagination-numbers" id="aysa-pagination-numbers-bottom"></div>
                    <button class="aysa-pagination-btn" id="aysa-next-btn-bottom" disabled>Next</button>
                </div>
            </div>
            
            <div class="aysa-table-footer">
                <p class="aysa-table-info">• This table displays keyword performance data with sortable columns. Click on any column header to sort the data.</p>
                <p class="aysa-table-info">• Row legend: <span class="aysa-row-legend aysa-row-legend-main">Main associated</span> <span class="aysa-row-legend aysa-row-legend-secondary">Secondary keyword</span></p>
                <p class="aysa-table-info aysa-refresh-footer-line">
                    <a href="#" id="aysa-footer-refresh-link" class="aysa-footer-refresh-link">Refresh data</a>
                    <span id="aysa-footer-refresh-meta" class="aysa-footer-refresh-meta">(last manual refresh: never)</span>
                </p>
            </div>
            </div>
        </div>
    </div>
</div>

<style>
/* Styles for the dynamic text (copied from aysa-setup-wizard.php and adapted) */
.aysa-wizard-intro-text { /* Keep general class name for consistency with function output */
    background-color: #f0f4f8;
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px; /* Adjusted margin for this context */
    max-width: 100%; /* Allow full width within its container */
    border: 1px solid #d1dde5;
}

.aysa-wizard-intro-text .aysa-chat-message {
    padding: 10px 15px;
    border-radius: 15px;
    line-height: 1.6;
    text-align: left;
    max-width: 100%;
}

.aysa-wizard-intro-text .aysa-ai-message {
    background-color: #e1f0ff;
    color: #333;
    display: inline-block; /* Or block if it should take full width of its parent */
    width: auto; /* Adjust based on content */
    border-bottom-left-radius: 0; /* Consistent with chat bubble style */
}

.aysa-wizard-intro-text .aysa-ai-message p {
    margin: 0;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    font-size: 15px;
}

.aysa-wizard-intro-text .aysa-ai-message p::after {
    content: '|';
    display: inline-block;
    animation: blink-animation 1s infinite;
    font-weight: bold;
}

.aysa-wizard-intro-text .aysa-ai-message p.typing-done::after {
    animation: none;
    content: '';
}

@keyframes blink-animation {
    to {
        visibility: hidden;
    }
}

/* Base Styles from existing CSS */
.aysa-admin {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    color: #333;
    max-width: 100%;
    margin: 0 auto;
    background-color: white;
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* Top Tabs */
.aysa-top-tabs {
    display: flex;
    flex-wrap: wrap;
    border-bottom: 1px solid #e0e0e0;
    background-color: #f8f9fa;
    padding: 0;
}

.aysa-tab {
    padding: 10px 15px;
    font-size: 13px;
    color: #666;
    cursor: pointer;
    border-bottom: 3px solid transparent;
    white-space: nowrap;
    text-decoration: none;
}

.aysa-tab.active {
    color: #1a73e8;
    font-weight: 500;
    border-bottom: 3px solid #1a73e8;
}

.aysa-tab.disabled {
    color: #bbb;
    cursor: not-allowed;
}

.aysa-tab:hover:not(.disabled):not(.active) {
    color: #1a73e8;
    border-bottom: 3px solid #e8f0fe;
}

/* Main Content */
.aysa-content {
    padding: 16px;
    flex-grow: 1;
}

/* Section Header */
.aysa-section-header {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
}

.aysa-header-icon {
    color: #1a73e8;
    margin-right: 10px;
    font-size: 20px;
}

.aysa-section-header h2 {
    font-size: 18px;
    font-weight: 500;
    margin: 0;
}

.aysa-section-subtitle {
    margin: 4px 0 0;
    font-size: 13px;
    color: #54606b;
}

.aysa-kd-subtabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px 0;
}

.aysa-kd-subtab {
    border: 1px solid #cfd8e3;
    background: #fff;
    color: #38506a;
    border-radius: 999px;
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    line-height: 1.1;
}

.aysa-kd-subtab.is-active {
    background: #123b63;
    border-color: #123b63;
    color: #fff;
}

.aysa-kd-dashboard-empty {
    border: 1px dashed #c6d4e3;
    border-radius: 10px;
    background: #f8fbff;
    padding: 24px 18px;
    margin-bottom: 16px;
}

.aysa-kd-dashboard-empty h3 {
    margin: 0 0 8px;
    color: #123b63;
}

.aysa-kd-dashboard-empty p {
    margin: 0;
    color: #5e7289;
}

.aysa-kd-data-panel.is-hidden {
    display: none;
}

/* Table Controls */
.aysa-table-controls {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
    margin-bottom: 20px;
    width: 100%;
}

.aysa-controls-left {
    display: grid;
    grid-template-columns: minmax(240px, 1.1fr) minmax(240px, 1fr) minmax(280px, 1.3fr);
    gap: 15px;
    align-items: center;
    min-width: 0;
}

.aysa-search-container {
    display: flex;
    width: 100%;
    border: 1px solid #ddd;
    border-radius: 4px;
    overflow: hidden;
    min-width: 0;
}

.aysa-search-input {
    padding: 8px 12px;
    border: none;
    width: 100%;
    font-size: 14px;
    flex-grow: 1;
    min-width: 0;
}

.aysa-search-input:focus {
    outline: none;
}

.aysa-search-btn {
    background-color: #0073aa;
    color: white;
    border: none;
    padding: 8px 15px;
    cursor: pointer;
}

.aysa-filter-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    width: 100%;
    min-width: 0;
}

.aysa-btn-primary-cta {
    background: linear-gradient(135deg, #1366d6, #1f7bf0);
    color: #fff;
    border: 1px solid #0f59be;
    border-radius: 6px;
    box-shadow: 0 1px 0 rgba(0,0,0,0.08);
}

.aysa-btn-primary-cta:hover {
    filter: brightness(1.05);
}

.aysa-columns-toggle-btn {
    background-color: #fff;
    color: #1f3b63;
    border: 1px solid #c8d3e0;
    border-radius: 6px;
    padding: 8px 12px;
    cursor: pointer;
    font-weight: 500;
}

.aysa-generate-strategy-btn {
    background: #0b7a5d;
    color: #fff;
    border: 1px solid #086a51;
    border-radius: 6px;
    padding: 8px 12px;
    cursor: pointer;
    font-weight: 600;
}

.aysa-generate-strategy-btn:hover {
    filter: brightness(1.05);
}

.aysa-keyword-strategy-panel {
    border: 1px solid #d6e2ee;
    border-radius: 8px;
    background: #f9fcff;
    margin: 8px 0 18px;
    padding: 12px 14px;
}

.aysa-keyword-strategy-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.aysa-keyword-strategy-header h3 {
    margin: 0;
    font-size: 15px;
    color: #123b63;
}

.aysa-keyword-strategy-meta {
    color: #536b84;
    font-size: 12px;
}

.aysa-keyword-strategy-summary {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.aysa-strategy-pill {
    background: #e8f0f8;
    color: #0f3558;
    border-radius: 999px;
    padding: 3px 9px;
    font-size: 12px;
    font-weight: 600;
}

.aysa-keyword-strategy-list {
    margin-top: 10px;
    display: grid;
    gap: 7px;
}

.aysa-keyword-strategy-item {
    display: grid;
    grid-template-columns: minmax(240px, 2fr) minmax(120px, 1fr) minmax(180px, 2fr);
    gap: 10px;
    align-items: center;
    background: #fff;
    border: 1px solid #e4ebf2;
    border-radius: 6px;
    padding: 8px 10px;
}

.aysa-keyword-strategy-keyword {
    font-weight: 600;
    color: #173b5f;
}

.aysa-keyword-strategy-details {
    color: #4d637a;
    font-size: 12px;
}

.aysa-keyword-strategy-action {
    display: inline-flex;
    justify-content: center;
    border-radius: 999px;
    padding: 3px 8px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
}

.aysa-keyword-strategy-action.action-associate_existing {
    background: #dbf2e7;
    color: #0a6a43;
}

.aysa-keyword-strategy-action.action-enhance_existing {
    background: #e6eef8;
    color: #184f89;
}

.aysa-keyword-strategy-action.action-create_new_page {
    background: #fdeacc;
    color: #915600;
}

.aysa-filter-btn, .aysa-export-btn {
    background-color: #f8f9fa;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 8px 15px;
    cursor: pointer;
}

/* Keywords Table */
.aysa-table-responsive {
    overflow-x: auto;
    overflow-y: auto;
    max-height: calc(100vh - 230px);
    margin-bottom: 20px;
    border: 1px solid #e0e0e0;
    border-radius: 3px;
    position: relative;
}

.aysa-kd-v2-panel .aysa-table-responsive {
    overflow: visible;
    max-height: none;
    border: 0;
    border-radius: 0;
    margin-bottom: 0;
}

.aysa-kd-v2-panel .aysa-kd-v2-toolbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 14px 16px;
    margin-bottom: 12px;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
}

.aysa-kd-v2-panel .aysa-kd-v2-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.aysa-kd-v2-panel .widefat thead th {
    position: static;
    top: auto;
    z-index: auto;
}

.aysa-km-workspace {
    display: block;
}

.aysa-km-workspace.aysa-hidden {
    display: none;
}

.aysa-keywords-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 13px;
    table-layout: auto;
    background-color: white;
    border: none;
}

.aysa-keywords-table th, .aysa-keywords-table td {
    padding: 10px 8px;
    text-align: left;
    border-bottom: 1px solid #e0e0e0;
    border-right: 1px solid #e0e0e0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Compact mode keeps the table focused on decision-critical columns. */
.aysa-keywords-table.compact-mode th.aysa-position-col,
.aysa-keywords-table.compact-mode td.aysa-position-col,
.aysa-keywords-table.compact-mode th.aysa-traffic-col,
.aysa-keywords-table.compact-mode td.aysa-traffic-col,
.aysa-keywords-table.compact-mode th.aysa-traffic-pct-col,
.aysa-keywords-table.compact-mode td.aysa-traffic-pct-col,
.aysa-keywords-table.compact-mode th.aysa-desired-col,
.aysa-keywords-table.compact-mode td.aysa-desired-col {
    display: none;
}

/* Association panel mode: keep research metrics on main row and move association UX below */
.aysa-keywords-table.aysa-association-panel-mode th.aysa-url-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-url-col,
.aysa-keywords-table.aysa-association-panel-mode th.aysa-page-type-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-page-type-col,
.aysa-keywords-table.aysa-association-panel-mode th.aysa-desired-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-desired-col {
    display: none;
}

.aysa-keywords-table.aysa-association-panel-mode {
    table-layout: fixed;
}

.aysa-keywords-table.aysa-association-panel-mode th.aysa-keyword-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-keyword-col { width: 27%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-intent-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-intent-col { width: 8%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-volume-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-volume-col { width: 11%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-difficulty-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-difficulty-col { width: 10%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-cpc-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-cpc-col { width: 10%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-serp-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-serp-col { width: 12%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-updated-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-updated-col { width: 10%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-position-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-position-col { width: 10%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-traffic-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-traffic-col { width: 8%; }
.aysa-keywords-table.aysa-association-panel-mode th.aysa-traffic-pct-col,
.aysa-keywords-table.aysa-association-panel-mode td.aysa-traffic-pct-col { width: 8%; }

.aysa-group-main-row td {
    border-top: 2px solid #d8e1ec;
}

.aysa-cluster-header-row td {
    background: linear-gradient(180deg, #eef6ff 0%, #f7fbff 100%) !important;
    border-top: 3px solid #bcd4f5;
    border-bottom: 1px solid #dce8f4;
}

.aysa-cluster-header {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.aysa-cluster-title {
    font-size: 15px;
    font-weight: 800;
    color: #17324d;
}

.aysa-cluster-meta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.aysa-gsc-plus-primary td:first-child {
    border-left: 4px solid #1f5ea8;
}

.aysa-gsc-plus-variant td:first-child {
    border-left: 4px solid #d7e3ef;
}

.aysa-gsc-plus-variant .aysa-main-keyword {
    padding-left: 22px;
    position: relative;
}

.aysa-gsc-plus-variant .aysa-main-keyword::before {
    content: '';
    position: absolute;
    left: 8px;
    top: 12px;
    width: 8px;
    height: 8px;
    border-left: 2px solid #b9c9d8;
    border-bottom: 2px solid #b9c9d8;
    border-bottom-left-radius: 2px;
}

.aysa-gsc-plus-variant .aysa-keyword-text {
    font-weight: 450;
    color: #425466;
}

.aysa-association-detail-row td {
    background: #f7fafc;
    border-bottom: 1px solid #e5edf5;
    overflow: visible !important;
    position: relative;
    z-index: 5;
}

.aysa-association-detail-cell {
    padding: 10px 12px !important;
    overflow: visible !important;
    position: relative;
    z-index: 6;
}

.aysa-association-detail-grid {
    display: grid;
    grid-template-columns: 1.25fr 1fr minmax(230px, 0.95fr);
    gap: 12px;
    align-items: stretch;
}

.aysa-association-detail-block {
    background: #ffffff;
    border: 1px solid #dce8f4;
    border-radius: 8px;
    padding: 10px;
    min-height: 100%;
}

.aysa-association-detail-title {
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 700;
    color: #48627d;
    margin-bottom: 8px;
}

.aysa-association-detail-row[data-association-state="linked"] .aysa-association-detail-cell {
    border-left: 4px solid #2e7d32;
}

.aysa-association-detail-row[data-association-state="partial"] .aysa-association-detail-cell {
    border-left: 4px solid #f9a825;
}

.aysa-association-detail-row[data-association-state="unlinked"] .aysa-association-detail-cell {
    border-left: 4px solid #cfd8e3;
}

.aysa-association-detail-content {
    white-space: normal;
    overflow: visible;
    text-overflow: initial;
    line-height: 1.4;
    color: #223344;
}

.aysa-association-detail-content .aysa-google-signals {
    margin-top: 8px;
}

.aysa-association-detail-actions {
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow: visible;
}

.aysa-association-detail-hint {
    font-size: 12px;
    color: #5d6f82;
}

.aysa-action-btn.aysa-action-btn-secondary-row {
    width: auto;
    min-width: 180px;
    align-self: flex-start;
}

.aysa-manage-action-dropdown {
    position: relative;
    display: inline-block;
    align-self: flex-start;
    z-index: 100020;
}

.aysa-manage-association-btn {
    width: auto !important;
    min-width: 190px;
    padding: 8px 18px;
    white-space: nowrap;
}

.aysa-manage-action-dropdown .aysa-dropdown-content {
    left: 0;
    right: auto;
    top: calc(100% + 6px);
    min-width: 240px;
}

.aysa-manage-action-dropdown.open .aysa-dropdown-content {
    left: 0 !important;
    right: auto !important;
    top: calc(100% + 6px) !important;
    z-index: 100005 !important;
}

.aysa-association-status-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
}

.aysa-association-status-chip.is-linked {
    background: #e8f5e9;
    color: #1b5e20;
    border: 1px solid #b8ddbf;
}

.aysa-association-status-chip.is-partial {
    background: #fff8e1;
    color: #8d6e00;
    border: 1px solid #f0d58a;
}

.aysa-association-status-chip.is-unlinked {
    background: #f1f5f9;
    color: #5b6f84;
    border: 1px solid #d5dfeb;
}

.aysa-association-check {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 8px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    background: #e8f5e9;
    color: #1b5e20;
    border: 1px solid #b7e1c0;
}

@media screen and (max-width: 1280px) {
    .aysa-association-detail-grid {
        grid-template-columns: 1fr;
    }
}

.aysa-keywords-table thead th {
    background-color: #f3f4f6;
    font-weight: 600;
    color: #3f3f46;
    position: sticky !important;
    top: 0 !important;
    z-index: 40;
    text-align: center;
    font-size: 14px;
    padding: 14px 10px;
    box-shadow: 0 1px 0 #d7dde3;
}

@media screen and (max-width: 782px) {
    .aysa-keywords-table thead th {
        top: 0 !important;
    }
}

.aysa-keywords-table th:last-child,
.aysa-keywords-table td:last-child {
    border-right: none;
}

.aysa-keywords-table tbody tr:hover {
    background-color: #f8fafc;
}

/* Intent Column */
.aysa-intent-col {
    width: 6%;
}

.aysa-keyword-indicators {
    display: flex;
    justify-content: center;
    gap: 3px;
}

.aysa-indicator {
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 3px;
    font-size: 11px;
    font-weight: bold;
    color: white;
}

.aysa-commercial {
    background-color: #34a853;
}

.aysa-transactional {
    background-color: #4285f4;
}

.aysa-navigational {
    background-color: #fbbc05;
}

.aysa-informational {
    background-color: #ea4335;
}

.aysa-target-intent {
    background-color: #1976d2;
    font-size: 10px;
}

.aysa-unknown {
    background-color: #9e9e9e;
    color: white;
}

/* Keyword Column */
.aysa-keyword-col {
    width: 15%;
    font-weight: 500;
}

.aysa-keyword-wrapper {
    display: flex;
    align-items: center;
    gap: 8px;
}

.aysa-keyword-text {
    flex-grow: 1;
    font-weight: 500;
}

.aysa-keyword-variants {
    margin-top: 4px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.aysa-keyword-variants-label {
    font-size: 11px;
    color: #666;
    font-weight: 600;
}

.aysa-seed-keyword-pill {
    display: inline-flex;
    align-items: center;
    margin-top: 8px;
    padding: 3px 10px;
    border-radius: 999px;
    background: #113c3a;
    color: #d5fff7;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.aysa-legacy-keyword-pill {
    display: inline-flex;
    align-items: center;
    margin-top: 6px;
    margin-left: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    background: #fff4e5;
    color: #8a4b00;
    border: 1px solid #f1c27d;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.aysa-keyword-todo {
    margin-top: 8px;
    padding: 7px 10px;
    border-radius: 8px;
    border: 1px solid #d7e3ef;
    background: #f7fbff;
    display: inline-flex;
    flex-direction: column;
    gap: 2px;
    max-width: 100%;
}

.aysa-keyword-todo-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.aysa-keyword-todo-reason {
    font-size: 11px;
    color: #5d6b79;
    white-space: normal;
    line-height: 1.35;
}

.aysa-keyword-todo.is-associate {
    border-color: #b7dfbf;
    background: #e9f8eb;
}

.aysa-keyword-todo.is-associate .aysa-keyword-todo-label {
    color: #1f7a2f;
}

.aysa-keyword-todo.is-product {
    border-color: #cde1ff;
    background: #eff5ff;
}

.aysa-keyword-todo.is-product .aysa-keyword-todo-label {
    color: #1d4e93;
}

.aysa-keyword-todo.is-category {
    border-color: #ffe0ad;
    background: #fff6e8;
}

.aysa-keyword-todo.is-category .aysa-keyword-todo-label {
    color: #8a5200;
}

.aysa-keyword-todo.is-article {
    border-color: #d8ccff;
    background: #f6f0ff;
}

.aysa-keyword-todo.is-article .aysa-keyword-todo-label {
    color: #5c2ca4;
}

.aysa-keyword-todo.is-landing {
    border-color: #ffd2db;
    background: #fff1f4;
}

.aysa-keyword-todo.is-landing .aysa-keyword-todo-label {
    color: #a1304e;
}

.aysa-keyword-variant-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 7px;
    border-radius: 999px;
    background: #e7f3ff;
    border: 1px solid #b9dcff;
    color: #205b8f;
    font-size: 11px;
    line-height: 1.3;
}

.aysa-keyword-variant-chip em {
    font-style: normal;
    color: #476c8d;
}

/* Neutral rows + zebra look by keyword group */
.aysa-main-associated,
.aysa-secondary-associated,
.aysa-no-association {
    box-shadow: none !important;
}

.aysa-zebra-light td {
    background-color: #f5f7fa !important;
}

.aysa-zebra-white td {
    background-color: #ffffff !important;
}

.aysa-association-detail-row.aysa-zebra-light td {
    background-color: #eef3f8 !important;
}

.aysa-association-detail-row.aysa-zebra-white td {
    background-color: #f8fafd !important;
}

/* Secondary keyword row base styling */
.aysa-secondary-keyword-row {
    font-size: 14px !important; /* Same as main rows */
    line-height: 1.5 !important; /* Same as main rows */
}

.aysa-secondary-keyword-row td {
    padding: 12px 8px !important; /* Same padding as main rows */
    font-size: 14px !important; /* Ensure font size is consistent */
}

/* Ensure Action button is same size on all rows */
.aysa-secondary-keyword-row .aysa-action-btn,
.aysa-main-associated .aysa-action-btn,
.aysa-no-association .aysa-action-btn {
    font-size: 13px !important;
    padding: 6px 12px !important;
    min-width: 70px !important;
    height: 32px !important;
    line-height: 1.5 !important;
}

/* Table data styling */
.aysa-volume-col, .aysa-difficulty-col, .aysa-cpc-col, .aysa-updated-col, .aysa-score-col, .aysa-position-col, .aysa-traffic-col, .aysa-traffic-pct-col, .aysa-external-col, .aysa-internal-col {
    width: 7%;
}

.aysa-cpc-col {
    width: 7%;
}

.aysa-updated-col {
    width: 10%;
}

.aysa-position-col {
    font-weight: 500;
}

.aysa-serp-col {
    width: 12%;
}

.aysa-serp-features-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.aysa-serp-chip {
    display: inline-block;
    padding: 2px 6px;
    border-radius: 999px;
    background: #eef2f7;
    color: #2f3f57;
    font-size: 11px;
    line-height: 1.2;
}

.aysa-serp-more {
    display: inline-block;
    padding: 2px 6px;
    border-radius: 999px;
    background: #f4e9ff;
    color: #55316e;
    font-size: 11px;
    line-height: 1.2;
}

.aysa-page-type-col {
    width: 8%;
    text-align: center;
}

.aysa-desired-col {
    width: 15%; /* Mărită de la 12% la 15% pentru mai mult spațiu */
    color: #666;
    text-align: center;
    padding: 8px 4px; /* Padding laterale reduse pentru a lăsa mai mult spațiu pentru dropdown */
}

.aysa-no {
    display: inline-block;
    color: #ea4335;
    font-size: 18px;
    width: 20px;
    height: 20px;
    text-align: center;
    line-height: 20px;
    background-color: #fce8e6;
    border-radius: 50%;
}

.aysa-url-col {
    width: 12%;
    color: #4285f4;
}

.aysa-keyword-col,
.aysa-url-col,
.aysa-page-type-col,
.aysa-serp-col {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: initial !important;
    word-break: break-word;
    vertical-align: top;
}

.aysa-competitor-col {
    width: 12%;
}

.aysa-action-btn {
    border: none;
    border-radius: 4px;
    padding: 6px 10px;
    font-size: 12px;
    cursor: pointer;
    color: white;
    width: 80px;
    text-align: center;
    background-color: #4285f4;
    transition: background-color 0.2s ease;
}

.aysa-action-btn:hover {
    background-color: #1565c0;
}

/* Action Dropdown Styles */
.aysa-action-dropdown {
    position: relative;
    display: inline-block;
}

.aysa-dropdown-content {
    display: none;
    position: absolute;
    background-color: #f9f9f9;
    min-width: 200px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 9999;
    border-radius: 4px;
    right: 0;
    top: 100%;
    margin-top: 5px;
    overflow: visible;
}

.aysa-dropdown-content a {
    color: #333;
    padding: 10px 12px;
    text-decoration: none;
    display: block;
    font-size: 12px;
    text-align: left;
    border-bottom: 1px solid #eee;
}

.aysa-dropdown-content a:last-child {
    border-bottom: none;
}

.aysa-dropdown-content a:hover {
    background-color: #f1f1f1;
}

.aysa-action-dropdown.open .aysa-dropdown-content {
    display: block !important;
    z-index: 99999 !important;
    position: absolute !important;
    right: 0 !important;
    top: 100% !important;
}

/* Table Footer */
.aysa-table-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 13px;
    color: #666;
    padding: 15px 0;
    flex-wrap: wrap;
    gap: 15px;
}

.aysa-refresh-footer-line {
    margin-left: auto;
    white-space: nowrap;
}

.aysa-footer-refresh-link {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #5c6f87;
    text-decoration: none;
    border-bottom: 1px dashed #9fb1c6;
}

.aysa-footer-refresh-link:hover,
.aysa-footer-refresh-link:focus {
    color: #1f5a96;
    border-bottom-color: #1f5a96;
    outline: none;
}

.aysa-footer-refresh-link.is-busy {
    opacity: 0.6;
    pointer-events: none;
}

.aysa-footer-refresh-meta {
    margin-left: 6px;
    color: #7b8794;
    font-size: 11px;
}

.aysa-pagination-info {
    font-size: 14px;
}

.aysa-pagination-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}

.aysa-pagination-btn {
    background-color: #f8f9fa;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 8px 12px;
    cursor: pointer;
    font-size: 13px;
    color: #333;
    transition: all 0.2s ease;
}

.aysa-pagination-btn:hover:not(:disabled) {
    background-color: #e9ecef;
    border-color: #adb5bd;
}

.aysa-pagination-btn:disabled {
    background-color: #f8f9fa;
    border-color: #e9ecef;
    color: #6c757d;
    cursor: not-allowed;
}

.aysa-pagination-numbers {
    display: flex;
    gap: 5px;
}

.aysa-page-number {
    padding: 8px 12px;
    border: 1px solid #ddd;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    background-color: #fff;
    color: #333;
    min-width: 40px;
    text-align: center;
    transition: all 0.2s ease;
}

.aysa-page-number:hover {
    background-color: #e9ecef;
    border-color: #adb5bd;
}

.aysa-page-number.active {
    background-color: #1a73e8;
    color: white;
    border-color: #1a73e8;
}

.aysa-pagination-ellipsis {
    padding: 8px 4px;
    color: #6c757d;
    font-size: 13px;
    display: flex;
    align-items: center;
}

.aysa-table-info {
    color: #666;
    font-size: 13px;
    margin: 0;
    flex: 1 1 100%;
    text-align: center;
}

.aysa-row-legend {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 12px;
    margin-left: 6px;
}

.aysa-row-legend-main {
    background: #d4edda;
    color: #255d2e;
}

.aysa-row-legend-secondary {
    background: #e8f5e9;
    color: #3c6b44;
}

@media screen and (max-width: 768px) {
    .aysa-table-footer {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }
    
    .aysa-pagination-controls {
        flex-wrap: wrap;
        justify-content: center;
    }
}

/* Removing pagination styles */

/* Responsive adjustments */
@media screen and (max-width: 1200px) {
    .aysa-keywords-table {
        min-width: 1000px;
    }
}

.aysa-sort-icon {
    font-size: 10px;
    color: #999;
    margin-left: 5px;
}

/* Text alignment for cells */
.aysa-volume-col, 
.aysa-difficulty-col, 
.aysa-cpc-col,
.aysa-updated-col,
.aysa-score-col,
.aysa-position-col,
.aysa-traffic-col,
.aysa-traffic-pct-col,
.aysa-external-col,
.aysa-internal-col {
    text-align: center;
}

.aysa-position-col {
    font-weight: 500;
}

.aysa-desired-col {
    color: #666;
    text-align: center;
}

.aysa-yes {
    color: #34a853;
    font-size: 16px;
}

.aysa-no {
    color: #ea4335;
    font-size: 16px;
}

/* Page Title */
.aysa-page-title {
    padding: 15px 20px;
    border-bottom: 1px solid #e0e0e0;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.aysa-page-title h1 {
    font-size: 20px;
    font-weight: 500;
    margin: 0;
    color: #333;
}

.aysa-title-right {
    display: flex;
    align-items: center;
    gap: 15px;
}

/* Add style for empty message */
.aysa-empty-message {
    text-align: center !important;
    padding: 40px 20px !important;
    color: #666;
    font-size: 15px;
    background-color: #f9f9f9;
}

.aysa-desired-wrapper {
    position: relative;
    width: 100%;
    max-width: 100%;
}

.aysa-desired-position {
    width: 180px !important; /* Lățime fixă mai mare pentru dropdown */
    max-width: 100% !important;
    background: #fff !important;
    padding: 6px 8px !important;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 14px;
    cursor: pointer;
    box-sizing: border-box;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    outline: none;
    min-width: 170px;
    height: initial !important;
}

.loading-categories {
    padding: 15px;
    text-align: center;
    color: #666;
    font-style: italic;
}

.no-categories {
    padding: 15px;
    text-align: center;
    color: #666;
    font-style: italic;
}

/* Add notification styles */
.aysa-notification {
    position: fixed;
    top: 30px;
    right: 30px;
    padding: 12px 20px;
    border-radius: 8px;
    color: white;
    font-size: 14px;
    font-weight: 500;
    z-index: 9999;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);
    animation: slideIn 0.6s cubic-bezier(0.16, 1, 0.3, 1);
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 280px;
    max-width: 350px;
    backdrop-filter: blur(8px);
    border: 1px solid rgba(255,255,255,0.1);
    transform-origin: right top;
}

.aysa-notification::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    border-radius: 8px 0 0 8px;
}

.aysa-notification-info {
    background: linear-gradient(135deg, rgba(33, 150, 243, 0.95), rgba(33, 150, 243, 0.85));
}

.aysa-notification-info::before {
    background: linear-gradient(to bottom, #1976D2, #2196F3);
}

.aysa-notification-success {
    background: linear-gradient(135deg, rgba(76, 175, 80, 0.95), rgba(76, 175, 80, 0.85));
}

.aysa-notification-success::before {
    background: linear-gradient(to bottom, #2E7D32, #4CAF50);
}

.aysa-notification-error {
    background: linear-gradient(135deg, rgba(244, 67, 54, 0.95), rgba(244, 67, 54, 0.85));
}

.aysa-notification-error::before {
    background: linear-gradient(to bottom, #D32F2F, #F44336);
}

.aysa-notification-loading {
    background: linear-gradient(135deg, rgba(255, 152, 0, 0.95), rgba(255, 152, 0, 0.85));
}

.aysa-notification-loading::before {
    background: linear-gradient(to bottom, #F57C00, #FF9800);
}

.aysa-notification-warning {
    background: linear-gradient(135deg, rgba(255, 193, 7, 0.95), rgba(255, 193, 7, 0.85));
}

.aysa-notification-warning::before {
    background: linear-gradient(to bottom, #F57C00, #FFC107);
}

.aysa-notification .dashicons {
    font-size: 20px;
    width: 20px;
    height: 20px;
    filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1));
}

.aysa-notification .dashicons.aysa-spinning {
    animation: spin 1s linear infinite;
}

.aysa-notification-close {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.8);
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
    padding: 0;
    margin-left: auto;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: all 0.2s ease;
}

.aysa-notification-close:hover {
    background: rgba(255, 255, 255, 0.2);
    color: white;
    transform: scale(1.1);
}

@keyframes slideIn {
    from {
        transform: translateX(100%) scale(0.8);
        opacity: 0;
    }
    to {
        transform: translateX(0) scale(1);
        opacity: 1;
    }
}

.aysa-notification.fade-out {
    animation: fadeOut 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes fadeOut {
    from {
        transform: translateX(0) scale(1);
        opacity: 1;
    }
    to {
        transform: translateX(100%) scale(0.8);
        opacity: 0;
    }
}

@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

.aysa-notification.fade-out {
    animation: fadeOut 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* Add styles for associated rows and buttons */
.aysa-row-associated {
    background-color: #e8f5e9 !important;
}

.aysa-btn-associated {
    background-color: #4caf50 !important;
    color: white !important;
    transition: background-color 0.2s ease !important;
}

.aysa-btn-associated:hover {
    background-color: #2e7d32 !important;
}

.aysa-cell-associated {
    background-color: #e8f5e9;
}

.aysa-associated-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 5px;
}

.aysa-item-name {
    flex-grow: 1;
    margin-right: 10px;
}

.aysa-disassociate-btn {
    background: none;
    border: none;
    color: #666;
    cursor: pointer;
    padding: 2px;
    display: flex;
    align-items: center;
}

.aysa-disassociate-btn:hover {
    color: #f44336;
}

.dropdown-item-associated {
    background-color: #e8f5e9 !important;
    color: #2e7d32 !important;
    font-weight: 500 !important;
}

.dropdown-item-associated:hover {
    background-color: #c8e6c9 !important;
}

.dropdown-category-button .dashicons {
    margin-left: 5px;
    font-size: 16px;
    width: 16px;
    height: 16px;
}

/* Add style for refresh suggested keywords button */
.aysa-generate-more-btn {
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    padding: 8px 12px;
    cursor: pointer;
    font-weight: 500;
    margin-left: 0;
    white-space: nowrap;
}

.aysa-generate-more-btn:hover {
    background-color: #45a049;
}

.aysa-generate-more-btn:disabled {
    background-color: #cccccc;
    cursor: not-allowed;
}

.aysa-generate-more-btn.aysa-processing {
    background-color: #ff9800;
    cursor: wait;
}

.aysa-generate-more-btn.aysa-exhausted {
    background-color: #9e9e9e;
    cursor: not-allowed;
    opacity: 0.7;
}

.aysa-generate-more-btn.aysa-exhausted:hover {
    background-color: #9e9e9e;
}

/* Add style for reassociate button */
.aysa-reassociate-btn {
    background-color: #2196F3;
    color: white;
    border: none;
    border-radius: 4px;
    padding: 8px 12px;
    cursor: pointer;
    font-weight: 500;
    margin-left: 0;
    white-space: nowrap;
}

.aysa-reassociate-btn:hover {
    background-color: #1976D2;
}

.aysa-reassociate-btn:disabled {
    background-color: #cccccc;
    cursor: not-allowed;
}

.aysa-reassociate-btn.aysa-processing {
    background-color: #ff9800;
    cursor: wait;
}

.aysa-reassociate-btn.aysa-processing .dashicons {
    animation: aysa-spin 1s linear infinite;
    margin-right: 5px;
}

.aysa-triage-unlinked-btn {
    background-color: #5e35b1;
    color: white;
    border: none;
    border-radius: 4px;
    padding: 8px 12px;
    cursor: pointer;
    font-weight: 500;
    margin-left: 0;
    white-space: nowrap;
}

.aysa-triage-unlinked-btn:hover {
    background-color: #4527a0;
}

.aysa-triage-unlinked-btn:disabled {
    background-color: #cccccc;
    cursor: not-allowed;
}

.aysa-triage-unlinked-btn.aysa-processing {
    background-color: #ff9800;
    cursor: wait;
}

.aysa-triage-unlinked-btn.aysa-processing .dashicons {
    animation: aysa-spin 1s linear infinite;
    margin-right: 5px;
}

/* Force-hide native dropdown arrows and ensure only custom arrow shows */
.aysa-desired-position {
    /* Eliminăm toate proprietățile care ascund săgeata nativă */
    /* background: #fff none !important; */
    /* background-image: none !important; */
    /* background-repeat: no-repeat !important; */
    /* background-position: right 12px center !important; */
    /* appearance: none !important; */
    /* -webkit-appearance: none !important; */
    /* -moz-appearance: none !important; */
}
/* Hide default arrow in IE/Edge */
/* .aysa-desired-position::-ms-expand {
    display: none !important;
} */
/* Hide default arrow in Firefox */
/* .aysa-desired-position::-moz-focus-inner {
    border: 0 !important;
} */

.aysa-desired-wrapper::after {
    /* Eliminăm complet săgeata customizată */
    display: none !important;
    /* content: '▾';
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    color: #666;
    font-size: 10px; */
}

/* Stilizare pentru încărcarea datelor */
.aysa-loading-row {
    background: #f9f9f9 !important;
}

.aysa-loading-cell {
    text-align: center !important;
    padding: 80px 20px !important;
    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%) !important;
    border: none !important;
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}

.aysa-loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 15px;
    max-width: 300px;
    margin: 0 auto;
    padding: 20px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.aysa-loading-container .dashicons {
    font-size: 36px;
    width: 36px;
    height: 36px;
    color: #0073aa;
    margin-bottom: 5px;
}

.aysa-loading-message-row {
    background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%) !important;
}

.aysa-loading-text {
    font-size: 16px;
    color: #333;
    font-weight: 500;
    text-align: center;
    line-height: 1.4;
}

@keyframes aysa-spin {
    to { transform: rotate(360deg); }
}

.aysa-spinning {
    animation: aysa-spin 1.5s linear infinite;
}

/* Loading placeholder skeleton */
.aysa-loading-placeholder {
    height: 20px;
    background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: loading-shimmer 1.5s infinite;
    border-radius: 4px;
    margin: 8px 4px;
}

@keyframes loading-shimmer {
    0% {
        background-position: -200% 0;
    }
    100% {
        background-position: 200% 0;
    }
}

.aysa-loading-row .aysa-loading-placeholder {
    opacity: 0.7;
}

.aysa-loading-message-row {
    background-color: #fafafa;
}

/* Page Type Badges */
.aysa-page-type {
    display: inline-block;
    padding: 3px 8px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.aysa-page-type-product {
    background-color: #e3f2fd;
    color: #1976d2;
    border: 1px solid #bbdefb;
}

.aysa-page-type-category {
    background-color: #f3e5f5;
    color: #7b1fa2;
    border: 1px solid #ce93d8;
}

.aysa-page-type-page {
    background-color: #e8f5e8;
    color: #388e3c;
    border: 1px solid #a5d6a7;
}

.aysa-page-type-unknown {
    background-color: #f5f5f5;
    color: #757575;
    border: 1px solid #e0e0e0;
}

.aysa-page-type-mixed {
    background-color: #fff3e0;
    color: #f57c00;
    border: 1px solid #ffcc02;
}

/* Stiluri pentru loading spinner-ele individuale din celule */
.aysa-loading-spinner {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 5px 0;
}

.aysa-loading-spinner .dashicons {
    font-size: 18px;
    width: 18px;
    height: 18px;
    color: #1a73e8;
}

/* Adaug stil specific pentru dropdown în tabel */
.aysa-keywords-table .aysa-action-dropdown {
    position: relative;
}

.aysa-keywords-table .aysa-action-dropdown .aysa-dropdown-content {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 99999;
    background-color: white;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    border: 1px solid #ddd;
    min-width: 200px;
    border-radius: 4px;
}

.aysa-keywords-table .aysa-action-btn {
    position: relative;
    z-index: 1;
}

/* Forțez afișarea dropdown-ului deasupra tabelului când este deschis */
.aysa-action-dropdown.open .aysa-dropdown-content {
    display: block !important;
    z-index: 99999 !important;
    position: absolute !important;
    right: 0 !important;
    top: 100% !important;
}

.aysa-secondary-dropdown {
    background: white;
    border: 1px solid #ddd;
    border-radius: 4px;
    max-height: 300px;
    overflow-y: auto;
}

.aysa-dropdown-item {
    padding: 8px 12px;
    cursor: pointer;
    border-bottom: 1px solid #eee;
}

.aysa-dropdown-item:last-child {
    border-bottom: none;
}

.aysa-dropdown-item:hover {
    background-color: #f5f5f5;
}

.aysa-loading-item,
.aysa-error-item {
    padding: 8px 12px;
    color: #666;
    font-style: italic;
}

.aysa-error-item {
    color: #dc3545;
}

.aysa-secondary-dropdown {
    background: white;
    border: 1px solid #ddd;
    border-radius: 4px;
    max-height: 300px;
    overflow-y: auto;
    position: absolute !important;
    z-index: 100000 !important;
}

.aysa-dropdown-item {
    padding: 8px 12px;
    cursor: pointer;
    border-bottom: 1px solid #eee;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.aysa-dropdown-item:last-child {
    border-bottom: none;
}

.aysa-dropdown-item:hover {
    background-color: #f5f5f5;
}

.aysa-dropdown-item.aysa-item-associated {
    background-color: #e8f5e9;
    color: #2e7d32;
    font-weight: 500;
}

.aysa-dropdown-item.aysa-item-associated:hover {
    background-color: #c8e6c9;
}

.aysa-dropdown-item.aysa-item-has-associations {
    background-color: #fff3cd;
    color: #856404;
    font-weight: 500;
}

.aysa-dropdown-item.aysa-item-has-associations:hover {
    background-color: #ffeaa7;
}

.aysa-dropdown-item.aysa-item-google-recommended {
    background: #eef6ff;
    border-left: 3px solid #1d4ed8;
}

.aysa-dropdown-item.aysa-item-google-recommended:hover {
    background: #dbeafe;
}

.aysa-dropdown-item.aysa-item-ga4-recommended {
    background: #ecfeff;
    border-left: 3px solid #0f766e;
}

.aysa-dropdown-item.aysa-item-ga4-recommended:hover {
    background: #cffafe;
}

.aysa-confidence-chip {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
}

.aysa-confidence-high {
    background: #dcfce7;
    color: #166534;
}

.aysa-confidence-medium {
    background: #fef9c3;
    color: #854d0e;
}

.aysa-confidence-low {
    background: #fee2e2;
    color: #991b1b;
}

.aysa-semantic-debug {
    margin-top: 6px;
    padding: 6px 8px;
    border-radius: 6px;
    background: #f8fafc;
    border: 1px dashed #cbd5e1;
    font-size: 11px;
    line-height: 1.35;
}

.aysa-semantic-debug-title {
    font-weight: 700;
    color: #334155;
    margin-bottom: 2px;
}

.aysa-semantic-debug-item {
    color: #475569;
}

.aysa-google-signals {
    margin-top: 6px;
    padding: 6px 8px;
    border-radius: 6px;
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    font-size: 11px;
    line-height: 1.4;
}

.aysa-google-signals strong {
    color: #1e293b;
}

.aysa-google-signal-item {
    margin-top: 2px;
    color: #334155;
}

.aysa-google-status {
    display: inline-block;
    margin-top: 4px;
    padding: 2px 7px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
}

.aysa-google-status-ok {
    background: #dcfce7;
    color: #166534;
}

.aysa-google-status-warn {
    background: #fee2e2;
    color: #991b1b;
}

.aysa-google-data-status {
    margin-left: 0;
    padding: 7px 10px;
    border-radius: 6px;
    border: 1px solid #dbeafe;
    background: #eff6ff;
    color: #1e3a8a;
    font-size: 12px;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.aysa-google-data-status-wrap {
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    min-width: 0;
}

.aysa-google-reconnect-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

.aysa-google-data-status.is-warn {
    border-color: #fecaca;
    background: #fef2f2;
    color: #991b1b;
}

.aysa-loading-item,
.aysa-error-item {
    padding: 8px 12px;
    color: #666;
    font-style: italic;
}

.aysa-error-item {
    color: #dc3545;
}

.aysa-action-dropdown {
    position: relative;
}

.aysa-dropdown-content {
    position: absolute;
    right: 0;
    top: 100%;
    z-index: 99999;
    background-color: white;
    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    border: 1px solid #ddd;
    min-width: 200px;
    border-radius: 4px;
    display: none;
    overflow: visible !important;
}

.aysa-action-dropdown.open .aysa-dropdown-content {
    display: block !important;
}

.aysa-dropdown-content a {
    display: block;
    padding: 8px 12px;
    color: #333;
    text-decoration: none;
    border-bottom: 1px solid #eee;
}

.aysa-dropdown-content a:last-child {
    border-bottom: none;
}

.aysa-dropdown-content a:hover {
    background-color: #f5f5f5;
}

.aysa-global-intro-text {
    background-color: #e6f7ea;
    border-radius: 8px;
    padding: 15px 20px;
    margin-top: 10px;
    margin-bottom: 20px;
    max-width: 90%;
    margin-left: auto;
    margin-right: auto;
    border: 1px solid #d1dde5;
    text-align: center;
    display: flex;
    align-items: center;
    gap: 20px;
}

.aysa-global-intro-text .aysa-eyes-img {
    width: 67px;
    height: auto;
    display: block;
    margin: 0;
    background: #e6f7ea;
}

.aysa-global-intro-text .aysa-chat-message {
    padding: 10px 15px;
    border-radius: 15px;
    line-height: 1.6;
    text-align: center;
    max-width: 100%;
    display: inline-block;
}

.aysa-global-intro-text .aysa-ai-message {
    background-color: #e1f0ff;
    color: #333;
    border-bottom-left-radius: 0;
    text-align: center;
}

.aysa-global-intro-text .aysa-ai-message p {
    margin: 0;
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    font-size: 1.2rem;
    font-weight: 600;
}

.aysa-global-intro-text .aysa-ai-message p::after {
    content: "|";
    display: inline-block;
    animation: blink-animation 1s infinite;
    font-weight: bold;
}

.aysa-global-intro-text .aysa-ai-message p.typing-done::after {
    animation: none;
    content: "";
}

@keyframes blink-animation {
    to {
        visibility: hidden;
    }
}

.aysa-add-keyword-container {
    display: flex;
    border: 1px solid #ddd;
    border-radius: 4px;
    overflow: hidden;
    width: 100%;
    min-width: 0;
}

.aysa-add-keyword-input {
    padding: 8px 12px;
    border: none;
    width: 100%;
    font-size: 14px;
}

.aysa-add-keyword-input:focus {
    outline: none;
}

.aysa-add-keyword-btn {
    background-color: #28a745;
    color: white;
    border: none;
    padding: 8px 15px;
    cursor: pointer;
    font-weight: 500;
}

.aysa-add-keyword-btn:hover {
    background-color: #218838;
}

/* Rows per page controls */
.aysa-rows-per-page-container {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: 0;
    overflow: visible;
    position: relative;
    z-index: 100;
}

.aysa-rows-per-page-container label {
    font-size: 14px;
    color: #666;
    white-space: nowrap;
}

/* Rows per page select */
.aysa-rows-select {
    padding: 6px 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 14px;
    background-color: white;
    cursor: pointer;
    min-width: 80px;
}

.aysa-rows-select:focus {
    outline: none;
    border-color: #1a73e8;
    box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
}

/* Pagination Areas */
.aysa-pagination-top,
.aysa-pagination-bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 15px;
    background-color: #f8f9fa;
    border: 1px solid #e0e0e0;
    border-radius: 4px;
    font-size: 13px;
    color: #666;
}

.aysa-pagination-top {
    margin-bottom: 15px;
}

.aysa-pagination-bottom {
    margin-top: 15px;
}

.aysa-pagination-top .aysa-pagination-info,
.aysa-pagination-bottom .aysa-pagination-info {
    font-size: 14px;
}

.aysa-pagination-top .aysa-pagination-controls,
.aysa-pagination-bottom .aysa-pagination-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}

.aysa-filter-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    overflow: visible;
    position: relative;
    flex-wrap: wrap;
    width: 100%;
}

.aysa-filter-container .aysa-filter-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Deleted keywords link styles - simple blue link positioned above buttons */
.aysa-banned-keywords-link-container {
    margin-bottom: 0;
    align-self: center;
}

@media screen and (max-width: 1400px) {
    .aysa-controls-left {
        grid-template-columns: minmax(220px, 1fr) minmax(220px, 1fr);
    }

    .aysa-google-data-status {
        grid-column: 1 / -1;
    }
}

@media screen and (max-width: 1100px) {
    .aysa-controls-left {
        grid-template-columns: 1fr;
    }

    .aysa-filter-container {
        align-items: flex-start;
    }

    .aysa-filter-container .aysa-filter-controls {
        justify-content: flex-start;
    }
}

.aysa-banned-keywords-link {
    color: #007cba;
    text-decoration: none;
    font-size: 14px;
    cursor: pointer;
}

.aysa-banned-keywords-link:hover {
    color: #005a87;
    text-decoration: underline;
}

.aysa-banned-keywords-link:focus {
    outline: 1px dotted #005a87;
    outline-offset: 2px;
}

.aysa-table-controls {
    overflow: visible;
    position: relative;
}

/* Button states for single keyword association */
.aysa-btn-waiting {
    background-color: #ffc107 !important;
    color: #212529 !important;
    cursor: not-allowed !important;
}

.aysa-btn-pulsing {
    animation: pulse 1.5s infinite ease-in-out;
}

.aysa-btn-success {
    background-color: #28a745 !important;
    color: white !important;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}
</style>

<script>
// Define ajaxurl if it's not already defined
var ajaxurl = ajaxurl || '<?php echo admin_url('admin-ajax.php'); ?>';
const aysaKeywordCacheNonce = '<?php echo esc_js(wp_create_nonce('aysa_keyword_cache_nonce')); ?>';
const aysaGoogleOauthNonce = '<?php echo esc_js(wp_create_nonce('aysa_google_oauth_nonce')); ?>';
const aysaAdminNonce = '<?php echo esc_js(wp_create_nonce('aysa_nonce')); ?>';
const aysaApiBaseUrl = '<?php echo esc_js(rtrim(Aysa_API_Config::get_base_url(), '/')); ?>';

jQuery(document).ready(function($) {
    if (window.AYSA_DEBUG === true) {
        console.log('Document ready - starting initialization');
    }
    
    // Pagination variables
    let currentPage = 1;
    let itemsPerPage = parseInt(localStorage.getItem('aysa_items_per_page')) || 15;
    let allKeywords = []; // Store all keywords
    let filteredKeywords = []; // Store filtered keywords for search
    let isCompactMode = false;
    let googleMappingsPromise = null;
    const AYSA_GSC_CACHE_TTL_MS = 15 * 60 * 1000;
    let activeKeywordSubtab = <?php echo wp_json_encode($aysa_saved_keyword_subtab); ?> || 'gsc_v2';
    let keywordMappingStatusFilter = 'all';
    const keywordDiscoveryV2Cache = {
        gsc_v2: null,
        dataforseo_v2: null,
        competitor_gap_v2: null,
        keyword_mapping_v2: null
    };
    let keywordSuggestionsAutoloadByProject = {};

    window.aysaGoogleKeywordMappings = [];
    window.aysaGoogleKeywordQueries = [];
    window.aysaGoogleKeywordRecommendations = {};
    window.aysaGoogleKeywordUrlHints = {};
    window.aysaGoogleKeywordUnresolvedHints = {};
    window.aysaKeywordSemanticVariants = {};
    window.aysaGa4ItemMetrics = {};
    window.aysaAutoAssociationState = {
        inProgress: false,
        lastRunKey: '',
        lastRunAt: 0,
        pageAutoRunDone: false
    };
    window.aysaEnableAutoAssociation = false;
    window.aysaWpItemsCatalog = { Category: [], Product: [], Page: [] };
    window.aysaSemanticTopMatchesCache = {};
    window.aysaKeywordConfidenceMap = {};
    window.aysaGoogleDataDiagnostics = {
        connected: null,
        gscRows: 0,
        gscQueryRows: 0,
        ga4Rows: 0,
        selectedGsc: '',
        usedGsc: '',
        selectedGa4: '',
        message: 'Checking Google connection...'
    };

    function getActiveSourceMode() {
        return (activeKeywordSubtab === 'keyword_suggestions' || activeKeywordSubtab === 'gsc_plus_data')
            ? 'keyword_suggestions'
            : 'gsc_auto';
    }

    function getGoogleCacheKey(projectId) {
        return `aysa_google_keyword_cache_${String(projectId || '')}`;
    }

    function readGoogleKeywordCache(projectId) {
        if (!projectId) {
            return null;
        }
        try {
            const raw = localStorage.getItem(getGoogleCacheKey(projectId));
            if (!raw) {
                return null;
            }
            const payload = JSON.parse(raw);
            const savedAt = Number(payload && payload.savedAt ? payload.savedAt : 0);
            if (!savedAt || (Date.now() - savedAt) > AYSA_GSC_CACHE_TTL_MS) {
                return null;
            }
            return payload;
        } catch (error) {
            return null;
        }
    }

    function writeGoogleKeywordCache(projectId, payload) {
        if (!projectId) {
            return;
        }
        try {
            localStorage.setItem(getGoogleCacheKey(projectId), JSON.stringify({
                savedAt: Date.now(),
                diagnostics: payload && payload.diagnostics ? payload.diagnostics : {},
                mappings: Array.isArray(payload && payload.mappings) ? payload.mappings : [],
                queries: Array.isArray(payload && payload.queries) ? payload.queries : [],
                unresolvedHints: payload && payload.unresolvedHints ? payload.unresolvedHints : {},
                urlHints: payload && payload.urlHints ? payload.urlHints : {},
                recommendations: payload && payload.recommendations ? payload.recommendations : {},
                ga4Metrics: payload && payload.ga4Metrics ? payload.ga4Metrics : {}
            }));
        } catch (error) {}
    }

    function escapeHtml(value) {
        return String(value ?? '').replace(/[&<>"']/g, function(char) {
            return {
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#39;'
            }[char];
        });
    }

    function escapeAttr(value) {
        return escapeHtml(value).replace(/`/g, '&#96;');
    }

    function renderGoogleDataStatus() {
        const $el = $('#aysa-google-data-status');
        const $reconnectBtn = $('#aysa-google-reconnect-btn');
        if (!$el.length) {
            return;
        }
        const d = window.aysaGoogleDataDiagnostics || {};
        let showReconnect = false;
        if (d.localMode === true) {
            $el.text('Google data status: connected (local cached mode, no live Google fetch).');
            $el.removeClass('is-warn');
            $reconnectBtn.addClass('aysa-hidden');
            return;
        }
        if (activeKeywordSubtab === 'keyword_suggestions') {
            $el.text('Keyword Suggestions source: endpoint only (related + suggestions).');
            $el.removeClass('is-warn');
            $reconnectBtn.addClass('aysa-hidden');
            return;
        }
        if (activeKeywordSubtab === 'gsc_plus_data') {
            let text = 'GSC + DATA status: checking...';
            let warn = false;
            if (d.connected === false) {
                warn = true;
                showReconnect = true;
                text = 'GSC + DATA status: Google needs reconnection.';
            } else if (d.connected === true) {
                text = `GSC + DATA status: connected | GSC rows: ${parseInt(d.gscRows || 0, 10)} | GSC query-only: ${parseInt(d.gscQueryRows || 0, 10)} | GA4 rows: ${parseInt(d.ga4Rows || 0, 10)}`;
            } else if (d.message) {
                text = `GSC + DATA status: ${String(d.message)}`;
            }
            $el.text(text);
            $el.toggleClass('is-warn', warn);
            $reconnectBtn.toggleClass('aysa-hidden', !showReconnect);
            return;
        }
        let text = 'Google data status: checking...';
        let warn = false;
        if (d.connected === false) {
            warn = true;
            text = `Google data status: not connected (${d.message || 'connect OAuth in Integrations'})`;
            showReconnect = true;
        } else if (d.connected === true) {
            const gsc = Number(d.gscRows || 0);
            const gscQueryOnly = Number(d.gscQueryRows || 0);
            const ga4 = Number(d.ga4Rows || 0);
            const usedDays = Number(d.usedDays || 0);
            text = `Google data status: connected | GSC rows: ${gsc}`;
            if (gscQueryOnly > 0) {
                text += ` | GSC query-only: ${gscQueryOnly}`;
            }
            text += ` | GA4 rows: ${ga4}`;
            if (usedDays > 0) {
                text += ` | window: ${usedDays}d`;
            }
            if (d.selectedGsc) {
                text += ` | GSC: ${d.selectedGsc}`;
            }
            if (d.usedGsc && d.usedGsc !== d.selectedGsc) {
                text += ` | used: ${d.usedGsc}`;
            }
            if (d.selectedGa4) {
                text += ` | GA4: ${d.selectedGa4}`;
            }
            if (gsc === 0) {
                warn = true;
                text += ` | ${d.message || 'no GSC query+page rows for selected property/date range'}`;
            }
        } else if (d.message) {
            const localMode = String(d.message || '').toLowerCase().includes('local mode');
            warn = !localMode;
            text = `Google data status: ${d.message}`;
            if (String(d.message || '').toLowerCase().includes('reconnect') || String(d.message || '').toLowerCase().includes('reauthorize')) {
                showReconnect = true;
            }
        }
        $el.text(text);
        $el.toggleClass('is-warn', warn);
        $reconnectBtn.toggleClass('aysa-hidden', !showReconnect);
    }

    async function reconnectGoogleForKeywordDiscovery() {
        const projectId = getProjectId() || 0;
        if (!projectId) {
            window.alert('Missing project ID.');
            return;
        }
        const $btn = $('#aysa-google-reconnect-btn');
        $btn.prop('disabled', true).text('Preparing...');
        try {
            const response = await fetch(ajaxurl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: new URLSearchParams({
                    action: 'aysa_google_get_auth_url',
                    nonce: aysaGoogleOauthNonce,
                    project_id: String(projectId),
                    return_url: window.location.href
                })
            });

            const payload = await response.json();
            if (!response.ok || !payload || !payload.success || !payload.data || !payload.data.auth_url) {
                throw new Error((payload && payload.data) ? String(payload.data) : 'Could not generate Google authorization URL.');
            }
            window.location.href = payload.data.auth_url;
        } catch (error) {
            const message = error && error.message ? error.message : 'OAuth init failed.';
            window.alert(message);
            $btn.prop('disabled', false).text('Reconnect Google');
        }
    }

    $(document).on('click', '#aysa-google-reconnect-btn', function() {
        reconnectGoogleForKeywordDiscovery();
    });
    
    // Initialize banned keywords list
    window.aysaBannedKeywords = [];
    
    // Load banned keywords on page load
    function loadBannedKeywordsList() {
        $.ajax({
            url: ajaxurl,
            type: 'GET',
            data: {
                action: 'aysa_get_banned_keywords',
                project_id: getProjectId() || 0,
                limit: 1000, // Get all banned keywords
                offset: 0,
                nonce: '<?php echo wp_create_nonce('aysa_banned_keywords_nonce'); ?>'
            },
            success: function(response) {
                if (response.success && response.data.keywords) {
                    window.aysaBannedKeywords = response.data.keywords.map(keyword => 
                        keyword.keyword.toLowerCase()
                    );
                    console.log('Loaded banned keywords:', window.aysaBannedKeywords);
                }
            },
            error: function(xhr, status, error) {
                console.error('Failed to load banned keywords:', error);
            }
        });
    }
    
    // Load banned keywords list
    loadBannedKeywordsList();
    renderGoogleDataStatus();
    
    // Set initial value for rows per page select
    $('#aysa-rows-per-page').val(itemsPerPage.toString());

    function applyColumnMode() {
        const $table = $('.aysa-keywords-table');
        const $toggle = $('#aysa-toggle-columns-btn');
        if (isCompactMode) {
            $table.addClass('compact-mode');
            $toggle.text('Show full columns').attr('aria-pressed', 'true');
        } else {
            $table.removeClass('compact-mode');
            $toggle.text('Show compact columns').attr('aria-pressed', 'false');
        }
    }

    applyColumnMode();

    $('#aysa-toggle-columns-btn').on('click', function() {
        isCompactMode = !isCompactMode;
        applyColumnMode();
    });
    
    // Pagination functions
    function updatePaginationInfo() {
        const totalItems = filteredKeywords.length;
        const startItem = totalItems === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1;
        const endItem = Math.min(currentPage * itemsPerPage, totalItems);
        
        // Update top pagination info
        $('#aysa-showing-from').text(startItem);
        $('#aysa-showing-to').text(endItem);
        $('#aysa-total-items').text(totalItems);
        
        // Update bottom pagination info
        $('#aysa-showing-from-bottom').text(startItem);
        $('#aysa-showing-to-bottom').text(endItem);
        $('#aysa-total-items-bottom').text(totalItems);
    }
    
    function updatePaginationControls() {
        const totalItems = filteredKeywords.length;
        const totalPages = Math.ceil(totalItems / itemsPerPage);
        
        console.log('🔧 Pagination Debug:', {
            totalItems,
            totalPages,
            currentPage,
            itemsPerPage,
            filteredKeywordsLength: filteredKeywords.length
        });
        
        // Update Previous/Next buttons for both top and bottom
        $('#aysa-prev-btn, #aysa-prev-btn-bottom').prop('disabled', currentPage <= 1);
        $('#aysa-next-btn, #aysa-next-btn-bottom').prop('disabled', currentPage >= totalPages);
        
        // Update page numbers for both containers
        const $numbersContainerTop = $('#aysa-pagination-numbers');
        const $numbersContainerBottom = $('#aysa-pagination-numbers-bottom');
        $numbersContainerTop.empty();
        $numbersContainerBottom.empty();
        
        if (totalPages <= 1) {
            console.log('🔧 Pagination: No pagination needed (totalPages <= 1)');
            return; // No pagination needed
        }
        
        // Calculate which page numbers to show
        let startPage = Math.max(1, currentPage - 2);
        let endPage = Math.min(totalPages, currentPage + 2);
        
        console.log('🔧 Before adjustment:', { startPage, endPage, currentPage, totalPages });
        
        // Adjust if we're near the beginning or end
        if (endPage - startPage < 4) {
            if (startPage === 1) {
                endPage = Math.min(totalPages, startPage + 4);
            } else if (endPage === totalPages) {
                startPage = Math.max(1, endPage - 4);
            }
        }
        
        console.log('🔧 After adjustment:', { startPage, endPage, range: endPage - startPage + 1 });
        
        // Helper function to add elements to both containers
        function addToBothContainers(element) {
            const $element = typeof element === 'string' ? $(element) : element;
            $numbersContainerTop.append($element);
            $numbersContainerBottom.append($element.clone(true));
        }
        
        // Add first page and ellipsis if needed
        if (startPage > 1) {
            addToBothContainers(`<span class="aysa-page-number" data-page="1">1</span>`);
            if (startPage > 2) {
                addToBothContainers(`<span class="aysa-pagination-ellipsis">...</span>`);
            }
        }
        
        // Add page numbers
        for (let i = startPage; i <= endPage; i++) {
            const $pageBtn = $(`<span class="aysa-page-number" data-page="${i}">${i}</span>`);
            if (i === currentPage) {
                $pageBtn.addClass('active');
            }
            addToBothContainers($pageBtn);
        }
        
        // Add last page and ellipsis if needed
        if (endPage < totalPages) {
            if (endPage < totalPages - 1) {
                addToBothContainers(`<span class="aysa-pagination-ellipsis">...</span>`);
            }
            addToBothContainers(`<span class="aysa-page-number" data-page="${totalPages}">${totalPages}</span>`);
        }
    }
    
    function goToPage(page) {
        const totalPages = Math.ceil(filteredKeywords.length / itemsPerPage);
        if (page < 1 || page > totalPages) return;
        
        currentPage = page;
        displayCurrentPage();
        updatePaginationControls();
        updatePaginationInfo();
    }
    
    function displayCurrentPage() {
        const startIndex = (currentPage - 1) * itemsPerPage;
        const endIndex = startIndex + itemsPerPage;
        const pageItems = filteredKeywords.slice(startIndex, endIndex);
        
        displayKeywordResults(pageItems, false); // false means don't update pagination (avoid recursion)
    }

    function buildGscPlusDataClusters(finalResults) {
        const clusterMap = new Map();
        (Array.isArray(finalResults) ? finalResults : []).forEach(item => {
            const result = item && item.mainKeyword ? item.mainKeyword : item;
            if (!result || !result.keyword) {
                return;
            }
            const clusterKey = getKeywordSemanticGroupKey(String(result.keyword || '')) || normalizeKeyword(String(result.keyword || ''));
            if (!clusterKey) {
                return;
            }
            if (!clusterMap.has(clusterKey)) {
                clusterMap.set(clusterKey, []);
            }
            clusterMap.get(clusterKey).push(result);
        });

        const clusters = Array.from(clusterMap.values()).map(items => {
            items.sort((a, b) => {
                const aScore = Math.max(Number(a.searchVolume || 0), Number(a.traffic || 0));
                const bScore = Math.max(Number(b.searchVolume || 0), Number(b.traffic || 0));
                return bScore - aScore;
            });
            return {
                main: items[0],
                items: items
            };
        });

        clusters.sort((a, b) => {
            const aScore = Math.max(Number(a.main.searchVolume || 0), Number(a.main.traffic || 0));
            const bScore = Math.max(Number(b.main.searchVolume || 0), Number(b.main.traffic || 0));
            return bScore - aScore;
        });

        return clusters;
    }

    function renderGscPlusDataFlatRows(finalResults, $tbody) {
        $('#aysa-gsc-data-clusters').addClass('aysa-hidden').empty();
        $('.aysa-table-responsive, .aysa-pagination-top, .aysa-pagination-bottom').removeClass('aysa-hidden');
        $tbody.empty();
        const clusters = buildGscPlusDataClusters(finalResults);
        let visualIndex = 0;
        clusters.forEach(function(cluster) {
            const mainKeyword = String((cluster.main && cluster.main.keyword) || '').trim();
            const clusterCount = Array.isArray(cluster.items) ? cluster.items.length : 0;
            if (clusterCount > 1) {
                const variantsLabel = `${clusterCount} keywords in cluster`;
                const $clusterRow = $(`
                    <tr class="aysa-group-main-row aysa-cluster-header-row">
                        <td colspan="12" class="aysa-keyword-col">
                            <div class="aysa-cluster-header">
                                <div class="aysa-cluster-title">${escapeHtml(mainKeyword)}</div>
                                <div class="aysa-cluster-meta">
                                    <div class="aysa-seed-keyword-pill">CLUSTER</div>
                                    <div class="aysa-association-status-chip is-partial">${escapeHtml(variantsLabel)}</div>
                                </div>
                            </div>
                        </td>
                    </tr>
                `);
                $tbody.append($clusterRow);
            }

            cluster.items.forEach(function(result, index) {
                const keyword = String(result.keyword || '').trim();
                const keywordSource = String(result.source || '').toLowerCase();
                const normalizedKeyword = String(keyword || '').toLowerCase();
                const hasGsc = keywordSource === 'gsc'
                    || keywordSource === 'gsc-query'
                    || keywordSource === 'gsc_query'
                    || keywordSource === 'gsc_query_only';
                const hasData = keywordSource === 'keyword_suggestion'
                    || keywordSource === 'related_keyword'
                    || keywordSource === 'suggested';
                const gscRow = hasGsc ? result : ((window.aysaGoogleKeywordQueries || []).find(row =>
                    String((row && row.keyword) || '').trim().toLowerCase() === normalizedKeyword
                ) || null);
                const confidenceInfo = window.aysaKeywordConfidenceMap
                    ? window.aysaKeywordConfidenceMap[normalizedKeyword]
                    : null;
                const keywordAssociations = getAssociationsForKeyword(keyword);

                let sourceLabel = 'DATA';
                if (hasGsc && hasData) {
                    sourceLabel = 'BOTH';
                } else if (hasGsc) {
                    sourceLabel = 'GSC';
                }

                let statusLabel = 'Needs review';
                let statusClass = 'is-unlinked';
                if (keywordAssociations.length > 0) {
                    statusLabel = 'Matched';
                    statusClass = 'is-linked';
                } else if (confidenceInfo && String(confidenceInfo.confidence || '').toLowerCase() === 'high') {
                    statusLabel = 'Suggested';
                    statusClass = 'is-partial';
                }

                let suggestedPageHtml = '<span class="aysa-page-type aysa-page-type-unknown">Needs review</span>';
                if (keywordAssociations.length > 0) {
                    const assoc = keywordAssociations[0];
                    suggestedPageHtml = `<span class="aysa-url-link">${escapeHtml(String(assoc.value || ''))}</span>`;
                } else {
                    const suggestion = getMatchedPageCandidateForKeyword(result);
                    if (suggestion && suggestion.item) {
                        suggestedPageHtml = `<span class="aysa-url-link">Suggested: ${escapeHtml(String(suggestion.item.name || ''))}</span>`;
                    }
                }

                const confidenceText = confidenceInfo && confidenceInfo.confidence
                    ? escapeHtml(String(confidenceInfo.confidence))
                    : 'Review';
                const isClustered = clusterCount > 1;
                const rowRoleClass = isClustered
                    ? (index === 0 ? 'aysa-gsc-plus-primary' : 'aysa-gsc-plus-variant')
                    : '';
                const roleBadge = isClustered ? (index === 0 ? 'PRIMARY' : 'VARIANT') : '';
                const $row = $(`
                    <tr class="aysa-group-main-row ${rowRoleClass} ${(visualIndex % 2 === 0) ? 'aysa-zebra-light' : 'aysa-zebra-white'}" data-keyword-id="${escapeAttr(result.id || '')}">
                        <td class="aysa-keyword-col">
                            <div class="aysa-main-keyword">
                                <div class="aysa-keyword-wrapper">
                                    <span class="aysa-keyword-text">${escapeHtml(keyword)}</span>
                                </div>
                                ${isClustered ? `<div class="${index === 0 ? 'aysa-seed-keyword-pill' : 'aysa-legacy-keyword-pill'}">${escapeHtml(roleBadge)}</div>` : ''}
                                <div class="${sourceLabel === 'GSC' ? 'aysa-seed-keyword-pill' : (sourceLabel === 'BOTH' ? 'aysa-confidence-chip aysa-confidence-medium' : 'aysa-legacy-keyword-pill')}">${escapeHtml(sourceLabel)}</div>
                                <div class="aysa-association-status-chip ${statusClass}">${escapeHtml(statusLabel)}</div>
                            </div>
                        </td>
                        <td class="aysa-intent-col">${getIntentIndicators(checkKeywordIntent(result) ? String(result.intent || '') : getIntentFallback(keyword), result.intentProbabilities || null)}</td>
                        <td class="aysa-volume-col">${formatNumber(result.searchVolume)}</td>
                        <td class="aysa-difficulty-col">${formatDifficulty(result.difficulty)}</td>
                        <td class="aysa-cpc-col">${formatCpcValue(result.cpc)}</td>
                        <td class="aysa-serp-col">${formatSerpFeatures(result.itemTypes)}</td>
                        <td class="aysa-updated-col">${formatUpdatedAgo(result.updatedAt || result.createdDate)}</td>
                        <td class="aysa-traffic-col">${gscRow ? formatNumber(gscRow.clicks || 0) : formatNumber(result.traffic)}</td>
                        <td class="aysa-traffic-pct-col">${gscRow ? escapeHtml(String(Number(gscRow.position || 0).toFixed(1))) : formatPercentValue(result.trafficPct)}</td>
                        <td class="aysa-url-col">${suggestedPageHtml}</td>
                        <td class="aysa-page-type-col"><div class="aysa-confidence-chip aysa-confidence-low">${confidenceText}</div></td>
                        <td class="aysa-desired-col"><span class="aysa-page-type aysa-page-type-unknown">${escapeHtml(statusLabel)}</span></td>
                    </tr>
                `);
                $tbody.append($row);
                visualIndex += 1;
            });
        });

        if (clusters.length === 0) {
            $tbody.html('<tr><td colspan="12" class="aysa-empty-message">No keywords available in GSC + DATA yet.</td></tr>');
        }
    }

    // Arată inițial starea de loading în tabel
    const $tbody = $('.aysa-keywords-table tbody');
    $tbody.html(`
        <tr class="aysa-loading-row">
            <td colspan="12" class="aysa-loading-cell">
                <div class="aysa-loading-container">
                    <span class="dashicons dashicons-update aysa-spinning"></span>
                    <span class="aysa-loading-text">Initializing keyword data...</span>
                </div>
            </td>
        </tr>
    `);
    
    // Function to show notifications
    function showNotification(message, type = 'info') {
        function normalizeNotificationMessage(rawMessage, notificationType) {
            const text = String(rawMessage || '').trim();
            if (notificationType === 'error') {
                if (text.toLowerCase().includes('http error')) {
                    return 'Operation failed. Please try again in a few seconds.';
                }
                if (text.toLowerCase().includes('invalid response')) {
                    return 'Unexpected server response. Please retry.';
                }
                if (text.toLowerCase().startsWith('error adding keyword')) {
                    return 'Keyword could not be added right now.';
                }
            }
            return text.length > 180 ? `${text.slice(0, 177)}...` : text;
        }

        // Remove any existing notifications of the same type to prevent stacking
        $(`.aysa-notification-${type}`).remove();
        
        const $notification = $('<div class="aysa-notification"></div>');
        $notification.addClass(`aysa-notification-${type}`);
        
        // Add icon based on type
        let iconClass = '';
        switch(type) {
            case 'success':
                iconClass = 'dashicons-yes';
                break;
            case 'error':
                iconClass = 'dashicons-no';
                break;
            case 'loading':
                iconClass = 'dashicons-update aysa-spinning';
                break;
            case 'warning':
                iconClass = 'dashicons-warning';
                break;
            default:
                iconClass = 'dashicons-info';
        }
        
        const finalMessage = normalizeNotificationMessage(message, type);
        $notification.html(`
            <span class="dashicons ${iconClass}"></span>
            <span>${escapeHtml(finalMessage)}</span>
            <button class="aysa-notification-close" onclick="$(this).parent().addClass('fade-out'); setTimeout(() => $(this).parent().remove(), 600);" title="Close notification">×</button>
        `);
        
        // Add to page
        $('body').append($notification);
        
        // For loading notifications, don't auto-remove (will be replaced by success/error)
        // For other notifications, auto-remove after 4 seconds
        if (type !== 'loading') {
            setTimeout(() => {
                $notification.addClass('fade-out');
                setTimeout(() => {
                    $notification.remove();
                }, 600);
            }, 4000); // Increased to 4 seconds for better visibility
        }
    }
    
    // Function to manually remove all notifications
    function clearNotifications() {
        $('.aysa-notification').addClass('fade-out');
        setTimeout(() => {
            $('.aysa-notification').remove();
        }, 600);
    }
    
    // Function to remove only loading notifications
    function clearLoadingNotifications() {
        $('.aysa-notification-loading').addClass('fade-out');
        setTimeout(() => {
            $('.aysa-notification-loading').remove();
        }, 600);
    }

    // Function to get WordPress items
    async function getWordPressItems(type) {
        try {
            const response = await fetch(ajaxurl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: new URLSearchParams({
                    action: 'aysa_get_items',
                    type: type,
                    nonce: '<?php echo wp_create_nonce("aysa_get_items_nonce"); ?>'
                })
            });

            if (!response.ok) {
                throw new Error(`Failed to get ${type}`);
            }

            const result = await response.json();
            if (!result.success) {
                throw new Error(result.message || `Failed to get ${type}`);
            }

            return result.data || [];
        } catch (error) {
            console.error(`Error getting ${type}:`, error);
            return [];
        }
    }

    function normalizeUrlForMatching(url) {
        try {
            const parsed = new URL(String(url || ''), window.location.origin);
            let path = (parsed.pathname || '/').toLowerCase();
            path = path.replace(/\/+$/, '');
            if (path === '') {
                path = '/';
            }
            return `${parsed.origin.toLowerCase()}${path}`;
        } catch (e) {
            return '';
        }
    }

    function normalizePathForMatching(pathValue) {
        const raw = String(pathValue || '').trim().toLowerCase();
        if (!raw) {
            return '/';
        }
        try {
            const parsed = new URL(raw, window.location.origin);
            let path = parsed.pathname || '/';
            path = path.replace(/\/+$/, '');
            return path || '/';
        } catch (e) {
            let path = raw.split('?')[0].split('#')[0];
            if (!path.startsWith('/')) {
                path = '/' + path;
            }
            path = path.replace(/\/+$/, '');
            return path || '/';
        }
    }

    function keywordTokens(keyword) {
        return String(keyword || '')
            .toLowerCase()
            .replace(/[^a-z0-9ăâîșşțţ\- ]/gi, ' ')
            .split(/\s+/)
            .filter(Boolean);
    }

    let wpCatalogPromise = null;
    async function ensureWpCatalogLoaded() {
        if (wpCatalogPromise) {
            return wpCatalogPromise;
        }
        wpCatalogPromise = (async () => {
            const [categories, pages, products] = await Promise.all([
                getWordPressItems('Category'),
                getWordPressItems('Page'),
                getWordPressItems('Product')
            ]);
            window.aysaWpItemsCatalog = {
                Category: Array.isArray(categories) ? categories : [],
                Page: Array.isArray(pages) ? pages : [],
                Product: Array.isArray(products) ? products : []
            };
            window.aysaSemanticTopMatchesCache = {};
        })();
        return wpCatalogPromise;
    }

    function normalizeSemanticText(value) {
        return String(value || '')
            .toLowerCase()
            .replace(/[^a-z0-9ăâîșşțţ\- ]/gi, ' ')
            .replace(/\s+/g, ' ')
            .trim();
    }

    function removeStopwords(tokens) {
        const stopwords = new Set([
            'si','sau','de','din','la','in','pe','cu','fara','pentru','prin','un','o','the','and','for','to','of',
            'a','al','ale','ai','dintr','dintre','catre','despre','este','sunt','fi','ca','ce'
        ]);
        return tokens.filter(t => t.length >= 2 && !stopwords.has(t));
    }

    function tokenSet(text) {
        const raw = normalizeSemanticText(text).split(' ').filter(Boolean);
        return new Set(removeStopwords(raw));
    }

    function jaccardSimilarity(setA, setB) {
        if (!setA.size || !setB.size) {
            return 0;
        }
        let intersection = 0;
        setA.forEach(v => {
            if (setB.has(v)) {
                intersection += 1;
            }
        });
        const union = setA.size + setB.size - intersection;
        return union > 0 ? (intersection / union) : 0;
    }

    function charBigramDice(a, b) {
        const s1 = normalizeSemanticText(a);
        const s2 = normalizeSemanticText(b);
        if (!s1 || !s2) {
            return 0;
        }
        const grams = text => {
            const out = [];
            for (let i = 0; i < text.length - 1; i += 1) {
                out.push(text.slice(i, i + 2));
            }
            return out;
        };
        const g1 = grams(s1);
        const g2 = grams(s2);
        if (!g1.length || !g2.length) {
            return 0;
        }
        const count = {};
        g1.forEach(g => { count[g] = (count[g] || 0) + 1; });
        let inter = 0;
        g2.forEach(g => {
            if (count[g] > 0) {
                inter += 1;
                count[g] -= 1;
            }
        });
        return (2 * inter) / (g1.length + g2.length);
    }

    function stemSemanticToken(token) {
        let t = String(token || '').trim().toLowerCase();
        if (!t) {
            return '';
        }
        t = t.replace(/[^a-z0-9]/g, '');
        if (t.length > 6) {
            t = t
                .replace(/(urilor|ilor|elor|iilor|iile)$/i, '')
                .replace(/(ului|elei|arei)$/i, '')
                .replace(/(uri|lor|ile|ele)$/i, '')
                .replace(/(ul|ei|ii|ie|ia|i|e|a)$/i, '');
        } else {
            t = t.replace(/(ii|ie|ia|i|e|a)$/i, '');
        }
        return t || String(token || '').trim().toLowerCase();
    }

    function getKeywordSemanticGroupKey(keyword) {
        const normalized = normalizeKeyword(String(keyword || ''));
        if (!normalized) {
            return '';
        }
        const tokens = removeStopwords(normalized.split(/\s+/).filter(Boolean));
        const stems = Array.from(new Set(tokens.map(stemSemanticToken).filter(Boolean)));
        stems.sort();
        return stems.join(' ');
    }

    function findSemanticKeywordMatch(keyword, existingKeywords) {
        const normalized = normalizeKeyword(String(keyword || ''));
        if (!normalized || !Array.isArray(existingKeywords) || existingKeywords.length === 0) {
            return null;
        }
        const groupKey = getKeywordSemanticGroupKey(normalized);
        if (!groupKey) {
            return null;
        }
        for (let i = 0; i < existingKeywords.length; i += 1) {
            const candidate = existingKeywords[i];
            const candidateKeyword = String((candidate && candidate.keyword) || '');
            if (!candidateKeyword) {
                continue;
            }
            const candidateKey = getKeywordSemanticGroupKey(candidateKeyword);
            if (candidateKey && candidateKey === groupKey) {
                return candidate;
            }
        }
        return null;
    }

    function semanticScoreForItem(keyword, item) {
        const keywordText = normalizeSemanticText(keyword);
        if (!keywordText) {
            return 0;
        }
        const itemName = normalizeSemanticText(item && item.name ? item.name : '');
        const itemSlug = normalizeSemanticText(item && item.slug ? item.slug : '');
        const itemUrl = normalizeSemanticText(item && item.url ? item.url : '');
        const itemDescription = normalizeSemanticText(item && item.description ? item.description : '');
        const itemText = `${itemName} ${itemSlug} ${itemUrl} ${itemDescription}`.trim();
        if (!itemText) {
            return 0;
        }

        const kSet = tokenSet(keywordText);
        const iSet = tokenSet(itemText);
        const tokenScore = jaccardSimilarity(kSet, iSet);
        const phraseScore = charBigramDice(keywordText, itemName || itemSlug || itemText);

        let exactBoost = 0;
        if (itemName.includes(keywordText) || itemSlug.includes(keywordText)) {
            exactBoost = 0.18;
        }
        const keywordTokensList = Array.from(kSet);
        const allInTitle = keywordTokensList.length > 0 && keywordTokensList.every(t => itemName.includes(t));
        if (allInTitle) {
            exactBoost += 0.12;
        }

        const weighted = (tokenScore * 0.62) + (phraseScore * 0.38) + exactBoost;
        return Math.max(0, Math.min(1, weighted));
    }

    function confidenceLabelFromScore(score, margin) {
        if (score >= 0.78 && margin >= 0.10) {
            return 'High';
        }
        if (score >= 0.62) {
            return 'Medium';
        }
        return 'Low';
    }

    function lexicalScoreForItem(keyword, item) {
        const keywordText = normalizeSemanticText(keyword || '');
        const itemName = normalizeSemanticText(item && item.name ? item.name : '');
        const itemSlug = normalizeSemanticText(item && item.slug ? item.slug : '');
        const itemUrl = normalizeSemanticText(item && item.url ? item.url : '');
        const itemText = `${itemName} ${itemSlug} ${itemUrl}`.trim();
        if (!keywordText || !itemText) {
            return 0;
        }

        const keywordTokensList = Array.from(tokenSet(keywordText));
        if (keywordTokensList.length === 0) {
            return 0;
        }

        let overlap = 0;
        keywordTokensList.forEach(token => {
            if (itemText.includes(token)) {
                overlap += 1;
            }
        });

        let score = overlap / keywordTokensList.length;
        if (itemName.includes(keywordText) || itemSlug.includes(keywordText)) {
            score += 0.25;
        }
        if (keywordTokensList.length >= 2 && keywordTokensList.every(token => itemName.includes(token) || itemSlug.includes(token))) {
            score += 0.20;
        }

        return Math.max(0, Math.min(1, score));
    }

    function resolveKeywordIntentForMatching(keyword, explicitIntent = '') {
        const fromExplicit = String(explicitIntent || '').trim().toLowerCase();
        if (fromExplicit && fromExplicit !== 'n/a') {
            return fromExplicit;
        }
        const fallback = String(getIntentFallback(String(keyword || '')) || '').trim().toLowerCase();
        return fallback || 'unknown';
    }

    function pageTypeFitScore(intent, itemType, keyword) {
        const normalizedIntent = String(intent || '').toLowerCase();
        const normalizedType = String(itemType || '').toLowerCase();
        const keywordText = String(keyword || '').toLowerCase();
        const localSignals = ['bucuresti', 'bragadiru', 'sector', 'livrare'];
        const hasLocalSignal = localSignals.some(signal => keywordText.includes(signal));

        if (normalizedIntent.includes('transactional') || normalizedIntent.includes('commercial')) {
            if (normalizedType === 'category' || normalizedType === 'product') return 1;
            if (normalizedType === 'page') return hasLocalSignal ? 0.72 : 0.45;
        }
        if (normalizedIntent.includes('informational')) {
            if (normalizedType === 'page') return 1;
            return 0.35;
        }
        if (normalizedIntent.includes('navigational')) {
            if (normalizedType === 'page') return 0.9;
            return 0.4;
        }

        if (hasLocalSignal && normalizedType === 'page') return 0.8;
        if (normalizedType === 'category') return 0.72;
        if (normalizedType === 'product') return 0.62;
        return 0.55;
    }

    function getCompositeRecommendation(keywordOrRow) {
        const row = (keywordOrRow && typeof keywordOrRow === 'object') ? keywordOrRow : null;
        const keyword = String((row && row.keyword) || keywordOrRow || '').trim();
        if (!keyword) {
            return null;
        }

        const intent = resolveKeywordIntentForMatching(keyword, row && row.intent ? row.intent : '');
        let best = null;
        let second = null;

        ['Category', 'Product', 'Page'].forEach(type => {
            const items = Array.isArray(window.aysaWpItemsCatalog && window.aysaWpItemsCatalog[type])
                ? window.aysaWpItemsCatalog[type]
                : [];
            items.forEach(item => {
                const lexical = lexicalScoreForItem(keyword, item);
                const semantic = semanticScoreForItem(keyword, item);
                const fit = pageTypeFitScore(intent, type, keyword);
                const total = (lexical * 0.45) + (semantic * 0.35) + (fit * 0.20);
                if (total < 0.36) {
                    return;
                }
                const candidate = {
                    source: 'composite',
                    score: total,
                    lexical: lexical,
                    semantic: semantic,
                    fit: fit,
                    item: {
                        type: type,
                        id: item.id,
                        name: item.name,
                        url: item.url || '',
                        slug: item.slug || ''
                    }
                };
                if (!best || candidate.score > best.score) {
                    second = best;
                    best = candidate;
                } else if (!second || candidate.score > second.score) {
                    second = candidate;
                }
            });
        });

        if (!best) {
            return null;
        }

        const margin = best.score - (second ? second.score : 0);
        return {
            source: best.source,
            score: best.score,
            lexical: best.lexical,
            semantic: best.semantic,
            fit: best.fit,
            margin: margin,
            confidence: confidenceLabelFromScore(best.score, margin),
            item: best.item
        };
    }

    function getTopSemanticMatches(keyword, limit = 3) {
        const keywordKey = String(keyword || '').trim().toLowerCase();
        if (!keywordKey) {
            return [];
        }
        if (window.aysaSemanticTopMatchesCache && Array.isArray(window.aysaSemanticTopMatchesCache[keywordKey])) {
            return window.aysaSemanticTopMatchesCache[keywordKey];
        }

        const all = [];
        ['Category', 'Product', 'Page'].forEach(type => {
            const items = Array.isArray(window.aysaWpItemsCatalog && window.aysaWpItemsCatalog[type])
                ? window.aysaWpItemsCatalog[type]
                : [];
            items.forEach(item => {
                const score = semanticScoreForItem(keywordKey, item);
                if (score >= 0.22) {
                    all.push({
                        type: type,
                        id: item.id,
                        name: String(item.name || ''),
                        score: score
                    });
                }
            });
        });

        all.sort((a, b) => b.score - a.score);
        const top = all.slice(0, limit);
        window.aysaSemanticTopMatchesCache[keywordKey] = top;
        return top;
    }

    function getSemanticRecommendation(keyword) {
        let best = null;
        let second = null;
        ['Category', 'Product', 'Page'].forEach(type => {
            const items = Array.isArray(window.aysaWpItemsCatalog && window.aysaWpItemsCatalog[type])
                ? window.aysaWpItemsCatalog[type]
                : [];
            items.forEach(item => {
                const score = semanticScoreForItem(keyword, item);
                if (score <= 0) {
                    return;
                }
                const candidate = {
                    source: 'semantic',
                    score: score,
                    item: {
                        type: type,
                        id: item.id,
                        name: item.name,
                        url: item.url || '',
                        slug: item.slug || ''
                    }
                };
                if (!best || candidate.score > best.score) {
                    second = best;
                    best = candidate;
                } else if (!second || candidate.score > second.score) {
                    second = candidate;
                }
            });
        });

        if (!best) {
            return null;
        }
        const margin = best.score - (second ? second.score : 0);
        const confidence = confidenceLabelFromScore(best.score, margin);
        return {
            source: best.source,
            score: best.score,
            margin: margin,
            confidence: confidence,
            item: best.item
        };
    }

    function getGa4KeywordScore(keyword, itemType, itemId) {
        const metricKey = `${itemType}|${itemId}`;
        const metric = window.aysaGa4ItemMetrics ? window.aysaGa4ItemMetrics[metricKey] : null;
        if (!metric) {
            return 0;
        }

        const tokens = keywordTokens(keyword);
        const haystack = `${metric.page_title || ''} ${metric.page_path || ''}`.toLowerCase();
        let overlap = 0;
        tokens.forEach(token => {
            if (token.length >= 3 && haystack.includes(token)) {
                overlap += 1;
            }
        });

        const relevance = tokens.length > 0 ? overlap / tokens.length : 0;
        if (tokens.length >= 2 && overlap < 2) {
            return 0;
        }
        if (tokens.length === 1 && overlap < 1) {
            return 0;
        }
        if (relevance < 0.55) {
            return 0;
        }
        const sessions = Number(metric.sessions || 0);
        return (relevance * 10000) + Math.min(sessions, 5000);
    }

    function findBestGa4HintForKeyword(keyword) {
        const tokens = keywordTokens(keyword);
        if (tokens.length === 0) {
            return null;
        }

        let best = null;
        Object.keys(window.aysaGa4ItemMetrics || {}).forEach(metricKey => {
            const metric = window.aysaGa4ItemMetrics[metricKey];
            if (!metric || !metric.item) {
                return;
            }
            const haystack = `${metric.page_title || ''} ${metric.page_path || ''}`.toLowerCase();
            let overlap = 0;
            tokens.forEach(token => {
                if (token.length >= 3 && haystack.includes(token)) {
                    overlap += 1;
                }
            });
            if (overlap === 0) {
                return;
            }
            const score = (overlap * 1000) + Number(metric.sessions || 0);
            if (!best || score > best.score) {
                best = {
                    score: score,
                    sessions: Number(metric.sessions || 0),
                    item: metric.item,
                    page_path: metric.page_path || ''
                };
            }
        });

        return best;
    }

    async function loadGoogleKeywordRecommendations(projectId, options = {}) {
        if (!projectId) {
            return;
        }

        const opts = Object.assign({
            forceRefresh: false
        }, options || {});

        if (!opts.forceRefresh) {
            const cached = readGoogleKeywordCache(projectId);
            if (cached) {
                window.aysaGoogleKeywordMappings = Array.isArray(cached.mappings) ? cached.mappings : [];
                window.aysaGoogleKeywordQueries = Array.isArray(cached.queries) ? cached.queries : [];
                window.aysaGoogleKeywordRecommendations = cached.recommendations || {};
                window.aysaGoogleKeywordUrlHints = cached.urlHints || {};
                window.aysaGoogleKeywordUnresolvedHints = cached.unresolvedHints || {};
                window.aysaGa4ItemMetrics = cached.ga4Metrics || {};
                window.aysaGoogleDataDiagnostics = Object.assign({}, cached.diagnostics || {}, {
                    message: (cached.diagnostics && cached.diagnostics.message)
                        ? cached.diagnostics.message
                        : 'cached'
                });
                renderGoogleDataStatus();
                return Promise.resolve();
            }
        }

        if (googleMappingsPromise) {
            return googleMappingsPromise;
        }

        googleMappingsPromise = (async () => {
            try {
                window.aysaGoogleKeywordUnresolvedHints = {};
                const response = await fetch(ajaxurl, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: new URLSearchParams({
                        action: 'aysa_google_keyword_mappings',
                        nonce: aysaGoogleOauthNonce,
                        project_id: String(projectId),
                        days: '90',
                        limit: '1000'
                    })
                });

                if (!response.ok) {
                    window.aysaGoogleDataDiagnostics = {
                        connected: null,
                        gscRows: 0,
                        gscQueryRows: 0,
                        ga4Rows: 0,
                        selectedGsc: '',
                        usedGsc: '',
                        selectedGa4: '',
                        message: `broker http ${response.status}`
                    };
                    renderGoogleDataStatus();
                    return;
                }

                const payload = await response.json();
                if (!payload || !payload.success || !payload.data) {
                    window.aysaGoogleDataDiagnostics = {
                        connected: null,
                        gscRows: 0,
                        gscQueryRows: 0,
                        ga4Rows: 0,
                        selectedGsc: '',
                        usedGsc: '',
                        selectedGa4: '',
                        message: 'invalid broker response'
                    };
                    renderGoogleDataStatus();
                    return;
                }
                if (!payload.data.connected) {
                    window.aysaGoogleDataDiagnostics = {
                        connected: false,
                        gscRows: 0,
                        gscQueryRows: 0,
                        ga4Rows: 0,
                        selectedGsc: String(payload.data.selected_gsc_site || ''),
                        usedGsc: String(payload.data.used_gsc_site || payload.data.selected_gsc_site || ''),
                        selectedGa4: String(payload.data.selected_ga4_property || ''),
                        message: 'connect Google and select properties'
                    };
                    renderGoogleDataStatus();
                    return;
                }

                const gscMappings = Array.isArray(payload.data.gsc_mappings) ? payload.data.gsc_mappings : [];
                const gscQueryRows = Array.isArray(payload.data.gsc_queries) ? payload.data.gsc_queries : [];
                const gscError = String(payload.data.gsc_error || '').trim();
                const gscErrorCode = parseInt(payload.data.gsc_error_code || 0, 10) || 0;
                window.aysaGoogleKeywordMappings = gscMappings;
                const queryMap = {};
                gscQueryRows.forEach(row => {
                    const queryValue = String((row && (row.query || row.keyword)) || '').trim();
                    if (!queryValue) {
                        return;
                    }
                    const key = normalizeKeyword(queryValue);
                    if (!key) {
                        return;
                    }
                    const clicks = Number((row && row.clicks) || 0);
                    const impressions = Number((row && row.impressions) || 0);
                    const current = queryMap[key];
                    if (!current || clicks > Number(current.clicks || 0) || impressions > Number(current.impressions || 0)) {
                        queryMap[key] = {
                            keyword: queryValue,
                            clicks: clicks,
                            impressions: impressions,
                            position: Number((row && row.position) || 0)
                        };
                    }
                });
                window.aysaGoogleKeywordQueries = Object.values(queryMap);

                await ensureWpCatalogLoaded();
                const categories = window.aysaWpItemsCatalog.Category || [];
                const pages = window.aysaWpItemsCatalog.Page || [];
                const products = window.aysaWpItemsCatalog.Product || [];

                const urlIndex = {};
                const pathIndex = {};
                [
                    { type: 'Category', items: categories },
                    { type: 'Page', items: pages },
                    { type: 'Product', items: products }
                ].forEach(group => {
                    (group.items || []).forEach(item => {
                        const normalized = normalizeUrlForMatching(item.url);
                        if (!normalized) {
                            return;
                        }
                        if (!Array.isArray(urlIndex[normalized])) {
                            urlIndex[normalized] = [];
                        }
                        urlIndex[normalized].push({
                            type: group.type,
                            id: item.id,
                            name: item.name,
                            url: item.url
                        });

                        const pathKey = normalizePathForMatching(item.url);
                        if (!Array.isArray(pathIndex[pathKey])) {
                            pathIndex[pathKey] = [];
                        }
                        pathIndex[pathKey].push({
                            type: group.type,
                            id: item.id,
                            name: item.name,
                            url: item.url
                        });
                    });
                });

                const recommendations = {};
                const keywordHints = {};
                const unresolvedHints = {};
                gscMappings.forEach(row => {
                    const keyword = String((row && row.keyword) || '').trim().toLowerCase();
                    const pageUrl = String((row && row.page) || '').trim();
                    if (!keyword || !pageUrl) {
                        return;
                    }

                    const normalizedPage = normalizeUrlForMatching(pageUrl);
                    const normalizedPath = normalizePathForMatching(pageUrl);
                    let candidates = normalizedPage ? (urlIndex[normalizedPage] || []) : [];
                    if (candidates.length !== 1 && normalizedPath) {
                        candidates = pathIndex[normalizedPath] || [];
                    }
                    if (candidates.length !== 1) {
                        const clicks = Number(row.clicks || 0);
                        const impressions = Number(row.impressions || 0);
                        const score = (clicks * 1000) + impressions;
                        const reason = !normalizedPage
                            ? 'invalid_or_relative_gsc_url'
                            : (candidates.length === 0 ? 'url_not_found_in_wp' : 'multiple_wp_matches');
                        const currentUnresolved = unresolvedHints[keyword];
                        if (!currentUnresolved || score > Number(currentUnresolved.score || 0)) {
                            unresolvedHints[keyword] = {
                                url: pageUrl,
                                clicks: clicks,
                                impressions: impressions,
                                position: Number(row.position || 0),
                                reason: reason,
                                matches: candidates.length
                            };
                        }
                        return;
                    }

                    const item = candidates[0];
                    const recKey = `${keyword}|${item.type}|${item.id}`;
                    const clicks = Number(row.clicks || 0);
                    recommendations[recKey] = {
                        clicks: clicks,
                        keyword: keyword,
                        page: pageUrl,
                        item: item
                    };

                    const existingHint = keywordHints[keyword];
                    if (!existingHint || clicks > Number(existingHint.clicks || 0)) {
                        keywordHints[keyword] = {
                            url: pageUrl,
                            clicks: clicks,
                            item: item
                        };
                    }
                });

                window.aysaGoogleKeywordRecommendations = recommendations;
                window.aysaGoogleKeywordUrlHints = keywordHints;
                window.aysaGoogleKeywordUnresolvedHints = unresolvedHints;

                const ga4Rows = Array.isArray(payload.data.ga4_pages) ? payload.data.ga4_pages : [];
                const ga4ItemMetrics = {};
                ga4Rows.forEach(row => {
                    const pagePath = normalizePathForMatching(row && row.page_path ? row.page_path : '');
                    const candidates = pathIndex[pagePath] || [];
                    if (candidates.length !== 1) {
                        return;
                    }
                    const item = candidates[0];
                    const metricKey = `${item.type}|${item.id}`;
                    const sessions = Number((row && row.sessions) || 0);
                    const pageViews = Number((row && row.page_views) || 0);
                    const current = ga4ItemMetrics[metricKey] || null;
                    if (!current || sessions > Number(current.sessions || 0)) {
                        ga4ItemMetrics[metricKey] = {
                            sessions: sessions,
                            page_views: pageViews,
                            page_title: String((row && row.page_title) || ''),
                            page_path: String((row && row.page_path) || ''),
                            item: item
                        };
                    }
                });
                window.aysaGa4ItemMetrics = ga4ItemMetrics;
                window.aysaGoogleDataDiagnostics = {
                    connected: true,
                    gscRows: gscMappings.length,
                    gscQueryRows: gscQueryRows.length,
                    ga4Rows: ga4Rows.length,
                    selectedGsc: String(payload.data.selected_gsc_site || ''),
                    usedGsc: String(payload.data.used_gsc_site || payload.data.selected_gsc_site || ''),
                    selectedGa4: String(payload.data.selected_ga4_property || ''),
                    usedDays: Number(payload.data.used_days || payload.data.days || 30),
                    gscErrorCode: gscErrorCode,
                    message: gscError || (gscMappings.length === 0
                        ? (gscQueryRows.length > 0
                            ? 'GSC has query-only data but no query+page pairs'
                            : 'no GSC data for selected property/date range')
                        : '')
                };
                writeGoogleKeywordCache(projectId, {
                    diagnostics: window.aysaGoogleDataDiagnostics,
                    mappings: window.aysaGoogleKeywordMappings,
                    queries: window.aysaGoogleKeywordQueries,
                    unresolvedHints: window.aysaGoogleKeywordUnresolvedHints,
                    urlHints: window.aysaGoogleKeywordUrlHints,
                    recommendations: window.aysaGoogleKeywordRecommendations,
                    ga4Metrics: window.aysaGa4ItemMetrics
                });
                renderGoogleDataStatus();
            } catch (error) {
                console.warn('Failed to load Google keyword mappings:', error);
                window.aysaGoogleDataDiagnostics = {
                    connected: null,
                    gscRows: 0,
                    gscQueryRows: 0,
                    ga4Rows: 0,
                    selectedGsc: '',
                    usedGsc: '',
                    selectedGa4: '',
                    message: 'google data request failed'
                };
                renderGoogleDataStatus();
            }
        })();

        return googleMappingsPromise;
    }

    function getBestGoogleRecommendation(keyword) {
        const keywordLower = String(keyword || '').trim().toLowerCase();
        if (!keywordLower) {
            return null;
        }

        let best = null;
        const recommendationMap = window.aysaGoogleKeywordRecommendations || {};
        Object.keys(recommendationMap).forEach(recKey => {
            if (!recKey.startsWith(`${keywordLower}|`)) {
                return;
            }
            const rec = recommendationMap[recKey];
            if (!rec || !rec.item) {
                return;
            }
            const score = Number(rec.clicks || 0);
            if (!best || score > best.score) {
                best = {
                    source: 'gsc',
                    score: score,
                    confidence: score >= 5 ? 'High' : 'Medium',
                    item: rec.item
                };
            }
        });

        if (best) {
            return best;
        }

        let ga4Best = null;
        ['Category', 'Product', 'Page'].forEach(type => {
            const items = Array.isArray(window.aysaWpItemsCatalog && window.aysaWpItemsCatalog[type])
                ? window.aysaWpItemsCatalog[type]
                : [];
            items.forEach(item => {
                const score = getGa4KeywordScore(keywordLower, type, item.id);
                if (score <= 0) {
                    return;
                }
                if (!ga4Best || score > ga4Best.score) {
                    ga4Best = {
                        source: 'ga4',
                        score: score,
                        confidence: score >= 7600 ? 'High' : (score >= 6200 ? 'Medium' : 'Low'),
                        item: {
                            type: type,
                            id: item.id,
                            name: item.name,
                            url: item.url || ''
                        }
                    };
                }
            });
        });

        return ga4Best;
    }

    async function upsertAssociation(projectId, keyword, candidateItem) {
        const params = new URLSearchParams();
        params.set('action', 'aysa_keyword_discovery_upsert_association');
        params.set('nonce', aysaAdminNonce);
        params.set('project_id', String(parseInt(projectId || 0, 10)));
        params.set('keyword', String(keyword || ''));
        params.set('associated_on', String((candidateItem && candidateItem.type) || ''));
        params.set('id_intern', String(parseInt((candidateItem && candidateItem.id) || 0, 10)));
        params.set('value', String((candidateItem && candidateItem.name) || ''));

        const response = await fetch(ajaxurl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            body: params.toString()
        });
        if (!response.ok) {
            throw new Error(`Association upsert failed with HTTP ${response.status}`);
        }
        const payload = await response.json().catch(() => null);
        if (!payload || !payload.success) {
            throw new Error(payload && payload.data ? String(payload.data) : 'Association upsert failed');
        }
        return (payload.data && payload.data.association) ? payload.data.association : {};
    }

    function getSemanticClusterKeywords(keyword) {
        const mainKeyword = String(keyword || '').trim();
        if (!mainKeyword) {
            return [];
        }
        const mainKey = mainKeyword.toLowerCase();
        const variants = Array.isArray(window.aysaKeywordSemanticVariants && window.aysaKeywordSemanticVariants[mainKey])
            ? window.aysaKeywordSemanticVariants[mainKey]
            : [];
        const cluster = [mainKeyword];
        variants.forEach(variant => {
            const value = String((variant && variant.keyword) || '').trim();
            if (value) {
                cluster.push(value);
            }
        });
        return Array.from(new Set(cluster.map(k => normalizeKeyword(k)))).map(norm => {
            const found = cluster.find(k => normalizeKeyword(k) === norm);
            return found || '';
        }).filter(Boolean);
    }

    async function propagateAssociationToSemanticCluster(projectId, mainKeyword, candidateItem) {
        const cluster = getSemanticClusterKeywords(mainKeyword);
        if (cluster.length <= 1 || !candidateItem) {
            return { created: 0, skipped: 0, failed: 0 };
        }
        let created = 0;
        let skipped = 0;
        let failed = 0;
        for (let i = 0; i < cluster.length; i += 1) {
            const keyword = cluster[i];
            if (normalizeKeyword(keyword) === normalizeKeyword(mainKeyword)) {
                continue;
            }
            const alreadyExists = Array.isArray(window.aysaAssociations) && window.aysaAssociations.some(a =>
                normalizeKeyword(String(a.keyword || '')) === normalizeKeyword(keyword) &&
                String(a.associatedOn || '') === String(candidateItem.type || '') &&
                String(a.idIntern || '') === String(candidateItem.id || '')
            );
            if (alreadyExists) {
                skipped += 1;
                continue;
            }
            try {
                const resp = await upsertAssociation(projectId, keyword, candidateItem);
                if (!Array.isArray(window.aysaAssociations)) {
                    window.aysaAssociations = [];
                }
                window.aysaAssociations.push({
                    keyword: keyword,
                    associatedOn: candidateItem.type,
                    idIntern: candidateItem.id,
                    value: candidateItem.name,
                    id: resp && resp.id ? resp.id : Date.now() + i
                });
                created += 1;
            } catch (e) {
                failed += 1;
            }
        }
        return { created, skipped, failed };
    }

    async function ensureCreatePageTask(projectId, keyword, reason, cachedTasks = null) {
        if (!projectId || !keyword) {
            return false;
        }

        const taskTitle = `Create page for keyword: ${keyword}`;
        let tasks = Array.isArray(cachedTasks) ? cachedTasks : [];

        if (tasks.length === 0) {
            try {
                const existingResp = await fetch(`${getApiBaseUrl()}/api/ResearchTasks/ByProject/${projectId}`);
                if (existingResp.ok) {
                    const existingData = await existingResp.json().catch(() => []);
                    tasks = Array.isArray(existingData) ? existingData : [];
                }
            } catch (e) {
                tasks = [];
            }
        }

        const found = tasks.find(t =>
            String(t && t.title ? t.title : '').trim().toLowerCase() === taskTitle.toLowerCase() &&
            String(t && t.status ? t.status : '').toLowerCase() !== 'deleted'
        );
        if (found) {
            return true;
        }

        const payload = {
            projectId: projectId,
            title: taskTitle,
            description: `Auto-created from Keyword Discovery. Reason: ${reason}`,
            status: 'in_progress',
            flag: 'isAi'
        };

        try {
            const createResp = await fetch(`${getApiBaseUrl()}/api/ResearchTasks`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });
            return createResp.ok;
        } catch (e) {
            return false;
        }
    }

    async function ensureRedirectRepairTask(projectId, keyword, missingUrl, reason, cachedTasks = null) {
        if (!projectId || !keyword || !missingUrl) {
            return false;
        }

        const taskTitle = `Review GSC URL for keyword: ${keyword}`;
        let tasks = Array.isArray(cachedTasks) ? cachedTasks : [];

        if (tasks.length === 0) {
            try {
                const existingResp = await fetch(`${getApiBaseUrl()}/api/ResearchTasks/ByProject/${projectId}`);
                if (existingResp.ok) {
                    const existingData = await existingResp.json().catch(() => []);
                    tasks = Array.isArray(existingData) ? existingData : [];
                }
            } catch (e) {
                tasks = [];
            }
        }

        const found = tasks.find(t =>
            String(t && t.title ? t.title : '').trim().toLowerCase() === taskTitle.toLowerCase() &&
            String(t && t.status ? t.status : '').toLowerCase() !== 'deleted'
        );
        if (found) {
            return true;
        }

        const payload = {
            projectId: projectId,
            title: taskTitle,
            description: `Auto-created from Keyword Discovery triage. Missing or unresolved GSC URL: ${missingUrl}. Reason: ${reason}`,
            status: 'in_progress',
            flag: 'isAi'
        };

        try {
            const createResp = await fetch(`${getApiBaseUrl()}/api/ResearchTasks`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });
            return createResp.ok;
        } catch (e) {
            return false;
        }
    }

    async function autoAssociateFromGoogle(keywords, projectId) {
        await loadGoogleKeywordRecommendations(projectId, { forceRefresh: true });

        const uniqueKeywords = Array.from(new Set((keywords || []).map(k => String(k || '').trim()).filter(Boolean)));
        const result = {
            remainingKeywords: [],
            associatedCount: 0,
            gscCount: 0,
            ga4Count: 0,
            semanticCount: 0,
            createdTasks: 0
        };
        const confidenceMap = window.aysaKeywordConfidenceMap || {};
        let cachedProjectTasks = null;
        let createdTasksThisRun = 0;
        const maxTasksPerRun = 25;

        try {
            const tasksResp = await fetch(`${getApiBaseUrl()}/api/ResearchTasks/ByProject/${projectId}`);
            if (tasksResp.ok) {
                const tasksData = await tasksResp.json().catch(() => []);
                cachedProjectTasks = Array.isArray(tasksData) ? tasksData : [];
            }
        } catch (e) {
            cachedProjectTasks = [];
        }

        for (const keyword of uniqueKeywords) {
            const alreadyAssociated = (window.aysaAssociations || []).some(a =>
                String(a.keyword || '').toLowerCase() === keyword.toLowerCase()
            );
            if (alreadyAssociated) {
                continue;
            }

            const googleRecommendation = getBestGoogleRecommendation(keyword);
            const semanticRecommendation = getSemanticRecommendation(keyword);

            let chosen = null;
            const semanticScore = semanticRecommendation ? Number(semanticRecommendation.score || 0) : 0;
            const hasStrongGoogleSignal = googleRecommendation && googleRecommendation.item && (
                googleRecommendation.confidence === 'High' ||
                (googleRecommendation.source === 'gsc' && googleRecommendation.confidence === 'Medium')
            );
            if (hasStrongGoogleSignal) {
                chosen = googleRecommendation;
            } else if (semanticRecommendation && semanticRecommendation.item && semanticRecommendation.confidence === 'High') {
                chosen = semanticRecommendation;
            } else if (semanticRecommendation && semanticRecommendation.item && semanticScore >= 0.20) {
                // Accept low-confidence semantic matches above 20% as requested.
                chosen = {
                    ...semanticRecommendation,
                    source: 'semantic',
                    confidence: semanticRecommendation.confidence || 'Low'
                };
            }

            const finalConfidence = chosen
                ? chosen.confidence
                : (googleRecommendation
                    ? googleRecommendation.confidence
                    : (semanticRecommendation ? semanticRecommendation.confidence : 'Low'));
            confidenceMap[String(keyword).toLowerCase()] = {
                confidence: finalConfidence,
                source: chosen ? chosen.source : (googleRecommendation ? googleRecommendation.source : (semanticRecommendation ? 'semantic' : 'none')),
                score: chosen
                    ? Number(chosen.score || 0)
                    : (googleRecommendation
                        ? Number(googleRecommendation.score || 0)
                        : Number((semanticRecommendation && semanticRecommendation.score) || 0))
            };
            window.aysaKeywordConfidenceMap = confidenceMap;

            if (chosen && chosen.item) {
                try {
                    const apiResponse = await upsertAssociation(projectId, keyword, chosen.item);
                    result.associatedCount += 1;
                    if (chosen.source === 'gsc') {
                        result.gscCount += 1;
                    } else if (chosen.source === 'ga4') {
                        result.ga4Count += 1;
                    } else if (chosen.source === 'semantic') {
                        result.semanticCount += 1;
                    }

                    if (!Array.isArray(window.aysaAssociations)) {
                        window.aysaAssociations = [];
                    }
                    const exists = window.aysaAssociations.some(a =>
                        String(a.keyword || '').toLowerCase() === keyword.toLowerCase() &&
                        String(a.associatedOn || '') === chosen.item.type &&
                        String(a.idIntern || '') === String(chosen.item.id)
                    );
                    if (!exists) {
                        window.aysaAssociations.push({
                            keyword: keyword,
                            associatedOn: chosen.item.type,
                            idIntern: chosen.item.id,
                            value: chosen.item.name,
                            id: apiResponse && apiResponse.id ? apiResponse.id : Date.now()
                        });
                    }
                    continue;
                } catch (err) {
                    console.warn(`Auto-association failed for "${keyword}":`, err);
                }
            }

            if (semanticRecommendation && semanticScore < 0.20) {
                if (createdTasksThisRun < maxTasksPerRun) {
                    const taskReason = semanticRecommendation.score > 0
                        ? `semantic_score=${semanticRecommendation.score.toFixed(3)} (low confidence)`
                        : 'no-semantic-match';
                    const taskOk = await ensureCreatePageTask(projectId, keyword, taskReason, cachedProjectTasks);
                    if (taskOk) {
                        result.createdTasks += 1;
                        createdTasksThisRun += 1;
                        if (Array.isArray(cachedProjectTasks)) {
                            cachedProjectTasks.push({
                                title: `Create page for keyword: ${keyword}`,
                                status: 'in_progress'
                            });
                        }
                    }
                }
                continue;
            }

            result.remainingKeywords.push(keyword);
        }

        return result;
    }

    function isSyntheticTestKeyword(keyword) {
        const k = String(keyword || '').trim().toLowerCase();
        if (!k) {
            return true;
        }
        if (/^(qa|test)[-_]/i.test(k)) {
            return true;
        }
        if (/qa[-_]?keyword[-_]?/i.test(k)) {
            return true;
        }
        if (/keyword[-_]?\d{6,}/i.test(k)) {
            return true;
        }
        if (/\d{8,}/.test(k)) {
            return true;
        }
        const letters = (k.match(/[a-zăâîșşțţ]/gi) || []).length;
        const digits = (k.match(/\d/g) || []).length;
        if (letters === 0) {
            return true;
        }
        if (digits > letters * 1.2) {
            return true;
        }
        return false;
    }

    function getGscRowsForKeyword(keyword, limit = 2) {
        const key = String(keyword || '').trim().toLowerCase();
        if (!key || !Array.isArray(window.aysaGoogleKeywordMappings)) {
            return [];
        }
        return window.aysaGoogleKeywordMappings
            .filter(row => String((row && row.keyword) || '').trim().toLowerCase() === key)
            .sort((a, b) => Number((b && b.clicks) || 0) - Number((a && a.clicks) || 0))
            .slice(0, limit);
    }

    function getGoogleUnresolvedHint(keyword) {
        const key = String(keyword || '').trim().toLowerCase();
        if (!key || !window.aysaGoogleKeywordUnresolvedHints) {
            return null;
        }
        return window.aysaGoogleKeywordUnresolvedHints[key] || null;
    }

    function findCatalogItemUrlByAssociation(association) {
        if (!association) {
            return '';
        }
        const type = String(association.associatedOn || '');
        const id = String(association.idIntern || '');
        const list = Array.isArray(window.aysaWpItemsCatalog && window.aysaWpItemsCatalog[type])
            ? window.aysaWpItemsCatalog[type]
            : [];
        const match = list.find(item => String(item.id) === id);
        return match && match.url ? String(match.url) : '';
    }

    function hasGscMatchForCurrentAssociation(keywordAssociations, gscRows) {
        if (!Array.isArray(keywordAssociations) || keywordAssociations.length === 0) {
            return false;
        }
        if (!Array.isArray(gscRows) || gscRows.length === 0) {
            return false;
        }
        const gscUrls = new Set(
            gscRows
                .map(r => normalizeUrlForMatching((r && r.page) || ''))
                .filter(Boolean)
        );
        return keywordAssociations.some(assoc => {
            const assocUrl = normalizeUrlForMatching(findCatalogItemUrlByAssociation(assoc));
            return assocUrl && gscUrls.has(assocUrl);
        });
    }

    // Function to get Project ID from multiple sources (copied from aysa-technical-optimization.php)
    function getProjectId() {
        // First try to get from aysaParams (passed from PHP)
        if (typeof aysaParams !== 'undefined' && aysaParams.project_id && aysaParams.project_id > 0) {
            if (window.AYSA_DEBUG === true) {
                console.log('Project ID from aysaParams:', aysaParams.project_id);
            }
            return aysaParams.project_id;
        }
        
        // Fallback to localStorage
        const storedProjectId = localStorage.getItem('aysa_project_id');
        if (storedProjectId && storedProjectId > 0) {
            console.log('Project ID from localStorage:', storedProjectId);
            return parseInt(storedProjectId);
        }
        
        // Avoid browser-side direct API calls; rely on locally persisted project id.
        let apiProjectId = null;
        
        // Fallback to PHP option if API call fails or returns no ID
        const phpProjectId = <?php echo intval(get_option('aysa_project_id', 0)); ?>;
        if (phpProjectId && phpProjectId > 0 && !apiProjectId) {
            console.log('Project ID from PHP options (fallback):', phpProjectId);
            localStorage.setItem('aysa_project_id', String(phpProjectId));
            return phpProjectId;
        }

        return apiProjectId || phpProjectId; // Return API result first, then PHP/local fallback
    }

    function getApiBaseUrl() {
        if (window.aysaParams && window.aysaParams.api_base_url) {
            return String(window.aysaParams.api_base_url).replace(/\/+$/, '');
        }
        if (window.aysa_ajax && window.aysa_ajax.api_base_url) {
            return String(window.aysa_ajax.api_base_url).replace(/\/+$/, '');
        }
        if (window.aysaApiConfig && window.aysaApiConfig.baseUrl) {
            return String(window.aysaApiConfig.baseUrl).replace(/\/+$/, '');
        }
        return 'https://api.aysa.ai';
    }

    function escapeStrategyHtml(value) {
        return String(value || '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    }

    function renderKeywordStrategyPanel(strategy) {
        const $panel = $('#aysa-keyword-strategy-panel');
        const $summary = $('#aysa-keyword-strategy-summary');
        const $list = $('#aysa-keyword-strategy-list');
        const $meta = $('#aysa-keyword-strategy-meta');

        if (!strategy || !Array.isArray(strategy.items) || strategy.items.length === 0) {
            $panel.hide();
            return;
        }

        const summary = strategy.summary || {};
        const total = Number(summary.total_keywords || strategy.items.length || 0);
        const associateCount = Number(summary.associate_existing || 0);
        const enhanceCount = Number(summary.enhance_existing || 0);
        const createCount = Number(summary.create_new_page || 0);
        const source = String(strategy.source || 'local_fallback');
        const generatedAt = String(strategy.generated_at || '');

        $meta.text(`Source: ${source} | Generated: ${generatedAt || 'N/A'}`);
        $summary.html([
            `<span class="aysa-strategy-pill">Total: ${total}</span>`,
            `<span class="aysa-strategy-pill">Associate Existing: ${associateCount}</span>`,
            `<span class="aysa-strategy-pill">Enhance Existing: ${enhanceCount}</span>`,
            `<span class="aysa-strategy-pill">Create New Page: ${createCount}</span>`
        ].join(''));

        const topItems = strategy.items.slice(0, 12);
        const rowsHtml = topItems.map((item) => {
            const keyword = escapeStrategyHtml(item.keyword || '');
            const volume = (item.search_volume !== null && item.search_volume !== undefined) ? item.search_volume : 'N/A';
            const kd = (item.kd !== null && item.kd !== undefined) ? item.kd : 'N/A';
            const rel = (item.seed_relevance !== null && item.seed_relevance !== undefined) ? item.seed_relevance : 'N/A';
            const action = String(item.recommended_action || 'enhance_existing');
            const actionLabel = action === 'associate_existing'
                ? 'Associate Existing'
                : (action === 'create_new_page' ? 'Create New Page' : 'Enhance Existing');
            const reason = escapeStrategyHtml(item.reason || '');
            return `
                <div class="aysa-keyword-strategy-item">
                    <div>
                        <div class="aysa-keyword-strategy-keyword">${keyword}</div>
                        <div class="aysa-keyword-strategy-details">Volume: ${volume} | KD: ${kd} | Relevance: ${rel}</div>
                    </div>
                    <div><span class="aysa-keyword-strategy-action action-${escapeStrategyHtml(action)}">${escapeStrategyHtml(actionLabel)}</span></div>
                    <div class="aysa-keyword-strategy-details">${reason}</div>
                </div>
            `;
        }).join('');

        $list.html(rowsHtml);
        $panel.show();
    }

    function loadKeywordStrategy(projectId) {
        if (!projectId) return;
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'aysa_keyword_discovery_get_strategy',
                nonce: aysaAdminNonce,
                project_id: parseInt(projectId, 10)
            },
            success: function(resp) {
                const strategy = (resp && resp.success && resp.data && resp.data.strategy) ? resp.data.strategy : null;
                if (strategy) {
                    window.aysaKeywordStrategy = strategy;
                }
                renderKeywordStrategyPanel(strategy);
            },
            error: function() {
                renderKeywordStrategyPanel(null);
            }
        });
    }

    function pollKeywordStrategyAsyncStatus(projectId, requestHash, attemptsLeft = 45) {
        return $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'aysa_research_async_status',
                nonce: aysaAdminNonce,
                task: 'keyword_strategy_generate',
                project_id: parseInt(projectId, 10)
            }
        }).then(function(response) {
            if (!(response && response.success && response.data)) {
                throw new Error('Keyword strategy status request failed.');
            }

            const status = response.data || {};
            if (requestHash && status.request_hash && status.request_hash !== requestHash && !status.result) {
                throw new Error('Keyword strategy worker returned mismatched request state.');
            }
            if (status.status === 'completed' && status.result) {
                return status.result;
            }
            if (status.status === 'failed') {
                throw new Error(String(status.error || 'Keyword strategy worker failed.'));
            }
            if (attemptsLeft <= 0) {
                throw new Error('Keyword strategy worker timed out.');
            }

            return new Promise(function(resolve, reject) {
                window.setTimeout(function() {
                    pollKeywordStrategyAsyncStatus(projectId, requestHash, attemptsLeft - 1).then(resolve).catch(reject);
                }, 3000);
            });
        });
    }

    function generateKeywordStrategyFromSeeds(projectId) {
        if (!projectId) {
            showNotification('Project ID is missing. Cannot generate strategy.', 'error');
            return;
        }
        const $btn = $('.aysa-generate-strategy-btn');
        if ($btn.prop('disabled')) {
            return;
        }
        $btn.prop('disabled', true).addClass('aysa-processing').text('Generating...');
        showNotification('Generating keyword strategy from seed keywords...', 'loading');

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'aysa_research_async_start',
                nonce: aysaAdminNonce,
                task: 'keyword_strategy_generate',
                project_id: parseInt(projectId, 10)
            },
            success: function(resp) {
                if (!(resp && resp.success && resp.data)) {
                    const msg = (resp && resp.data) ? String(resp.data) : 'Failed to generate strategy.';
                    showNotification(msg, 'error');
                    return;
                }
                const payload = resp.data || {};
                const finish = function(result) {
                    if (!(result && result.strategy)) {
                        const msg = result ? 'Strategy worker did not return a strategy.' : 'Failed to generate strategy.';
                        showNotification(msg, 'error');
                        return;
                    }
                    window.aysaKeywordStrategy = result.strategy;
                    renderKeywordStrategyPanel(result.strategy);
                    const summary = (result.strategy && result.strategy.summary) ? result.strategy.summary : {};
                    const total = Number(summary.total_keywords || 0);
                    const source = String(result.source || result.strategy.source || 'local_fallback');
                    showNotification(`Strategy ready: ${total} keywords (${source})`, 'success');
                };

                if (payload.status === 'completed' && payload.result) {
                    finish(payload.result);
                    return;
                }

                showNotification('Generating keyword strategy in the background...', 'loading');
                pollKeywordStrategyAsyncStatus(projectId, payload.request_hash || '')
                    .then(finish)
                    .catch(function(error) {
                        showNotification(error && error.message ? error.message : 'Failed to generate strategy.', 'error');
                    });
            },
            error: function(xhr) {
                const msg = xhr && xhr.responseJSON && xhr.responseJSON.data ? String(xhr.responseJSON.data) : 'Failed to generate strategy.';
                showNotification(msg, 'error');
            },
            complete: function() {
                $btn.prop('disabled', false).removeClass('aysa-processing').text('Generate Strategy');
            }
        });
    }

    async function generateKeywordAssociations(keywords, options = {}) {
    const opts = Object.assign({ suppressReload: false }, options || {});
    try {
        // Show loading notification
        showNotification('Generating keyword associations...', 'loading');

        const projectId = getProjectId();
        if (!projectId) {
            showToast("Project ID is missing. Please set it up in the plugin settings.", 'error');
            throw new Error('Project ID is not available.');
        }

        const googleAuto = await autoAssociateFromGoogle(keywords, projectId);
        const remainingKeywords = Array.isArray(googleAuto.remainingKeywords) ? googleAuto.remainingKeywords : [];
        if (googleAuto.associatedCount > 0) {
            showNotification(
                `Auto-associated ${googleAuto.associatedCount} keywords (GSC: ${googleAuto.gscCount}, GA4: ${googleAuto.ga4Count}, Semantic: ${googleAuto.semanticCount || 0}).`,
                'success'
            );
        }
        if ((googleAuto.createdTasks || 0) > 0) {
            showNotification(`Created ${googleAuto.createdTasks} content tasks for low-confidence keywords.`, 'warning');
        }

        if (remainingKeywords.length === 0) {
            showNotification('All unlinked keywords were handled from Google data. No extra AI request needed.', 'info');
            if (!opts.suppressReload) {
                loadAssociations();
            }
            return {
                ok: true,
                createdAssociations: [],
                googleAutoAssociated: googleAuto.associatedCount
            };
        }

        const aiEligibleKeywords = remainingKeywords.filter(k => !isSyntheticTestKeyword(k));
        const skippedSynthetic = remainingKeywords.length - aiEligibleKeywords.length;
        if (skippedSynthetic > 0) {
            showNotification(`Skipped ${skippedSynthetic} low-quality/test keywords from AI auto-association.`, 'warning');
        }
        if (aiEligibleKeywords.length === 0) {
            showNotification('No remaining keywords are eligible for AI association after quality checks.', 'info');
            if (!opts.suppressReload) {
                loadAssociations();
            }
            return {
                ok: true,
                createdAssociations: [],
                googleAutoAssociated: googleAuto.associatedCount,
                aiSkipped: skippedSynthetic
            };
        }

        // Get categories, pages, and products from WordPress
        const categories = await getWordPressItems('Category');
        const pages = await getWordPressItems('Page');
        const products = await getWordPressItems('Product');

        // Format the data according to the API's expected structure
        const requestData = {
            ProjectId: projectId,
            Keywords: aiEligibleKeywords,
            Categories: categories.map(cat => ({
                Id: cat.id,
                Name: cat.name
            })),
            Pages: pages.map(page => ({
                Id: page.id,
                Name: page.name
            })),
            Products: products.map(product => ({
                Id: product.id,
                Name: product.name
            }))
        };

        console.log('Sending request data:', requestData);

        // Set up manual timeout with AbortController (e.g., 5 minutes)
        const controller = new AbortController();
        const timeout = 300000; // 5 minutes in ms

        const timeoutId = setTimeout(() => {
            controller.abort();
        }, timeout);

        // Make API call to generate associations
        const response = await fetch(`${getApiBaseUrl()}/api/ChatGPT/generate-keyword-associations`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(requestData),
            signal: controller.signal
        });

        clearTimeout(timeoutId); // Cancel the timeout if request completes

        if (!response.ok) {
            const errorData = await response.json().catch(() => ({}));
            throw new Error(errorData.title || 'Failed to generate associations');
        }

        const result = await response.json();
        console.log('API Response:', result);

        if (!result) {
            showNotification('No associations were created.', 'info');
            return;
        }

        // Check if we have created new associations first, then existing ones
        if (Array.isArray(result.createdAssociations) && result.createdAssociations.length > 0) {
            showNotification(`AI created ${result.createdAssociations.length} new associations.`, 'success');
        } else if (result.existingAssociations) {
            showNotification('All products/pages/categories already have associations.', 'info');
        } else {
            showNotification('No new associations were created.', 'info');
        }

        if (!opts.suppressReload) {
            // Refresh full associations list to keep UI state consistent.
            loadAssociations();
        } else if (Array.isArray(result.createdAssociations) && result.createdAssociations.length > 0) {
            if (!Array.isArray(window.aysaAssociations)) {
                window.aysaAssociations = [];
            }
            result.createdAssociations.forEach((assoc, idx) => {
                const keyword = String((assoc && assoc.keyword) || '').trim();
                const associatedOn = String((assoc && assoc.associatedOn) || '');
                const idIntern = String((assoc && assoc.idIntern) || '');
                if (!keyword || !associatedOn || !idIntern) {
                    return;
                }
                const exists = window.aysaAssociations.some(a =>
                    normalizeKeyword(String(a.keyword || '')) === normalizeKeyword(keyword) &&
                    String(a.associatedOn || '') === associatedOn &&
                    String(a.idIntern || '') === idIntern
                );
                if (!exists) {
                    window.aysaAssociations.push({
                        keyword: keyword,
                        associatedOn: associatedOn,
                        idIntern: idIntern,
                        value: String((assoc && assoc.value) || ''),
                        id: assoc && assoc.id ? assoc.id : (Date.now() + idx)
                    });
                }
            });
        }

        return result;
    } catch (error) {
        if (error.name === 'AbortError') {
            console.error('Request timed out after 5 minutes.');
            showNotification('Request timed out after 5 minutes.', 'error');
        } else {
            console.error('Error generating associations:', error);
            showNotification('Error generating associations: ' + error.message, 'error');
        }
        return null;
    }
}

    // Pagination event handlers for both top and bottom
    $('#aysa-prev-btn, #aysa-prev-btn-bottom').on('click', function() {
        if (currentPage > 1) {
            goToPage(currentPage - 1);
        }
    });
    
    $('#aysa-next-btn, #aysa-next-btn-bottom').on('click', function() {
        const totalPages = Math.ceil(filteredKeywords.length / itemsPerPage);
        if (currentPage < totalPages) {
            goToPage(currentPage + 1);
        }
    });
    
    // Handle page number clicks
    $(document).on('click', '.aysa-page-number', function() {
        const page = parseInt($(this).data('page'));
        if (page && page !== currentPage) {
            goToPage(page);
        }
    });
    
    // Handle rows per page change
    $('#aysa-rows-per-page').on('change', function() {
        const selectedValue = parseInt($(this).val());
        updateItemsPerPage(selectedValue);
    });
    
    // Function to update items per page
    function updateItemsPerPage(newItemsPerPage) {
        itemsPerPage = newItemsPerPage;
        currentPage = 1; // Reset to first page
        
        // Save preference to localStorage
        localStorage.setItem('aysa_items_per_page', itemsPerPage);
        
        // Update select value if it was changed programmatically
        if (parseInt($('#aysa-rows-per-page').val()) !== itemsPerPage) {
            $('#aysa-rows-per-page').val(itemsPerPage.toString());
        }
        
        // Update display
        displayCurrentPage();
        updatePaginationControls();
        updatePaginationInfo();
        
        showNotification(`Showing ${itemsPerPage} rows per page`, 'info');
    }
    
    function isKeywordDiscoveryV2Tab() {
        return activeKeywordSubtab === 'gsc_v2' || activeKeywordSubtab === 'dataforseo_v2' || activeKeywordSubtab === 'competitor_gap_v2' || activeKeywordSubtab === 'keyword_mapping_v2';
    }

    function escapeHtml(value) {
        return String(value == null ? '' : value)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

    function formatV2Number(value, decimals = 0) {
        if (value === null || value === undefined || value === '' || value === 'N/A') {
            return '—';
        }
        const num = Number(value);
        if (!Number.isFinite(num)) {
            return '—';
        }
        return num.toLocaleString(undefined, {
            minimumFractionDigits: decimals,
            maximumFractionDigits: decimals
        });
    }

    function renderKeywordDiscoveryV2(tab, payload) {
        const table = $('#aysa-kd-v2-table');
        const thead = table.find('thead');
        const tbody = table.find('tbody');
        const workspace = $('#aysa-km-workspace');
        const rows = (payload && Array.isArray(payload.rows)) ? payload.rows : [];
        const count = Number(payload && payload.count ? payload.count : rows.length || 0);
        const cacheMeta = payload && payload.cache_meta ? payload.cache_meta : {};
        const keywordMappingFilterWrap = $('#aysa-km-status-filter-wrap');
        const keywordMappingFilter = $('#aysa-km-status-filter');
        if (tab === 'keyword_mapping_v2') {
            keywordMappingFilterWrap.removeClass('aysa-hidden').css('display', 'inline-flex');
            keywordMappingFilter.val(keywordMappingStatusFilter);
            workspace.removeClass('aysa-hidden');
            table.closest('.aysa-table-responsive').addClass('aysa-hidden');
        } else {
            keywordMappingFilterWrap.addClass('aysa-hidden').css('display', 'none');
            workspace.addClass('aysa-hidden').empty();
            table.closest('.aysa-table-responsive').removeClass('aysa-hidden');
        }
        tbody.empty();

        if (tab === 'gsc_v2') {
            $('#aysa-kd-v2-title').text('Google Search Console');
            const diagnostics = payload && payload.diagnostics ? payload.diagnostics : {};
            const gscSite = diagnostics.used_gsc_site || diagnostics.selected_gsc_site || '';
            $('#aysa-kd-v2-meta').text(`Rows: ${count} | GSC site: ${gscSite || 'n/a'}${cacheMeta.cached_at ? ` | ${cacheMeta.source || 'cache'} @ ${cacheMeta.cached_at}` : ''}`);
            thead.html(`
                <tr>
                    <th>Keyword</th>
                    <th>Page</th>
                    <th>Clicks</th>
                    <th>Impressions</th>
                    <th>CTR</th>
                    <th>Position</th>
                    <th>Row Type</th>
                </tr>
            `);
            rows.forEach((row) => {
                tbody.append(`
                    <tr>
                        <td>${escapeHtml(row.keyword || '')}</td>
                        <td>${escapeHtml(row.page || '')}</td>
                        <td>${formatV2Number(row.clicks || 0)}</td>
                        <td>${formatV2Number(row.impressions || 0)}</td>
                        <td>${row.ctr == null ? '—' : `${formatV2Number((Number(row.ctr) * 100), 2)}%`}</td>
                        <td>${formatV2Number(row.position, 2)}</td>
                        <td>${escapeHtml(row.row_type || '')}</td>
                    </tr>
                `);
            });
        } else if (tab === 'dataforseo_v2') {
            $('#aysa-kd-v2-title').text('Sugestii keywords');
            const seedKeywords = payload && Array.isArray(payload.seed_keywords) ? payload.seed_keywords : [];
            const provider = payload && payload.provider ? payload.provider : '';
            $('#aysa-kd-v2-meta').text(`Rows: ${count} | Seeds: ${seedKeywords.join(', ')}${provider ? ' | Metrici SEO' : ''}${cacheMeta.cached_at ? ` | ${cacheMeta.source || 'cache'} @ ${cacheMeta.cached_at}` : ''}`);
            thead.html(`
                <tr>
                    <th>Keyword</th>
                    <th>Seed</th>
                    <th>Source</th>
                    <th>Intent</th>
                    <th>Volume</th>
                    <th>KD</th>
                    <th>CPC</th>
                    <th>SERP Types</th>
                </tr>
            `);
            rows.forEach((row) => {
                const itemTypes = Array.isArray(row.item_types) ? row.item_types.join(', ') : '';
                tbody.append(`
                    <tr>
                        <td>${escapeHtml(row.keyword || '')}</td>
                        <td>${escapeHtml(row.seed_keyword || '')}</td>
                        <td>${escapeHtml(row.source || '')}</td>
                        <td>${escapeHtml(row.intent || '')}</td>
                        <td>${formatV2Number(row.search_volume || 0)}</td>
                        <td>${formatV2Number(row.kd, 2)}</td>
                        <td>${formatV2Number(row.cpc, 2)}</td>
                        <td>${escapeHtml(itemTypes)}</td>
                    </tr>
                `);
            });
        } else if (tab === 'competitor_gap_v2') {
            const gapBuildTag = 'CG-V2-20260328-1102';
            $('#aysa-kd-v2-title').text(`Competitor Gap ${gapBuildTag}`);
            const competitors = payload && Array.isArray(payload.competitors) ? payload.competitors : [];
            const missingCount = payload && payload.missing_count ? Number(payload.missing_count) : 0;
            const provider = payload && payload.provider ? payload.provider : '';
            $('#aysa-kd-v2-meta').text(`Build: ${gapBuildTag} | Rows: ${count} | Missing: ${missingCount} | Competitors: ${competitors.join(', ')}${provider ? ` | ${provider}` : ''}${cacheMeta.cached_at ? ` | ${cacheMeta.source || 'cache'} @ ${cacheMeta.cached_at}` : ''}`);
            thead.html(`
                <tr>
                    <th>Keyword</th>
                    <th>Gap Type</th>
                    <th>Competitors</th>
                    <th>Competitor Count</th>
                    <th>Search Volume</th>
                    <th>Our Volume</th>
                </tr>
            `);
            rows.forEach((row) => {
                const competitorList = Array.isArray(row.competitors) ? row.competitors.join(', ') : '';
                tbody.append(`
                    <tr>
                        <td>${escapeHtml(row.keyword || '')}</td>
                        <td>${escapeHtml(row.gap_type || '')}</td>
                        <td>${escapeHtml(competitorList)}</td>
                        <td>${formatV2Number(row.competitor_count || 0)}</td>
                        <td>${formatV2Number(row.search_volume || 0)}</td>
                        <td>${formatV2Number(row.our_search_volume, 0)}</td>
                    </tr>
                `);
            });
        } else {
            $('#aysa-kd-v2-title').text('Keyword Mapping');
            const build = payload && payload.workspace_build ? payload.workspace_build : (payload && payload.build ? payload.build : 'KMV1');
            const matcherBuild = payload && payload.matcher_build ? payload.matcher_build : 'KMM2';
            const uiBuild = 'KDUX1-20260329-01';
            const summary = payload && payload.summary ? payload.summary : {};
            const stats = payload && payload.source_stats ? payload.source_stats : {};
            const qualityFlags = payload && Array.isArray(payload.quality_flags) ? payload.quality_flags : [];
            const allClusters = payload && Array.isArray(payload.clusters) ? payload.clusters : [];
            const clusters = allClusters.filter((cluster) => {
                if (keywordMappingStatusFilter === 'all') {
                    return true;
                }
                return String(cluster.mapping_status || 'not_mapped') === keywordMappingStatusFilter;
            });
            $('#aysa-kd-v2-meta').text(
                `Build: ${build} | Keywords: ${formatV2Number(summary.total_keywords || 0)} | Clusters: ${formatV2Number(summary.cluster_count || 0)} | Visible: ${formatV2Number(clusters.length || 0)} | Selected clusters: ${formatV2Number(summary.selected_clusters || 0)} | Selected keywords: ${formatV2Number(summary.selected_keywords || 0)} | GSC: ${formatV2Number(stats.gsc || 0)} | DATA: ${formatV2Number(stats.data || 0)} | GAP: ${formatV2Number(stats.gap || 0)} | MULTI: ${formatV2Number(stats.multi || 0)}${qualityFlags.length ? ` | Flags: ${qualityFlags.join(', ')}` : ''}${cacheMeta.cached_at ? ` | ${cacheMeta.source || 'cache'} @ ${cacheMeta.cached_at}` : ''}`
            );
            $('#aysa-kd-v2-build').text(`Workspace: ${build} | Matcher: ${matcherBuild} | UI: ${uiBuild}`);
            thead.empty();
            tbody.empty();
            workspace.empty();
            if (!clusters.length) {
                workspace.html('<div style="padding:16px;border:1px solid #e5e7eb;border-radius:12px;background:#fff;">No keyword clusters returned for the current mapping filter.</div>');
                return;
            }
            clusters.forEach((cluster) => {
                const sources = Array.isArray(cluster.sources) ? cluster.sources : [];
                const secondaryKeywords = Array.isArray(cluster.secondary_keywords) ? cluster.secondary_keywords : [];
                const clusterSourcesHtml = sources.map((source) => `<span style="display:inline-block;padding:3px 8px;border-radius:999px;background:#e8eefb;color:#26437a;font-size:11px;font-weight:600;margin-right:6px;">${escapeHtml(source)}</span>`).join('');
                const clusterActionsHtml = ['selected', 'review', 'excluded'].map((state) => {
                    const active = String(cluster.selection_state || '') === state;
                    return `<button type="button" class="button button-small aysa-km-state-btn ${active ? 'button-primary' : ''}" data-cluster-id="${escapeHtml(cluster.cluster_id || '')}" data-selection-state="${state}" style="margin-right:6px;">${escapeHtml(state)}</button>`;
                }).join('');
                const clusterType = String(cluster.cluster_type || (secondaryKeywords.length ? 'cluster' : 'standalone'));
                const targetPageType = String(cluster.target_page_type || '');
                const mappingStatus = String(cluster.mapping_status || 'not_mapped');
                const mappingConfidence = cluster.mapping_confidence == null ? null : Number(cluster.mapping_confidence);
                const matchedPage = cluster && cluster.matched_page ? cluster.matched_page : null;
                const explainability = cluster && cluster.explainability ? cluster.explainability : {};
                const reviewContext = cluster && cluster.review_context ? cluster.review_context : {};
                const pageMatches = Array.isArray(reviewContext.top_candidates) && reviewContext.top_candidates.length
                    ? reviewContext.top_candidates
                    : (Array.isArray(explainability.page_matches) ? explainability.page_matches.slice(0, 3) : []);
                const businessFitScore = cluster.business_fit_score == null ? null : Number(cluster.business_fit_score);
                const failedChecks = Array.isArray(reviewContext.failed_checks) ? reviewContext.failed_checks : [];
                const mappingBadge = mappingStatus === 'mapped'
                    ? '<span style="display:inline-block;padding:3px 8px;border-radius:999px;background:#eaf7ed;color:#22663b;font-size:11px;font-weight:700;margin-right:6px;">MAPPED</span>'
                    : (mappingStatus === 'review'
                        ? '<span style="display:inline-block;padding:3px 8px;border-radius:999px;background:#fff7e8;color:#9a6700;font-size:11px;font-weight:700;margin-right:6px;">REVIEW</span>'
                        : '<span style="display:inline-block;padding:3px 8px;border-radius:999px;background:#fff1f0;color:#9a3412;font-size:11px;font-weight:700;margin-right:6px;">NOT MAPPED</span>');
                const candidateHtml = pageMatches.length ? `<div style="margin-top:10px;padding:10px 12px;border:1px solid #ebeef4;border-radius:10px;background:#fcfcfd;">
                        <div style="font-size:11px;font-weight:700;letter-spacing:.06em;color:#667085;text-transform:uppercase;margin-bottom:8px;">Review candidates</div>
                        ${pageMatches.map((candidate) => {
                            const confidence = candidate && candidate.confidence != null ? Number(candidate.confidence) : null;
                            const primaryCoverage = candidate && candidate.primary_coverage != null ? Number(candidate.primary_coverage) : null;
                            const modifierCoverage = candidate && candidate.modifier_coverage != null ? Number(candidate.modifier_coverage) : null;
                            return `<div style="padding:6px 0;border-top:1px solid #f2f4f7;">
                                <div style="font-size:12px;color:#344054;"><strong>${escapeHtml(candidate.url || '')}</strong></div>
                                <div style="font-size:11px;color:#667085;display:flex;gap:12px;flex-wrap:wrap;margin-top:4px;">
                                    ${candidate.type ? `<span>Type: <strong>${escapeHtml(candidate.type || '')}</strong></span>` : ''}
                                    ${confidence != null ? `<span>Match: <strong>${formatV2Number(Math.min(100, confidence * 100), 1)}%</strong></span>` : ''}
                                    ${primaryCoverage != null ? `<span>Topic: <strong>${formatV2Number(Math.min(100, primaryCoverage * 100), 1)}%</strong></span>` : ''}
                                    ${modifierCoverage != null ? `<span>Modifiers: <strong>${formatV2Number(Math.min(100, modifierCoverage * 100), 1)}%</strong></span>` : ''}
                                </div>
                            </div>`;
                        }).join('')}
                    </div>` : '';
                const reviewSummaryHtml = (mappingStatus === 'review' || mappingStatus === 'not_mapped') ? `<div style="margin-top:10px;padding:10px 12px;border:1px solid ${mappingStatus === 'review' ? '#f6e4b3' : '#fed7d7'};border-radius:10px;background:${mappingStatus === 'review' ? '#fffaf0' : '#fff5f5'};">
                        <div style="font-size:11px;font-weight:700;letter-spacing:.06em;color:${mappingStatus === 'review' ? '#9a6700' : '#9a3412'};text-transform:uppercase;margin-bottom:6px;">Agent 8 review context</div>
                        ${reviewContext.reason ? `<div style="font-size:12px;color:#475467;">${escapeHtml(reviewContext.reason || '')}</div>` : ''}
                        <div style="font-size:11px;color:#667085;display:flex;gap:12px;flex-wrap:wrap;margin-top:6px;">
                            ${businessFitScore != null ? `<span>Business fit: <strong>${formatV2Number(Math.min(100, businessFitScore * 100), 1)}%</strong></span>` : ''}
                            ${reviewContext.mapping_threshold != null ? `<span>Auto-map threshold: <strong>${formatV2Number(Math.min(100, Number(reviewContext.mapping_threshold) * 100), 1)}%</strong></span>` : ''}
                            ${reviewContext.review_floor != null ? `<span>Review floor: <strong>${formatV2Number(Math.min(100, Number(reviewContext.review_floor) * 100), 1)}%</strong></span>` : ''}
                        </div>
                        ${failedChecks.length ? `<div style="margin-top:6px;font-size:11px;color:#667085;">Failed checks: <strong>${escapeHtml(failedChecks.join(', '))}</strong></div>` : ''}
                        ${candidateHtml}
                    </div>` : '';

                const keywordRowHtml = (row, kind = 'secondary') => {
                    const rowSources = Array.isArray(row.sources) ? row.sources : [];
                    const sourceBadges = rowSources.map((source) => {
                        return `<span style="display:inline-block;padding:2px 7px;border-radius:999px;background:${rowSources.length > 1 ? '#eef7ec' : '#eef2ff'};color:${rowSources.length > 1 ? '#22663b' : '#304b91'};font-size:11px;font-weight:600;margin-right:6px;">${escapeHtml(source)}</span>`;
                    }).join('');
                    const intent = row.intent ? `<span style="display:inline-block;padding:2px 7px;border-radius:999px;background:#f4f5f7;color:#394150;font-size:11px;font-weight:600;margin-right:6px;">${escapeHtml(row.intent)}</span>` : '';
                    const stateButtons = ['selected', 'review', 'excluded'].map((state) => {
                        const active = String(row.selection_state || '') === state;
                        return `<button type="button" class="button button-small aysa-km-state-btn ${active ? 'button-primary' : ''}" data-keyword="${escapeHtml(row.keyword || '')}" data-selection-state="${state}" style="margin-right:6px;">${escapeHtml(state)}</button>`;
                    }).join('');
                    const rowPages = row.origin_signals && row.origin_signals.gsc && row.origin_signals.gsc.page ? row.origin_signals.gsc.page : '';
                    const rowCtr = row.origin_signals && row.origin_signals.gsc && row.origin_signals.gsc.ctr != null ? row.origin_signals.gsc.ctr : null;
                    const priority = row.priority_score == null ? '—' : formatV2Number(row.priority_score, 2);
                    const volume = row.search_volume == null ? '—' : formatV2Number(row.search_volume, 0);
                    const rowExplainability = row && row.explainability ? row.explainability : {};
                    const keywordMatches = Array.isArray(row.keyword_page_matches) ? row.keyword_page_matches : [];
                    const bestKeywordMatch = keywordMatches.length ? keywordMatches[0] : null;
                    const keywordConfidence = bestKeywordMatch && bestKeywordMatch.confidence != null ? Number(bestKeywordMatch.confidence) : null;
                    return `
                        <div style="display:flex;align-items:flex-start;justify-content:space-between;gap:16px;padding:${kind === 'primary' ? '14px 16px' : '12px 16px 12px 34px'};border-top:1px solid #edf0f5;background:${kind === 'primary' ? '#fbfcff' : '#ffffff'};">
                            <div style="flex:1;min-width:0;">
                                <div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px;">
                                    <span style="display:inline-block;padding:3px 8px;border-radius:999px;background:${kind === 'primary' ? '#1f3b6f' : '#eef2ff'};color:${kind === 'primary' ? '#fff' : '#304b91'};font-size:11px;font-weight:700;">${kind === 'primary' ? 'PRIMARY' : 'SECONDARY'}</span>
                                    <strong style="font-size:${kind === 'primary' ? '15px' : '14px'};">${escapeHtml(row.keyword || '')}</strong>
                                </div>
                                <div style="margin-bottom:8px;">${sourceBadges}${intent}</div>
                                <div style="font-size:12px;color:#5e6675;display:flex;gap:16px;flex-wrap:wrap;">
                                    <span>Priority: <strong>${priority}</strong></span>
                                    <span>Volume: <strong>${volume}</strong></span>
                                    <span>KD: <strong>${row.kd == null ? '—' : formatV2Number(row.kd, 2)}</strong></span>
                                    <span>Clicks: <strong>${formatV2Number(row.gsc_clicks || 0)}</strong></span>
                                    ${rowCtr != null ? `<span>CTR: <strong>${formatV2Number(rowCtr, 2)}</strong></span>` : ''}
                                    ${rowPages ? `<span>Page: <strong>${escapeHtml(rowPages)}</strong></span>` : ''}
                                </div>
                                ${bestKeywordMatch && bestKeywordMatch.url ? `<div style="margin-top:6px;font-size:12px;color:#475467;">Keyword best match: <strong>${escapeHtml(bestKeywordMatch.url || '')}</strong>${keywordConfidence != null ? ` (${formatV2Number((keywordConfidence * 100), 1)}%)` : ''}</div>` : ''}
                                ${rowExplainability.why_retained ? `<div style="margin-top:8px;font-size:12px;color:#667085;">${escapeHtml(rowExplainability.why_retained || '')}</div>` : ''}
                            </div>
                            <div style="flex:0 0 auto;white-space:nowrap;">${stateButtons}</div>
                        </div>
                    `;
                };

                const secondaryHtml = secondaryKeywords.map((row) => keywordRowHtml(row, 'secondary')).join('');
                workspace.append(`
                    <div style="border:1px solid #dfe5ef;border-radius:14px;overflow:hidden;background:#fff;margin-bottom:18px;box-shadow:0 1px 2px rgba(16,24,40,0.04);">
                        <div style="padding:16px;border-bottom:1px solid #edf0f5;background:#f7f9fc;">
                            <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:16px;flex-wrap:wrap;">
                                <div style="flex:1;min-width:280px;">
                                    <div style="font-size:11px;font-weight:700;letter-spacing:.08em;color:#64708a;text-transform:uppercase;margin-bottom:6px;">Cluster</div>
                                    <div style="font-size:18px;font-weight:700;color:#1b2433;margin-bottom:8px;">${escapeHtml(cluster.label || '')}</div>
                                    <div style="margin-bottom:8px;">${mappingBadge}${clusterSourcesHtml}</div>
                                    <div style="font-size:12px;color:#5e6675;display:flex;gap:16px;flex-wrap:wrap;">
                                        <span>Type: <strong>${escapeHtml(clusterType)}</strong></span>
                                        ${targetPageType ? `<span>Page type: <strong>${escapeHtml(targetPageType)}</strong></span>` : ''}
                                        <span>Priority: <strong>${formatV2Number(cluster.priority_score, 2)}</strong></span>
                                        <span>Intent: <strong>${escapeHtml(cluster.intent_summary || '')}</strong></span>
                                        <span>Secondary: <strong>${formatV2Number(secondaryKeywords.length, 0)}</strong></span>
                                        ${mappingConfidence != null ? `<span>Match: <strong>${formatV2Number(Math.min(100, mappingConfidence * 100), 1)}%</strong></span>` : ''}
                                    </div>
                                    ${matchedPage && matchedPage.url ? `<div style="margin-top:8px;font-size:12px;color:#475467;">Best match: <strong>${escapeHtml(matchedPage.url || '')}</strong></div>` : ''}
                                    ${explainability.why_cluster_exists ? `<div style="margin-top:10px;font-size:12px;color:#667085;">${escapeHtml(explainability.why_cluster_exists || '')}</div>` : ''}
                                    ${explainability.why_mapped ? `<div style="margin-top:4px;font-size:12px;color:#667085;">${escapeHtml(explainability.why_mapped || '')}</div>` : ''}
                                    ${reviewSummaryHtml}
                                </div>
                                <div style="flex:0 0 auto;white-space:nowrap;">
                                    ${clusterActionsHtml}
                                </div>
                            </div>
                        </div>
                        ${keywordRowHtml(cluster.primary_keyword || {}, 'primary')}
                        ${secondaryHtml}
                    </div>
                `);
            });
            return;
        }

        if (!rows.length) {
            tbody.append('<tr><td colspan="8">No rows returned.</td></tr>');
        }
    }

    function loadKeywordDiscoveryV2(forceRefresh = false) {
        const projectId = getProjectId();
        if (!projectId) {
            return;
        }
        const tab = activeKeywordSubtab;
        if (!isKeywordDiscoveryV2Tab()) {
            return;
        }
        if (!forceRefresh && keywordDiscoveryV2Cache[tab]) {
            renderKeywordDiscoveryV2(tab, keywordDiscoveryV2Cache[tab]);
            $('#aysa-kd-v2-status').text('Loaded from current browser session.');
            return;
        }

        let action = 'aysa_keyword_discovery_v2_gsc_raw';
        if (tab === 'dataforseo_v2') {
            action = 'aysa_keyword_discovery_v2_dataforseo_raw';
        } else if (tab === 'competitor_gap_v2') {
            action = 'aysa_keyword_discovery_v2_competitor_gap_raw';
        } else if (tab === 'keyword_mapping_v2') {
            // LEGACY UI PATH: read/debug only. Canonical Agent8 V3 mapping comes from the research run projection.
            action = 'aysa_keyword_mapping_v1_workspace';
        }

        const buildTag = 'KDUX1-20260329-01';
        $('#aysa-kd-v2-status').text(`Loading live rows... ${buildTag}`);
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {
                action: action,
                nonce: aysaKeywordCacheNonce,
                project_id: projectId,
                force_refresh: forceRefresh ? 1 : 0
            }
        }).done(function(resp) {
            if (!(resp && resp.success && resp.data)) {
                const message = resp && resp.data ? resp.data : 'Unknown error';
                $('#aysa-kd-v2-status').text(`Failed [${buildTag}]: ${message}`);
                return;
            }
            keywordDiscoveryV2Cache[tab] = resp.data;
            renderKeywordDiscoveryV2(tab, resp.data);
            const loadedCount = tab === 'keyword_mapping_v2'
                ? Number(resp.data && resp.data.summary && resp.data.summary.cluster_count ? resp.data.summary.cluster_count : 0)
                : Number(resp.data && resp.data.count ? resp.data.count : 0);
            $('#aysa-kd-v2-status').text(`Loaded [${buildTag}] ${loadedCount} ${tab === 'keyword_mapping_v2' ? 'clusters' : 'rows'}.`);
        }).fail(function(xhr) {
            let message = 'Request failed';
            if (xhr && xhr.responseJSON && xhr.responseJSON.data) {
                message = xhr.responseJSON.data;
            }
            $('#aysa-kd-v2-status').text(`Failed [${buildTag}]: ${message}`);
        });
    }

    function applyKeywordSubtabUi() {
        $('.aysa-kd-subtab').each(function() {
            const tab = $(this).data('subtab');
            const isActive = tab === activeKeywordSubtab;
            $(this).toggleClass('is-active', isActive);
            $(this).attr('aria-selected', isActive ? 'true' : 'false');
        });

        const isDashboard = activeKeywordSubtab === 'dashboard';
        const isV2 = isKeywordDiscoveryV2Tab();
        $('.aysa-kd-dashboard-panel').toggle(isDashboard);
        $('#aysa-kd-v2-panel').toggleClass('aysa-hidden', !isV2);
        $('.aysa-kd-data-panel').toggleClass('is-hidden', isDashboard || isV2);
        if (activeKeywordSubtab === 'gsc_plus_data') {
            $('#aysa-gsc-data-clusters').removeClass('aysa-hidden');
            $('.aysa-table-responsive, .aysa-pagination-top, .aysa-pagination-bottom').addClass('aysa-hidden');
        } else {
            $('#aysa-gsc-data-clusters').addClass('aysa-hidden');
            if (!isV2) {
                $('.aysa-table-responsive, .aysa-pagination-top, .aysa-pagination-bottom').removeClass('aysa-hidden');
            }
        }
    }

    function loadActiveKeywordSubtabData() {
        const projectId = getProjectId();
        if (!projectId) {
            return;
        }
        if (isKeywordDiscoveryV2Tab()) {
            loadKeywordDiscoveryV2(false);
            return;
        }
        if (activeKeywordSubtab === 'dashboard') {
            return;
        }
        if (activeKeywordSubtab === 'keyword_suggestions') {
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                dataType: 'json',
                data: {
                    action: 'aysa_keyword_discovery_local_keywords',
                    nonce: aysaKeywordCacheNonce,
                    project_id: projectId,
                    source_mode: 'keyword_suggestions'
                }
            }).done(function(localResp) {
                const localCount = (localResp && localResp.success && localResp.data)
                    ? parseInt(localResp.data.count || 0, 10)
                    : 0;
                const snapshotRunId = (localResp && localResp.success && localResp.data && localResp.data.snapshot)
                    ? String(localResp.data.snapshot.run_id || '').trim()
                    : '';

                if (localCount > 0) {
                    keywordSuggestionsAutoloadByProject[projectId] = true;
                    loadKeywordsFromApi(false, {
                        sourceMode: 'keyword_suggestions',
                        includeGoogle: false,
                        silent: true,
                        noLoadingState: false
                    }).then(function() {
                        if (snapshotRunId) {
                            showNotification(
                                `Loaded ${localCount} keyword suggestions from research run #${snapshotRunId}.`,
                                'success'
                            );
                        }
                    });
                    return;
                }

                showNotification('Generating keyword suggestions from current seed keywords...', 'loading');
                refreshKeywordSuggestionsData()
                    .then(function(refreshData) {
                        const seedCount = Array.isArray(refreshData && refreshData.seed_keywords)
                            ? refreshData.seed_keywords.length
                            : 0;
                        keywordSuggestionsAutoloadByProject[projectId] = true;
                        return loadKeywordsFromApi(false, {
                            sourceMode: 'keyword_suggestions',
                            includeGoogle: false,
                            silent: true,
                            noLoadingState: false
                        }).then(function() {
                            showNotification(
                                `Keyword Suggestions populated from ${seedCount || 'available'} seed keywords.`,
                                'success'
                            );
                        });
                    })
                    .catch(function(error) {
                        window.aysaKeywords = [];
                        allKeywords = [];
                        filteredKeywords = [];
                        displayKeywordResults([], true);
                        showNotification(
                            `Keyword suggestions could not be generated from current seed keywords: ${error.message || error}`,
                            'error'
                        );
                    });
            }).fail(function() {
                showNotification('Generating keyword suggestions from current seed keywords...', 'loading');
                refreshKeywordSuggestionsData()
                    .then(function(refreshData) {
                        const seedCount = Array.isArray(refreshData && refreshData.seed_keywords)
                            ? refreshData.seed_keywords.length
                            : 0;
                        keywordSuggestionsAutoloadByProject[projectId] = true;
                        return loadKeywordsFromApi(false, {
                            sourceMode: 'keyword_suggestions',
                            includeGoogle: false,
                            silent: true,
                            noLoadingState: false
                        }).then(function() {
                            showNotification(
                                `Keyword Suggestions populated from ${seedCount || 'available'} seed keywords.`,
                                'success'
                            );
                        });
                    })
                    .catch(function(error) {
                        window.aysaKeywords = [];
                        allKeywords = [];
                        filteredKeywords = [];
                        displayKeywordResults([], true);
                        showNotification(
                            `Keyword suggestions could not be generated from current seed keywords: ${error.message || error}`,
                            'error'
                        );
                    });
            });
            return;
        }
        if (activeKeywordSubtab === 'gsc_plus_data') {
            window.aysaGoogleDataDiagnostics = {
                connected: null,
                gscRows: 0,
                gscQueryRows: 0,
                ga4Rows: 0,
                selectedGsc: '',
                usedGsc: '',
                selectedGa4: '',
                message: 'checking live Google status...'
            };
            renderGoogleDataStatus();

            $.ajax({
                url: ajaxurl,
                type: 'POST',
                dataType: 'json',
                data: {
                    action: 'aysa_keyword_discovery_local_keywords',
                    nonce: aysaKeywordCacheNonce,
                    project_id: projectId,
                    source_mode: 'keyword_suggestions'
                }
            }).done(function(localResp) {
                const localCount = (localResp && localResp.success && localResp.data)
                    ? parseInt(localResp.data.count || 0, 10)
                    : 0;

                const loadCombined = function(forceRefreshGoogle = false) {
                    return loadKeywordsFromApi(false, {
                        sourceMode: 'keyword_suggestions',
                        includeGoogle: true,
                        silent: true,
                        noLoadingState: false,
                        forceRefreshGoogle: forceRefreshGoogle
                    });
                };

                if (localCount > 0) {
                    loadCombined(false);
                    return;
                }

                showNotification('Generating DATA suggestions and loading live GSC rows...', 'loading');
                refreshKeywordSuggestionsData()
                    .then(function() {
                        return loadCombined(true);
                    })
                    .then(function() {
                        showNotification('GSC + DATA loaded.', 'success');
                    })
                    .catch(function(error) {
                        window.aysaKeywords = [];
                        allKeywords = [];
                        filteredKeywords = [];
                        displayKeywordResults([], true);
                        showNotification(`GSC + DATA could not be loaded: ${error.message || error}`, 'error');
                    });
            }).fail(function() {
                loadKeywordsFromApi(false, {
                    sourceMode: 'keyword_suggestions',
                    includeGoogle: true,
                    silent: true,
                    noLoadingState: false,
                    forceRefreshGoogle: false
                });
            });
            return;
        }
        window.aysaGoogleDataDiagnostics = {
            connected: null,
            gscRows: 0,
            gscQueryRows: 0,
            ga4Rows: 0,
            selectedGsc: '',
            usedGsc: '',
            selectedGa4: '',
            message: 'checking live Google status...'
        };
        renderGoogleDataStatus();
        loadGoogleKeywordRecommendations(projectId, { forceRefresh: false }).catch(() => {});
        loadTargetKeywordsFromApi({
            sourceMode: 'gsc_auto',
            includeGoogle: false,
            silent: true
        });
    }

    function switchKeywordSubtab(tabId) {
        const target = String(tabId || '').trim();
        if (!target || target === activeKeywordSubtab) {
            applyKeywordSubtabUi();
            renderGoogleDataStatus();
            return;
        }
        activeKeywordSubtab = target;
        try {
            localStorage.setItem('aysa_keyword_discovery_subtab', activeKeywordSubtab);
        } catch (error) {}
        persistKeywordWorkspaceState(activeKeywordSubtab);
        // Keep data isolated between subtabs so "Keyword Suggestions" shows only its endpoint rows.
        allKeywords = [];
        filteredKeywords = [];
        window.aysaKeywords = [];
        applyKeywordSubtabUi();
        if (isKeywordDiscoveryV2Tab()) {
            loadKeywordDiscoveryV2(false);
            return;
        }
        renderGoogleDataStatus();
        loadActiveKeywordSubtabData();
    }

    $(document).on('click', '.aysa-kd-subtab', function() {
        switchKeywordSubtab($(this).data('subtab'));
    });

    $(document).on('click', '#aysa-kd-v2-refresh', function() {
        if (!isKeywordDiscoveryV2Tab()) {
            return;
        }
        keywordDiscoveryV2Cache[activeKeywordSubtab] = null;
        loadKeywordDiscoveryV2(true);
    });

    $(document).on('click', '.aysa-km-state-btn', function() {
        if (activeKeywordSubtab !== 'keyword_mapping_v2') {
            return;
        }
        const projectId = getProjectId();
        if (!projectId) {
            return;
        }
        const button = $(this);
        const clusterId = String(button.data('clusterId') || '').trim();
        const keyword = String(button.data('keyword') || '').trim();
        const selectionState = String(button.data('selectionState') || '').trim();
        if (!selectionState) {
            return;
        }

        $('#aysa-kd-v2-status').text('Saving keyword mapping selection...');
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {
                action: 'aysa_keyword_mapping_v1_save_selection',
                nonce: aysaKeywordCacheNonce,
                project_id: projectId,
                cluster_id: clusterId,
                keyword: keyword,
                selection_state: selectionState
            }
        }).done(function(resp) {
            if (!(resp && resp.success)) {
                const message = resp && resp.data ? resp.data : 'Selection save failed';
                $('#aysa-kd-v2-status').text(message);
                return;
            }
            keywordDiscoveryV2Cache.keyword_mapping_v2 = null;
            loadKeywordDiscoveryV2(true);
        }).fail(function(xhr) {
            let message = 'Selection save failed';
            if (xhr && xhr.responseJSON && xhr.responseJSON.data) {
                message = xhr.responseJSON.data;
            }
            $('#aysa-kd-v2-status').text(message);
        });
    });

    $(document).on('change', '#aysa-km-status-filter', function() {
        keywordMappingStatusFilter = String($(this).val() || 'all').trim() || 'all';
        if (activeKeywordSubtab !== 'keyword_mapping_v2') {
            return;
        }
        renderKeywordDiscoveryV2('keyword_mapping_v2', keywordDiscoveryV2Cache.keyword_mapping_v2 || {});
    });

    function persistKeywordWorkspaceState(subtab) {
        if (!window.ajaxurl) {
            return;
        }
        const body = new URLSearchParams({
            action: 'aysa_workspace_state_save',
            nonce: String(typeof aysaAdminNonce !== 'undefined' ? aysaAdminNonce : ''),
            tab: 'keyword-discovery',
            subtab: String(subtab || '')
        });
        fetch(window.ajaxurl, {
            method: 'POST',
            credentials: 'same-origin',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
            },
            body: body.toString()
        }).catch(function() {});
    }

    try {
        const urlParams = new URLSearchParams(window.location.search || '');
        const requestedKeywordSubtab = String(urlParams.get('kdv2_tab') || '').trim();
        if (!requestedKeywordSubtab) {
            const localSavedKeywordSubtab = String(localStorage.getItem('aysa_keyword_discovery_subtab') || '').trim();
            if (localSavedKeywordSubtab && ['gsc_v2', 'dataforseo_v2', 'competitor_gap_v2', 'keyword_mapping_v2'].includes(localSavedKeywordSubtab)) {
                activeKeywordSubtab = localSavedKeywordSubtab;
            }
        }
    } catch (error) {}

    // Load associations, and then keywords, when page loads
    if (window.AYSA_DEBUG === true) {
        console.log('Calling loadAssociations...');
    }
    const initialProjectId = getProjectId();
    if (initialProjectId) {
        ensureWpCatalogLoaded().catch(() => {});
        loadKeywordStrategy(initialProjectId);
    } else {
        window.aysaGoogleDataDiagnostics = {
            connected: null,
            gscRows: 0,
            ga4Rows: 0,
            selectedGsc: '',
            selectedGa4: '',
            message: 'project id missing'
        };
        renderGoogleDataStatus();
    }
    applyKeywordSubtabUi();
    loadAssociations();
    
    // Function to load all associations
    function loadAssociations() {
        if (window.AYSA_DEBUG === true) {
            console.log('Inside loadAssociations function');
        }
        
        // Get project ID
        const projectId = getProjectId();
        if (window.AYSA_DEBUG === true) {
            console.log('Project ID for associations:', projectId);
        }
        
        // Introducem o mică întârziere pentru a permite afișarea loading-ului inițial
        setTimeout(() => {
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'aysa_keyword_discovery_get_associations',
                    nonce: aysaAdminNonce,
                    project_id: parseInt(projectId),
                    local_only: 1
                },
                success: function(resp) {
                    const associations = (resp && resp.success && resp.data && Array.isArray(resp.data.associations))
                        ? resp.data.associations
                        : [];
                    console.log('Successfully loaded associations:', associations);
                    
                    // Verifică dacă am primit asocieri valide
                    if (Array.isArray(associations) && associations.length > 0) {
                        // Store associations for later use
                        window.aysaAssociations = associations;
                    } else {
                        console.warn('No associations found or invalid response format');
                        window.aysaAssociations = [];
                    }
                    
                    // Store association count for final notification
                    window.aysaAssociationCount = Array.isArray(associations) ? associations.length : 0;
                },
                error: function(xhr, status, error) {
                    console.error('Error loading associations:', {
                        status: status,
                        error: error,
                        response: xhr.responseText,
                        statusText: xhr.statusText
                    });
                    
                    // Inițializăm cu un array gol pentru a evita erorile
                    window.aysaAssociations = [];
                    
                    // Store association count for final notification (0 on error)
                    window.aysaAssociationCount = 0;
                },
                complete: function() {
                    // After associations are loaded (or fail), load the target keywords.
                    // This ensures target keywords are always displayed initially.
                    loadActiveKeywordSubtabData();
                }
            });
        }, 500); // O mică întârziere pentru a permite afișarea stării de loading
    }

    // Intent enrichment functions
    function checkKeywordIntent(keyword) {
        if (!keyword || typeof keyword !== 'object') {
            return false;
        }
        const intent = String(keyword.intent || '').trim().toLowerCase();
        return !!intent && intent !== 'n/a' && intent !== 'unknown' && intent !== 'target';
    }

    function getIntentFallback(keyword) {
        // Use existing determineKeywordIntent function from aysa-actions.js if available
        if (typeof determineKeywordIntent === 'function') {
            return determineKeywordIntent(keyword);
        }
        
        // Local fallback pattern matching (RO + EN) for fast intent assignment.
        const lowerKeyword = keyword.toLowerCase().trim();
        const navigationalPatterns = [
            'site oficial', 'official site', 'contact', 'program', 'adresa',
            'telefon', 'florariebragadiru', 'florarie bragadiru'
        ];
        const transactionalPatterns = [
            'buy', 'purchase', 'order', 'shop', 'price', 'cost', 'deal',
            'cumpara', 'cumpără', 'comanda', 'comandă', 'pret', 'preț',
            'livrare', 'online', 'oferta', 'ofertă', 'reducere', 'ieftin', 'cat costa', 'cât costă'
        ];
        const commercialPatterns = [
            'best', 'top', 'review', 'compare', 'vs', 'versus',
            'pareri', 'păreri', 'recenzie', 'recenzii', 'comparatie', 'compara', 'comparație'
        ];
        const informationalPatterns = [
            'how to', 'what is', 'guide', 'tutorial', 'tips', 'idea',
            'cum', 'ce este', 'ce inseamna', 'ce înseamnă', 'ghid', 'sfaturi', 'idei', 'cand', 'când', 'de ce', 'intretinere', 'îngrijire'
        ];

        for (let pattern of navigationalPatterns) {
            if (lowerKeyword.includes(pattern)) return 'navigational';
        }
        
        for (let pattern of transactionalPatterns) {
            if (lowerKeyword.includes(pattern)) return 'transactional';
        }
        for (let pattern of commercialPatterns) {
            if (lowerKeyword.includes(pattern)) return 'commercial';
        }
        for (let pattern of informationalPatterns) {
            if (lowerKeyword.includes(pattern)) return 'informational';
        }
        
        return 'informational'; // Default
    }

    // Function to normalize diacritics for keyword comparison
    function normalizeKeyword(keyword) {
        return keyword
            .toLowerCase()
            .normalize('NFD') // Decompose accented characters
            .replace(/[\u0300-\u036f]/g, '') // Remove diacritical marks
            .trim();
    }

    function keywordsEqual(a, b) {
        return normalizeKeyword(String(a || '')) === normalizeKeyword(String(b || ''));
    }

    function normalizeIntentToken(intentValue) {
        const value = String(intentValue || '').trim().toLowerCase();
        if (!value || value === 'n/a' || value === 'unknown') {
            return '';
        }
        if (value.includes('transaction')) return 'transactional';
        if (value.includes('commercial')) return 'commercial';
        if (value.includes('inform')) return 'informational';
        if (value.includes('navig')) return 'navigational';
        if (value === 't') return 'transactional';
        if (value === 'c') return 'commercial';
        if (value === 'i') return 'informational';
        if (value === 'n') return 'navigational';
        return value;
    }

    function determineKeywordTodoPlan({ keyword, intent, hasAssociation, hasExistingCandidate }) {
        const normalizedKeyword = String(keyword || '').trim().toLowerCase();
        const normalizedIntent = normalizeIntentToken(intent);

        if (hasAssociation) {
            return {
                action: 'associate_existing',
                label: 'Use existing page',
                className: 'is-associate',
                reason: 'Keyword already has an associated page.'
            };
        }

        if (hasExistingCandidate) {
            return {
                action: 'associate_existing',
                label: 'Match existing page',
                className: 'is-associate',
                reason: 'Found a strong existing URL candidate (GSC/semantic).'
            };
        }

        const informationalPatterns = [
            'cum ', 'ce ', 'cand ', 'de ce', 'ghid', 'sfaturi', 'idei', 'intretinere', 'îngrijire',
            'how ', 'what ', 'when ', 'guide', 'tips', 'idea'
        ];
        const landingPatterns = [
            'livrare', 'delivery', 'near me', 'aproape', 'bragadiru', 'bucuresti', 'sector', 'program', 'contact'
        ];
        const productPatterns = [
            'buchet', 'aranjament', 'trandafiri', 'lalele', 'frezii', 'orhidee', 'bonsai', 'cadou',
            'buc ', ' fire', ' fir', 'x', 'cm'
        ];
        const categoryPatterns = [
            'flori', 'buchete', 'aranjamente', 'plante', 'cadouri', 'fori de', 'de flori',
            'flowers', 'bouquets'
        ];

        const hasDigits = /\d/.test(normalizedKeyword);
        const hasInformationalPattern = informationalPatterns.some(p => normalizedKeyword.includes(p));
        const hasLandingPattern = landingPatterns.some(p => normalizedKeyword.includes(p));
        const hasProductPattern = productPatterns.some(p => normalizedKeyword.includes(p));
        const hasCategoryPattern = categoryPatterns.some(p => normalizedKeyword.includes(p));

        if (normalizedIntent === 'informational' || hasInformationalPattern) {
            return {
                action: 'todo_create_article',
                label: 'To do: create article',
                className: 'is-article',
                reason: 'Informational intent keyword.'
            };
        }

        if ((normalizedIntent === 'transactional' || normalizedIntent === 'commercial') && (hasDigits || hasProductPattern)) {
            return {
                action: 'todo_create_product_page',
                label: 'To do: create product page',
                className: 'is-product',
                reason: 'Specific transactional/commercial product query.'
            };
        }

        if ((normalizedIntent === 'transactional' || normalizedIntent === 'commercial' || normalizedIntent === 'navigational') && hasLandingPattern) {
            return {
                action: 'todo_create_landing_page',
                label: 'To do: create landing page',
                className: 'is-landing',
                reason: 'Local/service intent keyword.'
            };
        }

        if (hasCategoryPattern || normalizedIntent === 'commercial') {
            return {
                action: 'todo_create_category_page',
                label: 'To do: create category page',
                className: 'is-category',
                reason: 'Broad commercial keyword fits a category page.'
            };
        }

        if (normalizedIntent === 'transactional') {
            return {
                action: 'todo_create_landing_page',
                label: 'To do: create landing page',
                className: 'is-landing',
                reason: 'Transactional keyword without strong product match.'
            };
        }

        return {
            action: 'todo_create_article',
            label: 'To do: create article',
            className: 'is-article',
            reason: 'Default informational-safe recommendation.'
        };
    }

    function renderKeywordTodoPlan(plan) {
        if (!plan || !plan.label) {
            return '';
        }
        const safeLabel = escapeHtml(String(plan.label));
        const safeReason = escapeHtml(String(plan.reason || ''));
        const safeAction = escapeAttr(String(plan.action || ''));
        return `<div class="aysa-keyword-todo ${escapeAttr(String(plan.className || ''))}" data-action="${safeAction}" title="${safeReason}">
            <span class="aysa-keyword-todo-label">${safeLabel}</span>
            <span class="aysa-keyword-todo-reason">${safeReason}</span>
        </div>`;
    }

    function getAssociationsForKeyword(keyword) {
        if (!Array.isArray(window.aysaAssociations)) {
            return [];
        }
        return window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, keyword));
    }

    async function enrichKeywordsWithIntent(keywords) {
        const list = Array.isArray(keywords) ? keywords : [];
        if (list.length === 0) {
            return [];
        }

        const projectId = getProjectId();
        const keywordsNeedingIntent = list
            .map(item => String((item && item.keyword) || '').trim())
            .filter(Boolean);

        let remoteIntentMap = {};
        if (projectId && keywordsNeedingIntent.length > 0) {
            try {
                const response = await $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    dataType: 'json',
                    data: {
                        action: 'aysa_keyword_discovery_intent_batch',
                        nonce: aysaAdminNonce,
                        project_id: projectId,
                        keywords: JSON.stringify(keywordsNeedingIntent)
                    }
                });
                if (response && response.success && response.data && typeof response.data.intents === 'object') {
                    remoteIntentMap = response.data.intents || {};
                }
            } catch (error) {
                console.warn('Intent batch endpoint failed, using local fallback:', error);
            }
        }

        return list.map(keyword => {
            const currentIntent = String((keyword && keyword.intent) || '').trim();
            if (checkKeywordIntent(keyword)) {
                return keyword;
            }

            const kwKey = String((keyword && keyword.keyword) || '').trim().toLowerCase();
            const remote = remoteIntentMap && kwKey ? remoteIntentMap[kwKey] : null;
            const resolvedIntent = (remote && remote.intent) ? String(remote.intent).trim() : '';
            const intentProbabilities = (remote && remote.intent_probabilities && typeof remote.intent_probabilities === 'object')
                ? remote.intent_probabilities
                : (keyword.intentProbabilities || null);

            if (resolvedIntent !== '') {
                return {
                    ...keyword,
                    intent: resolvedIntent,
                    intentProbabilities: intentProbabilities
                };
            }

            return {
                ...keyword,
                intent: currentIntent && currentIntent !== 'N/A' ? currentIntent : getIntentFallback(String(keyword && keyword.keyword ? keyword.keyword : ''))
            };
        });
    }

    // Keyword difficulty enrichment function
    async function enrichKeywordsWithDifficulty(keywords) {
        if (aysaHasLocalLegacyApiBase) {
            return keywords;
        }

        const projectId = getProjectId();
        if (!projectId) {
            console.error('Project ID not found for difficulty enrichment');
            return keywords;
        }

        try {
            // Filter keywords that need difficulty data (have 0 or N/A difficulty)
            const keywordsNeedingDifficulty = keywords.filter(keyword => {
                const difficulty = keyword.difficulty;
                // Skip if keyword already has proper difficulty from SuggestedKeywords API
                if (difficulty && difficulty !== 'N/A' && difficulty !== 0 && difficulty !== '0') {
                    // Keyword already has difficulty
                    return false;
                }
                return true;
            });

            console.log(`🎯 Keywords needing difficulty analysis: ${keywordsNeedingDifficulty.length}/${keywords.length}`);

            if (keywordsNeedingDifficulty.length > 0) {
                // Use keyword research API to get difficulty data
                const keywordsList = keywordsNeedingDifficulty.map(k => k.keyword);
                
                // Call keyword metrics API for keyword difficulty
                const difficultyUrl = `${getApiBaseUrl()}/api/DataForSeo/keywords-research-and-analysis`;
                const queryParams = new URLSearchParams({
                    keywords: keywordsList.join(','),
                    locationName: 'Romania',
                    languageName: 'Romanian',
                    projectId: projectId.toString(),
                    limit: keywordsList.length.toString()
                });
                
                try {
                    console.log('🔍 Calling difficulty API:', `${difficultyUrl}?${queryParams}`);
                    
                    const difficultyResponse = await fetch(`${difficultyUrl}?${queryParams}`, {
                        method: 'GET',
                        headers: {
                            'Accept': 'application/json',
                            'Origin': window.location.origin
                        },
                        mode: 'cors'
                    });
                    
                    if (difficultyResponse.ok) {
                        const difficultyResults = await difficultyResponse.json();
                        console.log('🎨 Difficulty enrichment API successful:', difficultyResults);
                        
                        // Apply difficulty data to keywords
                        const enrichedKeywords = keywords.map(keyword => {
                            // Find matching difficulty data
                            const difficultyData = difficultyResults.find(result => 
                                result.keyword && result.keyword.toLowerCase() === keyword.keyword.toLowerCase()
                            );
                            
                            if (difficultyData) {
                                return {
                                    ...keyword,
                                    difficulty: difficultyData.keyword_difficulty || difficultyData.difficulty || 50,
                                    searchVolume: (difficultyData.search_volume !== undefined && difficultyData.search_volume !== null && difficultyData.search_volume !== '')
                                        ? difficultyData.search_volume
                                        : ((difficultyData.searchVolume !== undefined && difficultyData.searchVolume !== null && difficultyData.searchVolume !== '')
                                            ? difficultyData.searchVolume
                                            : keyword.searchVolume),
                                    competition: difficultyData.competition_level || difficultyData.competition || keyword.competition
                                };
                            }
                            
                            return keyword;
                        });
                        
                        console.log('🎨 Difficulty enrichment completed');
                        return enrichedKeywords;
                        
                    } else {
                        console.warn('Difficulty enrichment API failed:', difficultyResponse.status);
                        return keywords;
                    }
                } catch (apiError) {
                    console.error('Difficulty enrichment API error:', apiError);
                    return keywords;
                }
            }

            return keywords;

        } catch (error) {
            console.error('❌ Error during difficulty enrichment:', error);
            return keywords;
        }
    }

    // Force batch intent analysis for all keywords currently in frontend
    async function forceBatchIntentAnalysis() {
        console.log('🔥 Starting forceBatchIntentAnalysis...');
        
        // Wait a bit more to ensure all async operations are complete
        await new Promise(resolve => setTimeout(resolve, 500));
        
        // Collect ALL keywords from both window.aysaKeywords AND associations
        const baseKeywords = window.aysaKeywords || [];
        const associationKeywords = [];
        const includeAssociationKeywords = activeKeywordSubtab !== 'keyword_suggestions';
        
        // Extract keywords from associations (both main and secondary)
        if (includeAssociationKeywords && window.aysaAssociations && window.aysaAssociations.length > 0) {
            console.log('🔥 Found associations, extracting keywords...');
            
            // Create a map of existing keywords for faster lookup
            const existingKeywordsMap = new Map();
            baseKeywords.forEach(k => existingKeywordsMap.set(k.keyword.toLowerCase(), k));
            
                    window.aysaAssociations.forEach(association => {
                const keywordLower = association.keyword.toLowerCase();
                
                // Only add if not already in baseKeywords
                if (!existingKeywordsMap.has(keywordLower)) {
                    const currentIntent = association.intent || 'Unknown';
                    console.log(`🔥 Adding association keyword "${association.keyword}" with intent: "${currentIntent}"`);
                    
                    associationKeywords.push({
                        keyword: association.keyword,
                        searchVolume: 'N/A',
                        difficulty: 'N/A',
                        intent: currentIntent, // Use existing intent from association or 'Unknown'
                        competition: 'N/A',
                        id: association.id,
                        isFromAssociation: true, // Flag to identify association keywords
                        associationData: association,
                        intentProbability: association.intentProbability // Preserve probability if available
                    });
                }
            });
            
            console.log('🔥 Found', associationKeywords.length, 'unique keywords from associations');
        } else if (!includeAssociationKeywords) {
            console.log('🔥 Keyword Suggestions tab: skipping association keyword injection for intent analysis');
        }
        
        // Combine all keywords
        const allKeywords = [...baseKeywords, ...associationKeywords];
        console.log('🔥 Total keywords to analyze:', allKeywords.length, '(base:', baseKeywords.length, '+ associations:', associationKeywords.length, ')');
        
        if (allKeywords.length === 0) {
            console.log('🔥 No keywords to analyze for intent');
            return;
        }

        // Debug: Log all current intent values
        console.log('🔥 Current intent status of all keywords:');
        allKeywords.forEach((keyword, index) => {
            console.log(`${index + 1}. "${keyword.keyword}" -> intent: "${keyword.intent}"`);
        });

        // Filter keywords that need intent (N/A, Target, missing, or undefined)
        const keywordsNeedingIntent = allKeywords.filter(keyword => {
            const hasProperIntent = keyword.intent && 
                                  keyword.intent !== 'N/A' && 
                                  keyword.intent !== 'Target' &&
                                  keyword.intent !== 'Unknown' &&
                                  keyword.intent !== '' &&
                                  keyword.intent !== null &&
                                  keyword.intent !== undefined;
            
            const needsIntent = !hasProperIntent;
            
            if (needsIntent) {
                console.log(`🔥 Keyword needs intent: "${keyword.keyword}" (current: "${keyword.intent}")`);
            } else {
                console.log(`✅ Keyword has proper intent: "${keyword.keyword}" (current: "${keyword.intent}")`);
            }
            
            return needsIntent;
        });

        console.log(`🔥 Keywords needing intent: ${keywordsNeedingIntent.length}/${allKeywords.length}`);

        // Always show what we found, even if no keywords need intent
        if (keywordsNeedingIntent.length > 0) {
            console.log('🔥 Keywords that need intent analysis:', keywordsNeedingIntent.map(k => `"${k.keyword}" (${k.intent})`));
            
            // Show loading notification
            showNotification(`Analyzing intent for ${keywordsNeedingIntent.length} keywords...`, 'loading');
            
            // ✅ Show loading indicators in the Intent column
            showIntentLoadingInTable();

            try {
                console.log('🔥 Calling enrichKeywordsWithIntent for all keywords...');
                
                // Clear any existing loading notifications before starting
                clearLoadingNotifications();
                
                // Enrich with intent - pass ALL keywords so the function can work properly
                const enrichedKeywords = await enrichKeywordsWithIntent(allKeywords);
                
                console.log('🔥 Intent enrichment completed, updating data structures...');
                
                // Split the enriched keywords back into base keywords and association keywords
                const updatedBaseKeywords = [];
                const updatedAssociationKeywords = [];
                
                enrichedKeywords.forEach(keyword => {
                    if (keyword.isFromAssociation) {
                        updatedAssociationKeywords.push(keyword);
                    } else {
                        updatedBaseKeywords.push(keyword);
                    }
                });
                
                // Update window.aysaKeywords with the base keywords
                window.aysaKeywords = updatedBaseKeywords;
                
                // Update window.aysaAssociations with the new intent data
                if (updatedAssociationKeywords.length > 0 && window.aysaAssociations) {
                    console.log('🔥 Updating', updatedAssociationKeywords.length, 'association keywords with new intent data');
                    
                    // Create a map of updated intents for faster lookup
                    const intentMap = new Map();
                    updatedAssociationKeywords.forEach(keyword => {
                        intentMap.set(keyword.keyword.toLowerCase(), {
                            intent: keyword.intent,
                            intentProbability: keyword.intentProbability
                        });
                    });
                    
                    // Update the associations with new intent data
                    window.aysaAssociations = window.aysaAssociations.map(association => {
                        const intentData = intentMap.get(association.keyword.toLowerCase());
                        if (intentData) {
                            console.log(`🔥 Updated association "${association.keyword}": ${association.intent || 'Unknown'} -> ${intentData.intent}`);
                            return {
                                ...association,
                                intent: intentData.intent,
                                intentProbability: intentData.intentProbability
                            };
                        } else {
                            console.log(`🔥 No intent update for association "${association.keyword}" (current: ${association.intent || 'Unknown'})`);
                        }
                        return association;
                    });
                }
                
                // Refresh display with updated data
                console.log('🔥 Refreshing display...');
                displayKeywordResults(window.aysaKeywords);
                
                // ✅ Hide loading indicators after display refresh
                hideIntentLoadingInTable();
                
                // Count how many actually got updated
                const stillNeedingIntent = enrichedKeywords.filter(keyword => {
                    return !keyword.intent || 
                           keyword.intent === 'N/A' || 
                           keyword.intent === 'Target' ||
                           keyword.intent === 'Unknown' ||
                           keyword.intent === '' ||
                           keyword.intent === null ||
                           keyword.intent === undefined;
                });
                
                if (stillNeedingIntent.length > 0) {
                    console.warn(`🔥 ${stillNeedingIntent.length} keywords still need intent after analysis:`, 
                                stillNeedingIntent.map(k => `"${k.keyword}" (${k.intent})`));
                    showNotification(`Intent analysis completed. ${stillNeedingIntent.length} keywords still need manual review.`, 'warning');
                } else {
                    showNotification(`Intent analysis completed successfully for all ${keywordsNeedingIntent.length} keywords`, 'success');
                }
                
            } catch (error) {
                console.error('🔥 Batch intent analysis failed:', error);
                // ✅ Hide loading indicators on error
                hideIntentLoadingInTable();
                showNotification('Intent analysis failed', 'error');
            }
        } else {
            console.log('🔥 All keywords already have proper intent - no analysis needed');
            
            // Double-check by looking at the actual displayed table
            const displayedKeywords = [];
            $('.aysa-keywords-table tbody tr:not(.aysa-loading-row)').each(function() {
                const keywordText = $(this).find('td:eq(0)').text().trim();
                const intentCell = $(this).find('td.aysa-intent-col').first();
                if (!intentCell.length) {
                    // Skip detail/helper rows that do not represent actual keyword records.
                    return;
                }
                const hasIndicator = intentCell.find('.aysa-indicator').length > 0;
                const intentText = intentCell.text().trim();
                
                if (keywordText && !hasIndicator && (!intentText || intentText === 'N/A' || intentText === 'Unknown')) {
                    displayedKeywords.push({keyword: keywordText, displayedIntent: intentText});
                }
            });
            
            if (displayedKeywords.length > 0) {
                console.warn('🔥 MISMATCH DETECTED: Found keywords in display that lack intent:', displayedKeywords);
                showNotification(`Found ${displayedKeywords.length} keywords in display that still need intent analysis.`, 'warning');
            } else {
                showNotification('All keywords have proper intent data', 'success');
            }
        }
    }

    /**
     * Show loading indicators in the Intent column for specific keywords
     */
    function showIntentLoadingInTable() {
        // Showing intent loading indicators
        
        const $tbody = $('.aysa-keywords-table tbody');
        if (!$tbody.length) {
            console.error('🎯 Table tbody not found!');
            return;
        }
        
        // Find all Intent cells (2nd column, index 1) and add loading spinner
        const $rows = $tbody.find('tr:not(.aysa-loading-row)');
        // Processing table rows
        
        let loadingCount = 0;
        $rows.each(function(index) {
            const $intentCell = $(this).find('td.aysa-intent-col');
            
            if ($intentCell.length) {
                const currentContent = $intentCell.html();
                
                // Only show loading if the cell doesn't already have proper intent indicators
                // or if it's empty/showing Unknown
                if (!currentContent || 
                    currentContent.includes('aysa-unknown') || 
                    currentContent.trim() === '' ||
                    currentContent.includes('N/A')) {
                    
                    $intentCell.addClass('aysa-loading-intent').html(`
                        <div class="aysa-intent-loading">
                            <span class="aysa-spinner"></span>
                        </div>
                    `);
                    loadingCount++;
                }
            }
        });
        
        // Applied loading indicators to intent cells
        
        // Add CSS styles if not already present
        if (!document.getElementById('aysa-intent-loading-styles-kd')) {
            const style = document.createElement('style');
            style.id = 'aysa-intent-loading-styles-kd';
            style.textContent = `
                .aysa-intent-loading {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    height: 24px;
                }
                .aysa-spinner {
                    width: 16px;
                    height: 16px;
                    border: 2px solid #f3f3f3;
                    border-top: 2px solid #1976d2;
                    border-radius: 50%;
                    animation: aysa-spin 1s linear infinite;
                }
                @keyframes aysa-spin {
                    0% { transform: rotate(0deg); }
                    100% { transform: rotate(360deg); }
                }
                .aysa-loading-intent {
                    background-color: #f8f9fa;
                    text-align: center;
                }
            `;
            document.head.appendChild(style);
        }
    }

    /**
     * Hide loading indicators in the Intent column
     */
    function hideIntentLoadingInTable() {
        // Hiding intent loading indicators
        
        const $tbody = $('.aysa-keywords-table tbody');
        if (!$tbody.length) return;
        
        // Remove loading indicators from all intent cells
        const $loadingCells = $tbody.find('.aysa-loading-intent');
        $loadingCells.removeClass('aysa-loading-intent');
        // Removed loading indicators
        // The content will be updated by the display function
    }

    function getUnlinkedKeywordsForAutoAssociation() {
        const keywords = Array.isArray(window.aysaKeywords) ? window.aysaKeywords : [];
        const associations = Array.isArray(window.aysaAssociations) ? window.aysaAssociations : [];
        const associatedSet = new Set(
            associations
                .map(a => normalizeKeyword(String((a && a.keyword) || '')))
                .filter(Boolean)
        );
        const out = [];
        const seen = new Set();
        keywords.forEach(item => {
            const value = String((item && item.keyword) || '').trim();
            if (!value) {
                return;
            }
            const key = normalizeKeyword(value);
            if (!key || seen.has(key) || associatedSet.has(key)) {
                return;
            }
            seen.add(key);
            out.push(value);
        });
        return out;
    }

    function buildAutoAssociationRunKey(projectId, keywords) {
        const sorted = (keywords || []).map(k => normalizeKeyword(k)).filter(Boolean).sort();
        return `${String(projectId || '')}|${sorted.join('|')}`;
    }

    function runAutomaticAssociations(options = {}) {
        const opts = Object.assign({ manual: false, force: false }, options || {});
        const projectId = getProjectId();
        if (!projectId) {
            return $.Deferred().resolve(null).promise();
        }

        const keywords = getUnlinkedKeywordsForAutoAssociation();
        if (keywords.length === 0) {
            if (opts.manual) {
                showNotification('Nu exista keyword-uri neasociate.', 'info');
            }
            return $.Deferred().resolve(null).promise();
        }

        const state = window.aysaAutoAssociationState || { inProgress: false, lastRunKey: '', lastRunAt: 0 };
        const runKey = buildAutoAssociationRunKey(projectId, keywords);
        if (state.inProgress) {
            return $.Deferred().resolve(null).promise();
        }
        if (!opts.force && !opts.manual && state.pageAutoRunDone) {
            return $.Deferred().resolve(null).promise();
        }
        if (!opts.force && !opts.manual && state.lastRunKey === runKey) {
            return $.Deferred().resolve(null).promise();
        }

        state.inProgress = true;
        if (!opts.manual) {
            state.pageAutoRunDone = true;
        }
        window.aysaAutoAssociationState = state;

        const $btn = $('.aysa-reassociate-btn');
        const originalBtnHtml = $btn.html();
        $btn.prop('disabled', true).addClass('aysa-processing');
        $btn.html('<span class="dashicons dashicons-update aysa-spinning"></span> Auto associating...');

        if (!opts.manual) {
            showNotification(`Auto-association started (${keywords.length} unlinked keywords)...`, 'info');
        }

        return generateKeywordAssociations(keywords, { suppressReload: !opts.manual })
            .catch(() => null)
            .finally(() => {
                state.inProgress = false;
                state.lastRunKey = runKey;
                state.lastRunAt = Date.now();
                window.aysaAutoAssociationState = state;
                $btn.prop('disabled', false).removeClass('aysa-processing');
                $btn.html(originalBtnHtml || 'Reassociate Unlinked');
            });
    }

    function resolveWpItemByUrl(rawUrl) {
        const normalizedUrl = normalizeUrlForMatching(rawUrl);
        const normalizedPath = normalizePathForMatching(rawUrl);
        if (!normalizedUrl && !normalizedPath) {
            return null;
        }

        const catalog = window.aysaWpItemsCatalog || {};
        const buckets = ['Category', 'Page', 'Product'];
        let pathFallback = null;

        for (let i = 0; i < buckets.length; i += 1) {
            const type = buckets[i];
            const items = Array.isArray(catalog[type]) ? catalog[type] : [];
            for (let j = 0; j < items.length; j += 1) {
                const item = items[j];
                const itemUrl = String((item && item.url) || '').trim();
                if (!itemUrl) {
                    continue;
                }

                const itemNormalizedUrl = normalizeUrlForMatching(itemUrl);
                if (normalizedUrl && itemNormalizedUrl && normalizedUrl === itemNormalizedUrl) {
                    return {
                        type: type,
                        id: item.id,
                        name: item.name || itemUrl,
                        url: item.url || ''
                    };
                }

                const itemPath = normalizePathForMatching(itemUrl);
                if (!pathFallback && normalizedPath && itemPath && normalizedPath === itemPath) {
                    pathFallback = {
                        type: type,
                        id: item.id,
                        name: item.name || itemUrl,
                        url: item.url || ''
                    };
                }
            }
        }

        return pathFallback;
    }

    function getMatchedPageCandidateForKeyword(keywordOrRow) {
        const row = (keywordOrRow && typeof keywordOrRow === 'object') ? keywordOrRow : null;
        const kw = String((row && row.keyword) || keywordOrRow || '').trim();
        if (!kw) return null;

        // Priority 1: matched URL from GSC.
        const candidateKeys = Array.from(new Set([
            String(kw || '').toLowerCase().trim(),
            normalizeKeyword(String(kw || ''))
        ].filter(Boolean)));
        const gscHintsMap = window.aysaGoogleKeywordUrlHints || {};
        let gscHint = null;
        for (let i = 0; i < candidateKeys.length; i += 1) {
            if (gscHintsMap[candidateKeys[i]]) {
                gscHint = gscHintsMap[candidateKeys[i]];
                break;
            }
        }
        if (!gscHint) {
            const allHintKeys = Object.keys(gscHintsMap);
            for (let i = 0; i < allHintKeys.length; i += 1) {
                const mapKey = allHintKeys[i];
                if (candidateKeys.includes(normalizeKeyword(mapKey))) {
                    gscHint = gscHintsMap[mapKey];
                    break;
                }
            }
        }
        if (gscHint) {
            if (gscHint.item && gscHint.item.id) {
                return {
                    source: 'gsc',
                    item: gscHint.item
                };
            }
            const gscUrl = String((gscHint && gscHint.url) || '').trim();
            if (gscUrl) {
                const gscItemByUrl = resolveWpItemByUrl(gscUrl);
                if (gscItemByUrl && gscItemByUrl.id) {
                    return {
                        source: 'gsc-url',
                        item: gscItemByUrl
                    };
                }
            }
        }

        // Fallback: unresolved GSC URL for this keyword.
        const unresolvedMap = window.aysaGoogleKeywordUnresolvedHints || {};
        let unresolvedHint = null;
        for (let i = 0; i < candidateKeys.length; i += 1) {
            if (unresolvedMap[candidateKeys[i]]) {
                unresolvedHint = unresolvedMap[candidateKeys[i]];
                break;
            }
        }
        if (!unresolvedHint) {
            const allUnresolvedKeys = Object.keys(unresolvedMap);
            for (let i = 0; i < allUnresolvedKeys.length; i += 1) {
                const mapKey = allUnresolvedKeys[i];
                if (candidateKeys.includes(normalizeKeyword(mapKey))) {
                    unresolvedHint = unresolvedMap[mapKey];
                    break;
                }
            }
        }
        if (unresolvedHint && unresolvedHint.url) {
            const unresolvedItem = resolveWpItemByUrl(unresolvedHint.url);
            if (unresolvedItem && unresolvedItem.id) {
                return {
                    source: 'gsc-url-unresolved',
                    item: unresolvedItem
                };
            }
        }

        // Fallback 2: explicit matched URL already present in local row.
        const directUrl = String((row && (row.targetUrl || row.url || row.matchedUrl)) || '').trim();
        if (directUrl && directUrl !== 'N/A') {
            const directItem = resolveWpItemByUrl(directUrl);
            if (directItem && directItem.id) {
                return {
                    source: 'direct-url',
                    item: directItem
                };
            }
        }

        const compositeRecommendation = getCompositeRecommendation(row || kw);
        if (compositeRecommendation && compositeRecommendation.item && Number(compositeRecommendation.score || 0) >= 0.60) {
            return compositeRecommendation;
        }

        return null;
    }

    async function autoAssociateKeywordsWithMatchedPage(projectId) {
        if (!projectId) return { associated: 0, scanned: 0 };
        await ensureWpCatalogLoaded();

        const keywords = Array.isArray(window.aysaKeywords) ? window.aysaKeywords : [];
        const associations = Array.isArray(window.aysaAssociations) ? window.aysaAssociations : [];
        const associatedSet = new Set(
            associations
                .map(a => normalizeKeyword(String((a && a.keyword) || '')))
                .filter(Boolean)
        );

        const state = window.aysaMatchedPageAutoState || { inProgress: false, attempted: {} };
        if (state.inProgress) {
            return { associated: 0, scanned: 0 };
        }
        state.inProgress = true;
        window.aysaMatchedPageAutoState = state;

        let associated = 0;
        let scanned = 0;
        let changed = false;
        let noMatchedUrl = 0;
        let failedUpserts = 0;

        try {
            for (let i = 0; i < keywords.length; i += 1) {
                const kw = String((keywords[i] && keywords[i].keyword) || '').trim();
                if (!kw) continue;
                const norm = normalizeKeyword(kw);
                if (!norm) continue;
                if (associatedSet.has(norm)) continue;
                scanned += 1;

                const alreadyAttempted = !!state.attempted[norm];
                if (alreadyAttempted) continue;

                let candidate = getMatchedPageCandidateForKeyword(keywords[i] || kw);
                if ((!candidate || !candidate.item) && keywords[i] && keywords[i].isTargetKeyword) {
                    // Seed keywords: allow semantic fallback when no direct matched URL exists.
                    const semanticRecommendation = getSemanticRecommendation(kw);
                    const semanticScore = semanticRecommendation ? Number(semanticRecommendation.score || 0) : 0;
                    if (semanticRecommendation && semanticRecommendation.item && semanticScore >= 0.62) {
                        candidate = {
                            source: 'semantic-seed',
                            item: semanticRecommendation.item
                        };
                    }
                }
                if (!candidate || !candidate.item) {
                    noMatchedUrl += 1;
                    continue;
                }
                if (candidate.source === 'composite' && Number(candidate.score || 0) < 0.78) {
                    noMatchedUrl += 1;
                    continue;
                }

                try {
                    const apiResponse = await upsertAssociation(projectId, kw, candidate.item);
                    if (!Array.isArray(window.aysaAssociations)) {
                        window.aysaAssociations = [];
                    }
                    window.aysaAssociations.push({
                        keyword: kw,
                        associatedOn: candidate.item.type,
                        idIntern: candidate.item.id,
                        value: candidate.item.name,
                        id: apiResponse && apiResponse.id ? apiResponse.id : Date.now() + i
                    });
                    associatedSet.add(norm);
                    associated += 1;
                    changed = true;
                    state.attempted[norm] = true;
                } catch (e) {
                    // keep retry available on next run if this attempt failed
                    failedUpserts += 1;
                }
            }
        } finally {
            state.inProgress = false;
            window.aysaMatchedPageAutoState = state;
        }

        if (changed) {
            loadAssociations();
            showNotification(`Auto-associated ${associated} keywords with detected matched page.`, 'success');
        } else if (scanned > 0) {
            showNotification(`Auto-association: 0 updated (${noMatchedUrl} without matched URL, ${failedUpserts} failed saves).`, 'info');
        }
        return { associated, scanned };
    }

    async function runUnlinkedKeywordTriage() {
        const projectId = getProjectId();
        if (!projectId) {
            showNotification('Project ID is missing. Cannot run triage.', 'error');
            return null;
        }

        const keywords = getUnlinkedKeywordsForAutoAssociation();
        if (keywords.length === 0) {
            showNotification('Nu exista keyword-uri neasociate pentru triage.', 'info');
            return null;
        }

        const $triageBtn = $('.aysa-triage-unlinked-btn');
        const $reassociateBtn = $('.aysa-reassociate-btn');
        const originalBtnHtml = $triageBtn.html();

        $triageBtn.prop('disabled', true).addClass('aysa-processing');
        $triageBtn.html('<span class="dashicons dashicons-update aysa-spinning"></span> Triage in progress...');
        $reassociateBtn.prop('disabled', true);
        showNotification(`Triage started (${keywords.length} unlinked keywords)...`, 'loading');

        try {
            await loadGoogleKeywordRecommendations(projectId, { forceRefresh: true });
            await ensureWpCatalogLoaded();

            let cachedProjectTasks = null;
            try {
            const tasksResp = await fetch(`${getApiBaseUrl()}/api/ResearchTasks/ByProject/${projectId}`);
                if (tasksResp.ok) {
                    const tasksData = await tasksResp.json().catch(() => []);
                    cachedProjectTasks = Array.isArray(tasksData) ? tasksData : [];
                }
            } catch (e) {
                cachedProjectTasks = [];
            }

            const confidenceMap = window.aysaKeywordConfidenceMap || {};
            const stats = {
                associated: 0,
                gsc: 0,
                ga4: 0,
                semantic: 0,
                redirectTasks: 0,
                createPageTasks: 0,
                excluded: 0,
                failed: 0
            };
            const maxTasksPerRun = 35;
            let tasksCreatedThisRun = 0;

            for (let i = 0; i < keywords.length; i += 1) {
                const keyword = String(keywords[i] || '').trim();
                if (!keyword) {
                    continue;
                }

                const alreadyAssociated = (window.aysaAssociations || []).some(a =>
                    normalizeKeyword(String(a.keyword || '')) === normalizeKeyword(keyword)
                );
                if (alreadyAssociated) {
                    continue;
                }

                const googleRecommendation = getBestGoogleRecommendation(keyword);
                const unresolvedHint = getGoogleUnresolvedHint(keyword);
                const semanticRecommendation = getSemanticRecommendation(keyword);
                const semanticScore = semanticRecommendation ? Number(semanticRecommendation.score || 0) : 0;

                let chosen = null;
                let chosenSource = 'none';

                const hasStrongGoogleSignal = googleRecommendation && googleRecommendation.item && (
                    (googleRecommendation.source === 'gsc' && (googleRecommendation.confidence === 'High' || googleRecommendation.confidence === 'Medium')) ||
                    (googleRecommendation.source === 'ga4' && googleRecommendation.confidence === 'High')
                );
                if (hasStrongGoogleSignal) {
                    chosen = googleRecommendation;
                    chosenSource = googleRecommendation.source;
                } else if (semanticRecommendation && semanticRecommendation.item && semanticScore >= 0.20) {
                    chosen = {
                        ...semanticRecommendation,
                        source: 'semantic',
                        confidence: semanticRecommendation.confidence || 'Low'
                    };
                    chosenSource = 'semantic';
                }

                confidenceMap[String(keyword).toLowerCase()] = {
                    confidence: chosen ? chosen.confidence : (semanticRecommendation ? semanticRecommendation.confidence : 'Low'),
                    source: chosen ? chosenSource : (unresolvedHint ? 'gsc_unresolved' : 'none'),
                    score: chosen ? Number(chosen.score || 0) : semanticScore
                };

                if (chosen && chosen.item) {
                    try {
                        const apiResponse = await upsertAssociation(projectId, keyword, chosen.item);
                        if (!Array.isArray(window.aysaAssociations)) {
                            window.aysaAssociations = [];
                        }
                        window.aysaAssociations.push({
                            keyword: keyword,
                            associatedOn: chosen.item.type,
                            idIntern: chosen.item.id,
                            value: chosen.item.name,
                            id: apiResponse && apiResponse.id ? apiResponse.id : Date.now() + i
                        });

                        const propagation = await propagateAssociationToSemanticCluster(projectId, keyword, chosen.item);
                        stats.associated += 1 + Number((propagation && propagation.created) || 0);
                        if (chosenSource === 'gsc') {
                            stats.gsc += 1;
                        } else if (chosenSource === 'ga4') {
                            stats.ga4 += 1;
                        } else {
                            stats.semantic += 1;
                        }
                        continue;
                    } catch (e) {
                        stats.failed += 1;
                        continue;
                    }
                }

                if (unresolvedHint && unresolvedHint.url) {
                    if (tasksCreatedThisRun < maxTasksPerRun) {
                        const reason = unresolvedHint.reason || 'gsc_url_unresolved';
                        const taskOk = await ensureRedirectRepairTask(projectId, keyword, unresolvedHint.url, reason, cachedProjectTasks);
                        if (taskOk) {
                            stats.redirectTasks += 1;
                            tasksCreatedThisRun += 1;
                            if (Array.isArray(cachedProjectTasks)) {
                                cachedProjectTasks.push({
                                    title: `Review GSC URL for keyword: ${keyword}`,
                                    status: 'in_progress'
                                });
                            }
                            continue;
                        }
                    }
                    stats.failed += 1;
                    continue;
                }

                if (isSyntheticTestKeyword(keyword)) {
                    stats.excluded += 1;
                    continue;
                }

                if (tasksCreatedThisRun < maxTasksPerRun) {
                    const taskReason = semanticRecommendation
                        ? `semantic score too low (${Math.round(semanticScore * 100)}%)`
                        : 'no viable Google/semantic candidate';
                    const taskOk = await ensureCreatePageTask(projectId, keyword, taskReason, cachedProjectTasks);
                    if (taskOk) {
                        stats.createPageTasks += 1;
                        tasksCreatedThisRun += 1;
                        if (Array.isArray(cachedProjectTasks)) {
                            cachedProjectTasks.push({
                                title: `Create page for keyword: ${keyword}`,
                                status: 'in_progress'
                            });
                        }
                    } else {
                        stats.failed += 1;
                    }
                }
            }

            window.aysaKeywordConfidenceMap = confidenceMap;
            clearLoadingNotifications();
            showNotification(
                `Triage done. Associated: ${stats.associated} (GSC ${stats.gsc}, GA4 ${stats.ga4}, Semantic ${stats.semantic}) | URL repair tasks: ${stats.redirectTasks} | Create-page tasks: ${stats.createPageTasks} | Excluded: ${stats.excluded} | Failed: ${stats.failed}`,
                stats.failed > 0 ? 'warning' : 'success'
            );
            loadAssociations();
            return stats;
        } catch (error) {
            clearLoadingNotifications();
            console.error('Triage failed:', error);
            showNotification(`Triage failed: ${error.message}`, 'error');
            return null;
        } finally {
            $triageBtn.prop('disabled', false).removeClass('aysa-processing').html(originalBtnHtml || 'Triage Unlinked');
            $reassociateBtn.prop('disabled', false);
        }
    }

    function startLocalKeywordRefreshAndWait(projectId, options = {}) {
        const dfd = $.Deferred();
        const refreshKind = String(options.refreshKind || (activeKeywordSubtab === 'keyword_suggestions' ? 'keyword_suggestions' : 'gsc_auto')).trim();
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'aysa_keyword_discovery_refresh_start_background',
                nonce: aysaAdminNonce,
                project_id: projectId,
                refresh_kind: refreshKind
            },
            success: function(resp) {
                if (!resp || !resp.success) {
                    dfd.reject(new Error((resp && resp.data) ? String(resp.data) : 'Failed to start refresh'));
                    return;
                }
                const poll = function() {
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'aysa_keyword_discovery_refresh_status',
                            nonce: aysaAdminNonce,
                            project_id: projectId
                        },
                        success: function(statusResp) {
                            if (!statusResp || !statusResp.success || !statusResp.data) {
                                dfd.reject(new Error('Invalid refresh status response'));
                                return;
                            }
                            const status = statusResp.data;
                            if (status.status === 'running') {
                                setTimeout(poll, 2000);
                                return;
                            }
                            if (status.status === 'completed') {
                                dfd.resolve(status);
                                return;
                            }
                            dfd.reject(new Error(status.last_error || ('Refresh ' + status.status)));
                        },
                        error: function(xhr) {
                            dfd.reject(new Error(xhr && xhr.responseText ? xhr.responseText : 'Refresh status failed'));
                        }
                    });
                };
                setTimeout(poll, 1200);
            },
            error: function(xhr) {
                dfd.reject(new Error(xhr && xhr.responseText ? xhr.responseText : 'Failed to start refresh'));
            }
        });
        return dfd.promise();
    }

    // Load and display keyword suggestions from local database.
    function loadKeywordsFromApi(forceRefresh = false, options = {}) {
        const opts = Object.assign({
            silent: false,
            noLoadingState: false,
            localOnly: false,
            // Keep passive page loads local-only; run intent enrichment only on explicit actions.
            skipIntentRefresh: true,
            sourceMode: getActiveSourceMode(),
            includeGoogle: false
        }, options || {});
        const $tbody = $('.aysa-keywords-table tbody');
        if (!opts.noLoadingState) {
            $tbody.html(`
                <tr class="aysa-loading-row">
                    <td colspan="12" class="aysa-loading-cell">
                        <div class="aysa-loading-container">
                            <span class="dashicons dashicons-update aysa-spinning"></span>
                            <span class="aysa-loading-text">${forceRefresh ? 'Refreshing keywords in background...' : 'Loading local keywords...'}</span>
                        </div>
                    </td>
                </tr>
            `);
        }

        const projectId = getProjectId();
        if (!projectId) {
            console.error("Project ID is missing.");
            $tbody.html('<tr><td colspan="12" class="aysa-empty-message">Project ID not found. Please set it up in plugin settings.</td></tr>');
            if (!opts.silent) {
                showNotification("Project ID is missing. Please set it up in the plugin settings.", 'error');
            }
            return $.Deferred().resolve().promise();
        }

        if (forceRefresh) {
            return startLocalKeywordRefreshAndWait(projectId).then(function() {
                return loadKeywordsFromApi(false, opts);
            }).catch(function(error) {
                if (!opts.silent) {
                    showNotification(`Refresh failed: ${error.message || error}`, 'error');
                }
                return $.Deferred().resolve().promise();
            });
        }

        return $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'aysa_keyword_discovery_local_keywords',
                nonce: aysaKeywordCacheNonce,
                project_id: projectId,
                source_mode: opts.sourceMode
            },
            success: async function(response) {
                const expectedSourceMode = getActiveSourceMode();
                if (opts.sourceMode !== expectedSourceMode) {
                    console.log(`Ignoring stale keyword response for source_mode="${opts.sourceMode}" (active="${expectedSourceMode}")`);
                    return;
                }
                if (!response || !response.success || !response.data || !Array.isArray(response.data.keywords)) {
                    console.error('Invalid local keywords response format:', response);
                    showNotification('Failed to load local keywords', 'error');
                    return;
                }
                updateFooterManualRefresh(response.data.status || null);
                const keywords = response.data.keywords;
                console.log('Successfully loaded keywords from local DB:', keywords);
                console.log('🔍 Sample keyword data:', keywords[0]);
                
                const keywordCount = Array.isArray(keywords) ? keywords.length : 0;
                const associationCount = window.aysaAssociationCount || 0;
                
                if (Array.isArray(keywords)) {
                    // Keep datasets isolated by subtab to avoid cross-tab contamination.
                    const isKeywordSuggestionsTab = opts.sourceMode === 'keyword_suggestions' || activeKeywordSubtab === 'keyword_suggestions';
                    const isGscAutoTab = opts.sourceMode === 'gsc_auto' || activeKeywordSubtab === 'gsc_auto_discovery';
                    const existingKeywords = (isKeywordSuggestionsTab || isGscAutoTab) ? [] : (window.aysaKeywords || []);
                    let mergedKeywords = [...existingKeywords];
                    const semanticVariants = {};

                    const addSemanticVariant = (mainKeyword, variantKeyword, source, row = null) => {
                        const mainKey = String(mainKeyword || '').trim().toLowerCase();
                        const variant = String(variantKeyword || '').trim();
                        if (!mainKey || !variant) {
                            return;
                        }
                        if (!Array.isArray(semanticVariants[mainKey])) {
                            semanticVariants[mainKey] = [];
                        }
                        const already = semanticVariants[mainKey].some(v =>
                            normalizeKeyword(String(v.keyword || '')) === normalizeKeyword(variant)
                        );
                        if (already) {
                            return;
                        }
                        semanticVariants[mainKey].push({
                            keyword: variant,
                            source: source || 'semantic',
                            clicks: Number((row && row.clicks) || 0),
                            impressions: Number((row && row.impressions) || 0)
                        });
                    };

                    const pushKeywordIfUnique = (mappedKeyword, source, originalRow = null) => {
                        const keywordText = String((mappedKeyword && mappedKeyword.keyword) || '').trim();
                        if (!keywordText) {
                            return false;
                        }
                        const semanticCollapseAllowed = isKeywordSuggestionsTab;
                        const normalized = normalizeKeyword(keywordText);
                        const exactDuplicate = mergedKeywords.some(existing =>
                            normalizeKeyword(String(existing.keyword || '')) === normalized
                        );
                        if (exactDuplicate) {
                            return false;
                        }
                        const semanticMatch = semanticCollapseAllowed
                            ? findSemanticKeywordMatch(keywordText, mergedKeywords)
                            : null;
                        if (semanticMatch && semanticMatch.keyword) {
                            addSemanticVariant(semanticMatch.keyword, keywordText, source, originalRow);
                            return false;
                        }
                        mergedKeywords.push(mappedKeyword);
                        return true;
                    };
                    
                    keywords.forEach(apiKeyword => {
                        // Map local DB keyword payload format to internal format
                        const mappedKeyword = {
                            keyword: apiKeyword.keyword,
                            searchVolume: (apiKeyword.searchVolume !== undefined && apiKeyword.searchVolume !== null && apiKeyword.searchVolume !== '') ? apiKeyword.searchVolume : 'N/A',
                            difficulty: (apiKeyword.difficulty !== undefined && apiKeyword.difficulty !== null && apiKeyword.difficulty !== '') ? apiKeyword.difficulty : 'N/A',
                            cpc: (apiKeyword.cpc !== undefined && apiKeyword.cpc !== null && apiKeyword.cpc !== '') ? apiKeyword.cpc : 'N/A',
                            intent: (apiKeyword.intent !== undefined && apiKeyword.intent !== null && apiKeyword.intent !== '') ? apiKeyword.intent : 'N/A',
                            intentProbabilities: (apiKeyword.intentProbabilities && typeof apiKeyword.intentProbabilities === 'object') ? apiKeyword.intentProbabilities : null,
                            traffic: (apiKeyword.traffic !== undefined && apiKeyword.traffic !== null && apiKeyword.traffic !== '') ? apiKeyword.traffic : 'N/A',
                            trafficPct: (apiKeyword.trafficPct !== undefined && apiKeyword.trafficPct !== null && apiKeyword.trafficPct !== '') ? apiKeyword.trafficPct : 'N/A',
                            position: (apiKeyword.position !== undefined && apiKeyword.position !== null && apiKeyword.position !== '') ? apiKeyword.position : 'N/A',
                            itemTypes: Array.isArray(apiKeyword.itemTypes) ? apiKeyword.itemTypes : [],
                            targetUrl: apiKeyword.targetUrl || apiKeyword.url || 'N/A',
                            competition: apiKeyword.competition || 'N/A',
                            id: apiKeyword.id,
                            projectId: apiKeyword.projectId,
                            source: apiKeyword.source || 'suggested',
                            updatedAt: apiKeyword.updatedAt || apiKeyword.createdDate || '',
                            createdDate: apiKeyword.createdDate
                        };
                        
                        console.log('🔍 Mapping local keyword row:', {
                            original: apiKeyword,
                            mapped: mappedKeyword
                        });
                        
                        // In Keyword Suggestions, keep only endpoint-provided suggestion sources.
                        if (isKeywordSuggestionsTab) {
                            const src = String(mappedKeyword.source || '').toLowerCase();
                            const allowedSuggestionSources = new Set(['keyword_suggestion', 'related_keyword', 'suggested']);
                            if (!allowedSuggestionSources.has(src)) {
                                return;
                            }
                        }

                        pushKeywordIfUnique(mappedKeyword, 'suggested', apiKeyword);
                    });

                    if (!opts.localOnly && opts.includeGoogle) {
                        await loadGoogleKeywordRecommendations(projectId, {
                            forceRefresh: !!opts.forceRefreshGoogle
                        });
                        if (Array.isArray(window.aysaGoogleKeywordMappings) && window.aysaGoogleKeywordMappings.length > 0) {
                            window.aysaGoogleKeywordMappings.forEach(gscRow => {
                                const gscKeyword = String((gscRow && gscRow.keyword) || '').trim();
                                if (!gscKeyword) {
                                    return;
                                }

                                pushKeywordIfUnique({
                                    keyword: gscKeyword,
                                    searchVolume: gscRow.impressions ? Math.round(Number(gscRow.impressions)) : 'N/A',
                                    difficulty: 'N/A',
                                    intent: 'N/A',
                                    competition: 'N/A',
                                    id: '',
                                    projectId: projectId,
                                    source: 'gsc',
                                    gscPage: gscRow.page || '',
                                    gscClicks: Number(gscRow.clicks || 0),
                                    gscPosition: Number(gscRow.position || 0)
                                }, 'gsc-mapping', gscRow);
                            });
                        }
                        if (Array.isArray(window.aysaGoogleKeywordQueries) && window.aysaGoogleKeywordQueries.length > 0) {
                            window.aysaGoogleKeywordQueries.forEach(gscQuery => {
                                const gscKeyword = String((gscQuery && gscQuery.keyword) || '').trim();
                                if (!gscKeyword) {
                                    return;
                                }
                                pushKeywordIfUnique({
                                    keyword: gscKeyword,
                                    searchVolume: gscQuery.impressions ? Math.round(Number(gscQuery.impressions)) : 'N/A',
                                    difficulty: 'N/A',
                                    intent: 'N/A',
                                    competition: 'N/A',
                                    id: '',
                                    projectId: projectId,
                                    source: 'gsc-query',
                                    gscClicks: Number(gscQuery.clicks || 0),
                                    gscPosition: Number(gscQuery.position || 0),
                                    isGoogleSuggestion: true
                                }, 'gsc-query', gscQuery);
                            });
                        }
                    }

                    // Fill missing local metrics from Google signals already loaded in this page.
                    const googleSignalMap = {};
                    const putSignal = (row) => {
                        const key = normalizeKeyword(String((row && row.keyword) || ''));
                        if (!key) return;
                        const current = googleSignalMap[key] || { clicks: 0, impressions: 0, position: null };
                        const clicks = Number((row && row.clicks) || 0);
                        const impressions = Number((row && row.impressions) || 0);
                        const posRaw = Number((row && row.position) || 0);
                        if (clicks > current.clicks) current.clicks = clicks;
                        if (impressions > current.impressions) current.impressions = impressions;
                        if (posRaw > 0 && (current.position === null || posRaw < current.position)) current.position = posRaw;
                        googleSignalMap[key] = current;
                    };
                    (window.aysaGoogleKeywordMappings || []).forEach(putSignal);
                    (window.aysaGoogleKeywordQueries || []).forEach(putSignal);

                    mergedKeywords = mergedKeywords.map((kw) => {
                        const key = normalizeKeyword(String((kw && kw.keyword) || ''));
                        const signal = googleSignalMap[key];
                        if (!signal) return kw;
                        const next = { ...kw };
                        const hasTraffic = !(next.traffic === undefined || next.traffic === null || next.traffic === '' || next.traffic === 'N/A' || Number(next.traffic) <= 0);
                        const hasVolume = !(next.searchVolume === undefined || next.searchVolume === null || next.searchVolume === '' || next.searchVolume === 'N/A' || Number(next.searchVolume) <= 0);
                        // Do not hydrate SERP position from GSC average position; it can be misleading.
                        // Keep Position strictly from rank-tracking/suggested keyword sources.
                        if (!hasTraffic && signal.clicks > 0) next.traffic = Math.round(signal.clicks);
                        if (!hasVolume && signal.impressions > 0) next.searchVolume = Math.round(signal.impressions);
                        return next;
                    });
                    
                    if (mergedKeywords.length > 0) {
                        // Keep page loads local-first; enrichment is performed during explicit refresh workflows.
                    }
                    
                    window.aysaKeywords = mergedKeywords;
                    window.aysaKeywordSemanticVariants = semanticVariants;
                    // Pass enriched keywords to display, not just the new ones
                    displayKeywordResults(mergedKeywords);
                    if (window.aysaEnableAutoAssociation === true) {
                        runAutomaticAssociations({ manual: false });
                    }
                    autoAssociateKeywordsWithMatchedPage(projectId).catch(() => null);

                    // Ensure intent analysis actually runs after table data is loaded.
                    // This fills intent from DB/API and falls back to local heuristics when needed.
                    if (!opts.skipIntentRefresh) {
                        setTimeout(() => {
                            forceBatchIntentAnalysis();
                        }, 120);
                    }
                } else {
                    // Only clear if no existing keywords
                    if (!window.aysaKeywords || window.aysaKeywords.length === 0) {
                        window.aysaKeywords = [];
                        $tbody.html('<tr><td colspan="12" class="aysa-empty-message">No keyword suggestions found for this project.</td></tr>');
                    }
                }
                
                // Show combined notification with all keyword types
                const targetKeywordCount = window.aysaKeywords ? window.aysaKeywords.filter(k => k.isTargetKeyword).length : 0;
                
                if (!opts.silent) {
                    if (keywordCount > 0 && targetKeywordCount > 0) {
                        // Both target and suggested keywords
                        const totalKeywords = targetKeywordCount + keywordCount;
                        showNotification(`Loaded ${totalKeywords} keywords total (${targetKeywordCount} target + ${keywordCount} suggested)`, 'success');
                    } else if (keywordCount > 0) {
                        // Only suggested keywords
                        showNotification(`Loaded ${keywordCount} local keywords`, 'success');
                    } else if (targetKeywordCount > 0) {
                        // Only target keywords
                        showNotification(`Loaded ${targetKeywordCount} target keywords`, 'success');
                    } else {
                        // No keywords at all
                        showNotification('No local keywords found for this project. Press Refresh Data.', 'info');
                    }
                }
                const semanticVariantCount = Object.values(window.aysaKeywordSemanticVariants || {})
                    .reduce((sum, variants) => sum + (Array.isArray(variants) ? variants.length : 0), 0);
                const googleSuggestionCount = (window.aysaKeywords || []).filter(k => String(k.source || '').toLowerCase() === 'gsc-query').length;
                if (!opts.silent && (googleSuggestionCount > 0 || semanticVariantCount > 0)) {
                    showNotification(`Google suggestions: ${googleSuggestionCount} new | Semantic groups: ${semanticVariantCount}`, 'info');
                }
            },
            error: function(xhr, status, error) {
                console.error('Error loading local keywords:', { status, error, response: xhr.responseText });
                
                // Check if we at least have target keywords
                const targetKeywordCount = window.aysaKeywords ? window.aysaKeywords.filter(k => k.isTargetKeyword).length : 0;
                
                if (targetKeywordCount > 0) {
                    // We have target keywords but failed to load suggested keywords
                    if (!opts.silent) {
                        showNotification(`Loaded ${targetKeywordCount} target keywords, but failed to load local keywords`, 'error');
                    }
                } else {
                    // No keywords at all
                    $tbody.html('<tr><td colspan="12" class="aysa-empty-message">Failed to load keywords.</td></tr>');
                    if (!opts.silent) {
                        showNotification('Failed to load keywords', 'error');
                    }
                    window.aysaKeywords = [];
                }
            }
        });
    }

    // Load target keywords from KeywordsAndCompetitors API
    function loadTargetKeywordsFromApi(options = {}) {
        const opts = Object.assign({
            sourceMode: getActiveSourceMode(),
            includeGoogle: activeKeywordSubtab !== 'keyword_suggestions',
            silent: false
        }, options || {});
        const isGscAutoTab = opts.sourceMode === 'gsc_auto' || activeKeywordSubtab === 'gsc_auto_discovery';
        const $tbody = $('.aysa-keywords-table tbody');
        $tbody.html(`
            <tr class="aysa-loading-row">
                <td colspan="12" class="aysa-loading-cell">
                    <div class="aysa-loading-container">
                        <span class="dashicons dashicons-update aysa-spinning"></span>
                        <span class="aysa-loading-text">${isGscAutoTab ? 'Loading GSC keywords...' : 'Loading target keywords...'}</span>
                    </div>
                </td>
            </tr>
        `);

        const projectId = getProjectId();
        if (!projectId) {
            console.error("Project ID is missing.");
            $tbody.html('<tr><td colspan="12" class="aysa-empty-message">Project ID not found. Please set it up in plugin settings.</td></tr>');
            showNotification("Project ID is missing. Please set it up in the plugin settings.", 'error');
            return;
        }

        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'aysa_keyword_discovery_get_keywords_and_competitors',
                nonce: aysaAdminNonce,
                project_id: parseInt(projectId)
            },
            success: async function(response) {
                const expectedSourceMode = getActiveSourceMode();
                if (opts.sourceMode !== expectedSourceMode) {
                    console.log(`Ignoring stale target keyword response for source_mode="${opts.sourceMode}" (active="${expectedSourceMode}")`);
                    return;
                }
                const data = (response && response.success && response.data)
                    ? response.data
                    : {};
                console.log('Successfully loaded target keywords from API:', data);
                
                if (data && Array.isArray(data.keywords) && data.keywords.length > 0) {
                    // Keep target keywords visible in Keyword Discovery as baseline rows.
                    let targetKeywords = data.keywords.filter(keyword => keyword && keyword.trim() !== '').map(keyword => ({
                        keyword: keyword,
                        searchVolume: 'N/A',
                        difficulty: 'N/A',
                        intent: 'Target',
                        competition: 'N/A',
                        traffic: 'N/A',
                        trafficPct: 'N/A',
                        position: 'N/A',
                        itemTypes: [],
                        targetUrl: 'N/A',
                        source: 'target',
                        isTargetKeyword: true
                    }));
                    
                    console.log(`📌 Loaded ${targetKeywords.length} target keywords:`, targetKeywords.map(k => k.keyword));
                    
                    // Store target keywords in a separate variable for reference
                    window.aysaTargetKeywords = targetKeywords;

                    if (!isGscAutoTab) {
                        // Initialize non-GSC tabs with target keywords so UI is never empty.
                        window.aysaKeywords = targetKeywords;
                        allKeywords = targetKeywords;
                        displayKeywordResults(window.aysaKeywords);
                        
                        // Show loading state while enriching with suggested/local metrics.
                        $tbody.append('<tr><td colspan="12" class="aysa-empty-message">Loading suggested keywords...</td></tr>');
                    } else {
                        window.aysaKeywords = [];
                        allKeywords = [];
                    }
                    
                    // Reset generate more button state for new project
                    resetGenerateMoreButton();
                    
                    // Load suggested keywords (these WILL be displayed)
                    loadKeywordsFromApi(false, {
                        sourceMode: opts.sourceMode,
                        includeGoogle: !!opts.includeGoogle,
                        silent: !!opts.silent
                    });
                } else {
                    window.aysaKeywords = [];
                    allKeywords = [];
                    if (!isGscAutoTab) {
                        $tbody.html('<tr><td colspan="12" class="aysa-empty-message">No target keywords found for this project. Please complete the Setup SEO Profile wizard first.</td></tr>');
                    }
                    
                    // Reset generate more button state
                    resetGenerateMoreButton();
                    
                    // Don't show notification here - will be handled in loadKeywordsFromApi()
                    console.log('No target keywords found for this project');
                    
                    // Even if no target keywords, still try to load suggested keywords
                    window.aysaLoadingTargetKeywords = false; // No target keywords, so clear flag
                    loadKeywordsFromApi(false, {
                        sourceMode: opts.sourceMode,
                        includeGoogle: !!opts.includeGoogle,
                        silent: !!opts.silent
                    });
                }
            },
            error: function(xhr, status, error) {
                const expectedSourceMode = getActiveSourceMode();
                if (opts.sourceMode !== expectedSourceMode) {
                    console.log(`Ignoring stale target keyword error for source_mode="${opts.sourceMode}" (active="${expectedSourceMode}")`);
                    return;
                }
                console.error('Error loading target keywords from API:', { status, error, response: xhr.responseText });
                console.log('Failed to load target keywords, trying to load suggested keywords anyway');
                window.aysaKeywords = [];
                
                // Reset generate more button state
                resetGenerateMoreButton();
                
                // Still try to load suggested keywords even if target keywords failed
                window.aysaLoadingTargetKeywords = false; // Clear flag on error
                loadKeywordsFromApi(false, {
                    sourceMode: opts.sourceMode,
                    includeGoogle: !!opts.includeGoogle,
                    silent: !!opts.silent
                });
            }
        });
    }

    // Function to reset the Generate more Keywords button state
    function resetGenerateMoreButton() {
        const $btn = $('.aysa-generate-more-btn');
        $btn.prop('disabled', false)
            .removeClass('aysa-processing aysa-exhausted')
            .text('Refresh Suggested Keywords');
    }

    // Remove the search button click handler since we don't need API calls
    $('.aysa-search-btn').off('click');
    
    // Store original grouped keywords for search restoration
    let originalGroupedKeywords = [];
    
    // Update search to filter existing results while maintaining grouping
    $('.aysa-search-input').on('input', function() {
        const searchTerm = $(this).val().toLowerCase().trim();
        
        if (allKeywords.length > 0) {
            if (searchTerm === '') {
                // Restore original grouped keywords when search is cleared
                if (originalGroupedKeywords.length > 0) {
                    filteredKeywords = originalGroupedKeywords;
                } else if (activeKeywordSubtab === 'gsc_plus_data') {
                    filteredKeywords = allKeywords.map(keyword => ({
                        mainKeyword: keyword,
                        secondaryKeywords: [],
                        association: null
                    }));
                } else if (typeof groupKeywordsByAssociation === 'function') {
                    filteredKeywords = groupKeywordsByAssociation(allKeywords, '');
                } else {
                    // Fallback: use all keywords as-is if grouping function is not available
                    filteredKeywords = allKeywords;
                }
            } else {
                // Store original grouped keywords on first search
                if (originalGroupedKeywords.length === 0) {
                    originalGroupedKeywords = [...filteredKeywords];
                }
                
                // Filter from all keywords - search by keyword name and associated page/category/product name
                const searchFilteredKeywords = allKeywords.filter(result => {
                    // First check if keyword name matches
                    if (result.keyword.toLowerCase().includes(searchTerm)) {
                        return true;
                    }
                    
                    // Then check if any associated item name matches
                    if (window.aysaAssociations && Array.isArray(window.aysaAssociations)) {
                        const keywordAssociations = getAssociationsForKeyword(result.keyword);
                        return keywordAssociations.some(association => 
                            association.value && association.value.toLowerCase().includes(searchTerm)
                        );
                    }
                    
                    return false;
                });
                
                // Re-group the filtered keywords to maintain Primary/Secondary structure
                if (activeKeywordSubtab === 'gsc_plus_data') {
                    filteredKeywords = searchFilteredKeywords.map(keyword => ({
                        mainKeyword: keyword,
                        secondaryKeywords: [],
                        association: null
                    }));
                } else if (typeof groupKeywordsByAssociation === 'function') {
                    filteredKeywords = groupKeywordsByAssociation(searchFilteredKeywords, searchTerm);
                } else {
                    // Fallback: use filtered keywords as-is if grouping function is not available
                    filteredKeywords = searchFilteredKeywords;
                }
            }
            
            // Reset to first page
            currentPage = 1;
            
            // Display results for current page
            displayCurrentPage();
            updatePaginationInfo();
            updatePaginationControls();
        }
    });

    // Add click handler for the reassociate button
    $('.aysa-reassociate-btn').on('click', function() {
        runAutomaticAssociations({ manual: true, force: true });
    });

    // Add click handler for the triage button
    $('.aysa-triage-unlinked-btn').on('click', function() {
        runUnlinkedKeywordTriage();
    });

    // Add click handler for manual keyword addition
    $('.aysa-add-keyword-btn').on('click', async function() {
        const $btn = $(this);
        const $input = $('.aysa-add-keyword-input');
        const keyword = $input.val().trim();
        
        if (!keyword) {
            showNotification('Please enter a keyword to add', 'error');
            return;
        }
        
        // Check if keyword already exists
        if (window.aysaKeywords && window.aysaKeywords.some(k => k.keyword.toLowerCase() === keyword.toLowerCase())) {
            showNotification('This keyword already exists', 'error');
            $input.val('');
            return;
        }
        
        // Get project ID
        const projectId = getProjectId();
        if (!projectId) {
            showNotification('Project ID is missing. Cannot add keyword.', 'error');
            return;
        }
        
        // Disable button and show loading
        $btn.prop('disabled', true);
        $btn.html('<span class="dashicons dashicons-update aysa-spinning"></span> Adding...');
        
        try {
            // First save to database via API
            const suggestion = {
                ProjectId: projectId,
                Keyword: keyword,
                SearchVolume: 0, 
                Difficulty: 0,
                Intent: 'N/A',
                Competition: 'N/A'
            };

            const apiUrl = `${getApiBaseUrl()}/api/SuggestedKeywords/insert-one`;
            const response = await fetch(apiUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(suggestion)
            });

            if (response.status === 409) { // Conflict
                const errorData = await response.json();
                showNotification(errorData.message || 'Keyword already exists.', 'error');
                return;
            }

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const result = await response.json();

            if (result.success && result.data) {
                // Create keyword object from API response
                let newKeyword = {
                    keyword: result.data.keyword,
                    searchVolume: (result.data.searchVolume !== undefined && result.data.searchVolume !== null && result.data.searchVolume !== '') ? result.data.searchVolume : 'N/A',
                    difficulty: (result.data.difficulty !== undefined && result.data.difficulty !== null && result.data.difficulty !== '') ? result.data.difficulty : 'N/A',
                    intent: (result.data.intent !== undefined && result.data.intent !== null && result.data.intent !== '') ? result.data.intent : 'N/A',
                    intentProbabilities: (result.data.intentProbabilities && typeof result.data.intentProbabilities === 'object') ? result.data.intentProbabilities : null,
                    competition: (result.data.competition !== undefined && result.data.competition !== null && result.data.competition !== '') ? result.data.competition : 'N/A',
                    id: result.data.id,
                    projectId: result.data.projectId,
                    isManualKeyword: true
                };
                
                // 🎯 Enrich with intent data
                console.log(`🚀 Enriching manual keyword "${keyword}" with intent and difficulty...`);
                try {
                    // First enrich with intent
                    let enrichedKeywords = await enrichKeywordsWithIntent([newKeyword]);
                    newKeyword = enrichedKeywords[0];
                    
                    // Then enrich with difficulty
                    enrichedKeywords = await enrichKeywordsWithDifficulty([newKeyword]);
                    newKeyword = enrichedKeywords[0];
                } catch (enrichError) {
                    console.warn('Failed to enrich keyword with intent/difficulty:', enrichError);
                    // Continue with basic data if enrichment fails
                }
                
                // Add to the list
                if (!window.aysaKeywords) {
                    window.aysaKeywords = [];
                }
                window.aysaKeywords.unshift(newKeyword); // Add at beginning to make it visible
                
                // Refresh display with proper grouping
                displayKeywordResults(window.aysaKeywords);
                
                // Clear input and show success
                $input.val('');
                showNotification(`Keyword "${keyword}" added successfully and saved to database`, 'success');
            } else {
                throw new Error('Failed to add keyword. Invalid response from server.');
            }
            
        } catch (error) {
            console.error('Error adding manual keyword:', error);
            showNotification(`Error adding keyword: ${error.message}`, 'error');
        } finally {
            // Restore button
            $btn.prop('disabled', false);
            $btn.html('Add');
        }
    });

    // Allow Enter key to add keyword
    $('.aysa-add-keyword-input').on('keypress', function(e) {
        if (e.which === 13) { // Enter key
            $('.aysa-add-keyword-btn').click();
        }
    });

    // Add click handler for the generate more keywords button
    async function refreshKeywordSuggestionsData() {
        const projectId = getProjectId();
        if (!projectId) {
            throw new Error('Project ID is missing.');
        }
        const status = await startLocalKeywordRefreshAndWait(projectId, { refreshKind: 'keyword_suggestions' });
        if (!status || status.status !== 'completed') {
            throw new Error((status && status.last_error) ? status.last_error : 'Keyword suggestions refresh failed');
        }
        return status;
    }

    $('.aysa-generate-more-btn').on('click', function() {
        const $btn = $(this);
        const projectId = getProjectId();
        
        // Check if button is already disabled or processing
        if ($btn.prop('disabled') || $btn.hasClass('aysa-processing')) {
            return;
        }

        if (!projectId) {
            showNotification('Project ID is missing.', 'error');
            return;
        }
        
        // Disable button and add processing class
        $btn.prop('disabled', true).addClass('aysa-processing').text('Refreshing...');

        if (activeKeywordSubtab === 'keyword_suggestions' || activeKeywordSubtab === 'gsc_plus_data') {
            showNotification('Refreshing keyword suggestions...', 'loading');
            refreshKeywordSuggestionsData()
                .then(() => {
                    allKeywords = [];
                    filteredKeywords = [];
                    window.aysaKeywords = [];
                    return loadKeywordsFromApi(false, {
                    sourceMode: 'keyword_suggestions',
                    includeGoogle: activeKeywordSubtab === 'gsc_plus_data',
                    silent: true
                    });
                })
                .then(() => {
                    showNotification(
                        activeKeywordSubtab === 'gsc_plus_data'
                            ? 'GSC + DATA refreshed.'
                            : 'Keyword suggestions refreshed.',
                        'success'
                    );
                })
                .catch((error) => {
                    console.error('Keyword suggestions refresh failed:', error);
                    showNotification(
                        activeKeywordSubtab === 'gsc_plus_data'
                            ? `GSC + DATA refresh failed: ${error.message || error}`
                            : `Keyword suggestions refresh failed: ${error.message || error}`,
                        'error'
                    );
                })
                .finally(() => {
                    $btn.removeClass('aysa-processing');
                    $btn.prop('disabled', false).text('Refresh suggested Keywords');
                });
            return;
        }

        // Store initial keyword count to detect if new keywords were loaded
        const initialSuggestedCount = window.aysaKeywords ? window.aysaKeywords.filter(k => !k.isTargetKeyword).length : 0;

        // Show loading notification
        showNotification('Refreshing suggested keywords...', 'loading');

        // Call the function to refresh suggested keywords
        startLocalKeywordRefreshAndWait(projectId, { refreshKind: 'gsc_auto' }).then(function() {
            return loadKeywordsFromApi(false, {
            sourceMode: 'gsc_auto',
            includeGoogle: true
            });
        }).always(() => {
            // Check if new keywords were actually loaded
            const finalSuggestedCount = window.aysaKeywords ? window.aysaKeywords.filter(k => !k.isTargetKeyword).length : 0;
            const newKeywordsLoaded = finalSuggestedCount > initialSuggestedCount;

            // Remove processing class
            $btn.removeClass('aysa-processing');

            if (newKeywordsLoaded) {
                // Re-enable button if new keywords were loaded
                $btn.prop('disabled', false).text('Refresh suggested Keywords');
            } else {
                // Re-enable button anyway, but keep the same text
                $btn.prop('disabled', false).text('Refresh suggested Keywords');
            }
        });
    });

    function formatRefreshTimestamp(unixTs) {
        const seconds = Number(unixTs || 0);
        if (!Number.isFinite(seconds) || seconds <= 0) {
            return 'never';
        }
        const dt = new Date(seconds * 1000);
        if (Number.isNaN(dt.getTime())) {
            return 'never';
        }
        const pad = (value) => String(value).padStart(2, '0');
        return `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())} ${pad(dt.getHours())}:${pad(dt.getMinutes())}:${pad(dt.getSeconds())}`;
    }

    function updateFooterManualRefresh(status) {
        const metaEl = document.getElementById('aysa-footer-refresh-meta');
        if (!metaEl) {
            return;
        }
        const finishedAt = Number(status && status.finished_at ? status.finished_at : 0);
        metaEl.textContent = `(last manual refresh: ${formatRefreshTimestamp(finishedAt)})`;
    }

    $('#aysa-footer-refresh-link').on('click', function(e) {
        e.preventDefault();
        const $link = $(this);
        if ($link.hasClass('is-busy')) {
            return;
        }
        $link.addClass('is-busy');
        $('.aysa-generate-more-btn').trigger('click');
        const clearBusy = function() {
            if (!$('.aysa-generate-more-btn').hasClass('aysa-processing')) {
                $link.removeClass('is-busy');
                return;
            }
            setTimeout(clearBusy, 500);
        };
        setTimeout(clearBusy, 500);
    });

    const AYSA_LOCAL_DB_POLL_MS = 90 * 1000;
    let aysaLocalDbPollTimer = null;
    let aysaLocalDbPollInFlight = false;

    function startLocalDbAutoRefresh() {
        if (aysaLocalDbPollTimer) {
            clearInterval(aysaLocalDbPollTimer);
            aysaLocalDbPollTimer = null;
        }
        aysaLocalDbPollTimer = setInterval(function() {
            if (document.hidden) {
                return;
            }
            if (aysaLocalDbPollInFlight) {
                return;
            }
            if ($('.aysa-generate-more-btn').hasClass('aysa-processing')) {
                return;
            }
            aysaLocalDbPollInFlight = true;
            loadKeywordsFromApi(false, {
                silent: true,
                noLoadingState: true,
                localOnly: true,
                skipIntentRefresh: true
            }).always(function() {
                aysaLocalDbPollInFlight = false;
            });
        }, AYSA_LOCAL_DB_POLL_MS);
    }

    function stopLocalDbAutoRefresh() {
        if (aysaLocalDbPollTimer) {
            clearInterval(aysaLocalDbPollTimer);
            aysaLocalDbPollTimer = null;
        }
    }

    startLocalDbAutoRefresh();
    $(window).on('beforeunload', stopLocalDbAutoRefresh);

    function syncStickyHeaderOffset() {
        const adminBar = document.getElementById('wpadminbar');
        const fallbackTop = (window.innerWidth <= 782) ? 46 : 32;
        const adminBarHeight = adminBar ? Math.round(adminBar.getBoundingClientRect().height || 0) : 0;
        const wrap = document.querySelector('.aysa-table-responsive');
        const hasInternalVerticalScroll = !!(wrap && (wrap.scrollHeight - wrap.clientHeight > 1));
        const topPx = hasInternalVerticalScroll ? 0 : Math.max(fallbackTop, adminBarHeight);
        document.documentElement.style.setProperty('--aysa-sticky-table-top', `${topPx}px`);
        if (wrap) {
            wrap.style.overflowX = 'auto';
        }
        document.querySelectorAll('.aysa-keywords-table thead th').forEach((th) => {
            th.style.position = 'sticky';
            th.style.top = `${topPx}px`;
            th.style.zIndex = '40';
        });
    }

    syncStickyHeaderOffset();
    window.addEventListener('resize', syncStickyHeaderOffset, { passive: true });

    // Build strategy from setup seed keywords (no auto page creation).
    $('.aysa-generate-strategy-btn').on('click', function() {
        const projectId = getProjectId();
        generateKeywordStrategyFromSeeds(projectId);
    });

    // Function to group keywords by association for display
    function groupKeywordsByAssociation(keywords, searchTerm = '') {
        console.log('🔍 Starting keyword grouping with:', keywords.length, 'keywords');
        console.log('🔍 Available associations:', window.aysaAssociations?.length || 0);
        console.log('🔍 Search term for grouping:', searchTerm);
        const isKeywordSuggestionsTab = activeKeywordSubtab === 'keyword_suggestions';
        const isGscAutoTab = activeKeywordSubtab === 'gsc_auto_discovery';
        
        const groupedData = [];
        const processedKeywords = new Set();
        const groupMap = new Map();
        
        // Get the keywords that match the search to avoid showing unrelated associated keywords
        const keywordNames = new Set(keywords.map(k => k.keyword.toLowerCase()));

        // Keyword Suggestions must stay endpoint-only. Do not inject/merge legacy associations here.
        if (isKeywordSuggestionsTab) {
            const seen = new Set();
            keywords.forEach(keyword => {
                const normalized = String((keyword && keyword.keyword) || '').trim().toLowerCase();
                if (!normalized || seen.has(normalized)) {
                    return;
                }
                seen.add(normalized);
                groupedData.push({
                    mainKeyword: keyword,
                    secondaryKeywords: [],
                    association: null
                });
            });

            console.log(`✅ Grouping complete (keyword suggestions): ${groupedData.length} standalone rows`);
            return groupedData;
        }
        
        // First, create groups from associations and try to match with existing keywords
        if (window.aysaAssociations && window.aysaAssociations.length > 0) {
            window.aysaAssociations.forEach(association => {
                const groupKey = `${association.idIntern}_${association.link || 'null'}`;
                
                if (!groupMap.has(groupKey)) {
                    groupMap.set(groupKey, {
                        mainKeyword: null,
                        secondaryKeywords: [],
                        association: association,
                        groupKey: groupKey
                    });
                }
                
                const group = groupMap.get(groupKey);
                
                // Try to find matching keyword in the main keywords list
                const matchingKeyword = keywords.find(k => 
                    k.keyword.toLowerCase() === association.keyword.toLowerCase()
                );
                
                if (matchingKeyword) {
                    // Use existing keyword data
                    if (association.isMain === true) {
                        // Only set main if currently null or replace with isMain=true
                        if (!group.mainKeyword || group.mainKeyword.association.isMain !== true) {
                            group.mainKeyword = {
                                ...matchingKeyword,
                                association: association
                            };
                            console.log(`👑 Set main keyword from existing list: ${matchingKeyword.keyword} (isMain: ${association.isMain})`);
                        }
                    } else {
                        group.secondaryKeywords.push({
                            ...matchingKeyword,
                            association: association
                        });
                        console.log(`📌 Added secondary keyword from existing list: ${matchingKeyword.keyword} (isMain: ${association.isMain})`);
                    }
                    processedKeywords.add(association.keyword.toLowerCase());
                } else {
                    if (isKeywordSuggestionsTab) {
                        // Keep Keyword Suggestions endpoint-only: do not synthesize rows from legacy associations.
                        return;
                    }
                    // Only create synthetic keywords if they match the search term or if no search is active
                    const shouldIncludeKeyword = searchTerm === '' || 
                        association.keyword.toLowerCase().includes(searchTerm) ||
                        (association.value && association.value.toLowerCase().includes(searchTerm));
                    
                    if (shouldIncludeKeyword) {
                        // Create a keyword object from association data (for keywords not in main list)
                        // Check intent cache first, then association intent, then default to 'Unknown'
                        let keywordIntent = 'Unknown';
                        
                        // 1. Check if we have intent in cache
                        if (window.aysaCachedIntents && window.aysaCachedIntents.intents) {
                            const normalizedKeyword = association.keyword
                                .toLowerCase()
                                .normalize('NFD')
                                .replace(/[\u0300-\u036f]/g, '')
                                .trim();
                            
                            const cachedIntent = window.aysaCachedIntents.intents.find(intent => {
                                const normalizedCached = intent.keyword
                                    .toLowerCase()
                                    .normalize('NFD')
                                    .replace(/[\u0300-\u036f]/g, '')
                                    .trim();
                                return normalizedCached === normalizedKeyword;
                            });
                            
                            if (cachedIntent) {
                                keywordIntent = cachedIntent.intent;
                                console.log(`📊 Using cached intent for "${association.keyword}": ${keywordIntent}`);
                            }
                        }
                        
                        // 2. If no cached intent, use association intent if available
                        if (keywordIntent === 'Unknown' && association.intent) {
                            keywordIntent = association.intent;
                            console.log(`🔗 Using association intent for "${association.keyword}": ${keywordIntent}`);
                        }
                        
                        const syntheticKeyword = {
                            keyword: association.keyword,
                            searchVolume: 'N/A',
                            difficulty: 'N/A',
                            intent: keywordIntent,
                            id: association.id,
                            intentProbability: association.intentProbability // Include probability if available
                        };
                        
                        if (association.isMain === true) {
                            // Only set main if currently null or replace with isMain=true
                            if (!group.mainKeyword || group.mainKeyword.association.isMain !== true) {
                                group.mainKeyword = {
                                    ...syntheticKeyword,
                                    association: association
                                };
                                console.log(`👑 Created main keyword from association: ${association.keyword} (isMain: ${association.isMain}, intent: ${keywordIntent})`);
                            }
                        } else {
                            group.secondaryKeywords.push({
                                ...syntheticKeyword,
                                association: association
                            });
                            console.log(`📌 Created secondary keyword from association: ${association.keyword} (isMain: ${association.isMain}, intent: ${keywordIntent})`);
                        }
                        processedKeywords.add(association.keyword.toLowerCase());
                    } else {
                        console.log(`🚫 Skipping associated keyword "${association.keyword}" (doesn't match search: "${searchTerm}")`);
                    }
                }
            });
        }
        
        // Convert grouped data to array and handle groups without main keywords
        groupMap.forEach((group, groupKey) => {
            console.log(`🏗️ Processing group ${groupKey}:`, {
                hasMain: !!group.mainKeyword,
                secondaryCount: group.secondaryKeywords.length
            });
            
            if (!group.mainKeyword && group.secondaryKeywords.length > 0) {
                // If no main keyword found, promote first secondary to main
                group.mainKeyword = group.secondaryKeywords.shift();
                group.mainKeyword.association.isMain = true; // Force as main for display
                console.log(`🔄 Promoted secondary to main: ${group.mainKeyword.keyword}`);
            }
            
            if (group.mainKeyword) {
                groupedData.push(group);
            }
        });
        
        // Add standalone keywords (those without associations)
        keywords.forEach(keyword => {
            if (!processedKeywords.has(keyword.keyword.toLowerCase())) {
                groupedData.push({
                    mainKeyword: keyword,
                    secondaryKeywords: [],
                    association: null
                });
                console.log(`🔸 Added standalone keyword: ${keyword.keyword}`);
            }
        });

        // Keep seed/target keywords pinned at the top for planning-first UX.
        groupedData.sort((a, b) => {
            const aMain = a && a.mainKeyword ? a.mainKeyword : {};
            const bMain = b && b.mainKeyword ? b.mainKeyword : {};

            const aIsSeed = !!(aMain.isTargetKeyword || String(aMain.source || '').toLowerCase() === 'target');
            const bIsSeed = !!(bMain.isTargetKeyword || String(bMain.source || '').toLowerCase() === 'target');

            if (aIsSeed !== bIsSeed) {
                return aIsSeed ? -1 : 1;
            }

            const aKeyword = String(aMain.keyword || '').toLowerCase();
            const bKeyword = String(bMain.keyword || '').toLowerCase();
            return aKeyword.localeCompare(bKeyword, undefined, { sensitivity: 'base' });
        });
        
        console.log(`✅ Grouping complete. Created ${groupedData.length} groups from ${keywords.length} original keywords and ${window.aysaAssociations?.length || 0} associations`);
        return groupedData;
    }

    // Modify the displayKeywordResults function to work with pagination and merge target + suggested keywords
    function displayKeywordResults(results, updatePagination = true) {
        const $tbody = $('.aysa-keywords-table tbody');
        const isKeywordSuggestionsTab = activeKeywordSubtab === 'keyword_suggestions';
        const isGscAutoTab = activeKeywordSubtab === 'gsc_auto_discovery';
        const isGscPlusDataTab = activeKeywordSubtab === 'gsc_plus_data';
        const wrap = document.querySelector('.aysa-table-responsive');
        
        // If this is the initial load with all data, store it
        if (updatePagination) {
            if (isKeywordSuggestionsTab) {
                const incomingKeywords = Array.isArray(results) ? results : [];
                const dedupMap = new Map();
                incomingKeywords.forEach((keywordObj) => {
                    const key = String((keywordObj && keywordObj.keyword) || '').trim().toLowerCase();
                    if (!key || dedupMap.has(key)) {
                        return;
                    }
                    dedupMap.set(key, keywordObj);
                });
                const suggestionsOnly = Array.from(dedupMap.values()).filter(keyword =>
                    !window.aysaBannedKeywords?.includes(String((keyword && keyword.keyword) || '').toLowerCase())
                );
                allKeywords = suggestionsOnly;
                filteredKeywords = suggestionsOnly.map(keyword => ({
                    mainKeyword: keyword,
                    secondaryKeywords: [],
                    association: null
                }));
                originalGroupedKeywords = [];
                currentPage = 1;
            } else if (isGscPlusDataTab) {
                const incomingKeywords = Array.isArray(results) ? results : [];
                const dedupMap = new Map();
                incomingKeywords.forEach((keywordObj) => {
                    const key = String((keywordObj && keywordObj.keyword) || '').trim().toLowerCase();
                    if (!key || dedupMap.has(key)) {
                        return;
                    }
                    dedupMap.set(key, keywordObj);
                });
                const allowedSources = new Set([
                    'gsc', 'gsc-query', 'gsc_query', 'gsc_query_only',
                    'keyword_suggestion', 'related_keyword', 'suggested'
                ]);
                const combined = Array.from(dedupMap.values())
                    .filter(keyword => !window.aysaBannedKeywords?.includes(String((keyword && keyword.keyword) || '').toLowerCase()))
                    .filter(keyword => allowedSources.has(String((keyword && keyword.source) || '').toLowerCase()));
                allKeywords = combined;
                filteredKeywords = combined.map(keyword => ({
                    mainKeyword: keyword,
                    secondaryKeywords: [],
                    association: null
                }));
                originalGroupedKeywords = [];
                currentPage = 1;
            } else if (isGscAutoTab) {
                const incomingKeywords = Array.isArray(results) ? results : [];
                const dedupMap = new Map();
                incomingKeywords.forEach((keywordObj) => {
                    const key = String((keywordObj && keywordObj.keyword) || '').trim().toLowerCase();
                    if (!key || dedupMap.has(key)) {
                        return;
                    }
                    dedupMap.set(key, keywordObj);
                });
                const gscOnly = Array.from(dedupMap.values())
                    .filter(keyword => !window.aysaBannedKeywords?.includes(String((keyword && keyword.keyword) || '').toLowerCase()))
                    .filter(keyword => {
                        const source = String((keyword && keyword.source) || '').toLowerCase();
                        return source === 'gsc' || source === 'gsc-query' || source === 'gsc_query' || source === 'gsc_query_only';
                    });
                allKeywords = gscOnly;
                filteredKeywords = gscOnly.map(keyword => ({
                    mainKeyword: keyword,
                    secondaryKeywords: [],
                    association: null
                }));
                originalGroupedKeywords = [];
                currentPage = 1;
            } else {
            // Check if we already have keywords stored (for merging)
            const existingKeywords = allKeywords || [];
            const newKeywords = results || [];
            
            // Merge target and suggested keywords, preventing duplicates
            const mergedKeywords = [...existingKeywords];
            
            newKeywords.forEach(newKeyword => {
                // Check if keyword already exists (case-insensitive comparison)
                const isDuplicate = mergedKeywords.some(existing => 
                    existing.keyword.toLowerCase() === newKeyword.keyword.toLowerCase()
                );
                
                if (!isDuplicate) {
                    mergedKeywords.push(newKeyword);
                }
            });
            
            // Filter out banned keywords
            const nonBannedKeywords = mergedKeywords.filter(keyword => !window.aysaBannedKeywords?.includes(keyword.keyword.toLowerCase()));
            
            // Group keywords BEFORE pagination
            const groupedKeywords = groupKeywordsByAssociation(nonBannedKeywords);
            
            allKeywords = nonBannedKeywords; // Keep original for search/filtering
            filteredKeywords = groupedKeywords; // Use grouped for display
            originalGroupedKeywords = []; // Reset search cache when data is reloaded
            currentPage = 1;
            }
        }
        
        // Use the provided results (for pagination) or filtered results (for full load)
        const dataToDisplay = updatePagination ? filteredKeywords : results;

        // On full redraw we always restart from top so the first row is visible.
        if (updatePagination && wrap) {
            wrap.scrollTop = 0;
        }
        
        // Arată indicatorul de loading inițial
        if (!$tbody.find('.aysa-loading-row').length && updatePagination) {
            $tbody.html(`
                <tr class="aysa-loading-row">
                    <td colspan="12" class="aysa-loading-cell">
                        <div class="aysa-loading-container">
                            <span class="dashicons dashicons-update aysa-spinning"></span>
                            <span class="aysa-loading-text">Loading keywords data...</span>
                        </div>
                    </td>
                </tr>
            `);
        }

        // Dacă nu avem rezultate, arată mesajul corespunzător
        if (!dataToDisplay || dataToDisplay.length === 0) {
            $tbody.html('<tr><td colspan="12" class="aysa-empty-message">No keyword suggestions found. Please generate suggestions from the Competition & Keywords page.</td></tr>');
            if (updatePagination) {
                updatePaginationInfo();
                updatePaginationControls();
            }
            return;
        }

        // Am primit rezultate, goliți tabela și adăugăm rândurile de date
        $tbody.empty();

        // Prepare storage for dropdown selections
        const savedSelections = {};

        // Get project ID for API calls
        const projectId = getProjectId();

        if (!projectId) {
            console.error('Project ID not found in localStorage');
            $tbody.html('<tr><td colspan="12" class="aysa-empty-message">Project ID not found. Please create a project first.</td></tr>');
            return;
        }

        // Dacă avem puține rezultate și e prima încărcare, adăugăm un mesaj de loading pentru a evita flickering
        if (dataToDisplay.length < 5 && updatePagination) {
            $tbody.html(`
                <tr class="aysa-loading-row">
                    <td colspan="12" class="aysa-loading-cell">
                        <div class="aysa-loading-container">
                            <span class="dashicons dashicons-update aysa-spinning"></span>
                            <span class="aysa-loading-text">Processing keyword data...</span>
                        </div>
                    </td>
                </tr>
            `);
        }

        // Determine which data to process and whether to use timeout
        const finalResults = updatePagination ? 
            filteredKeywords.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage) : 
            dataToDisplay;

        // Procesez datele cu o mică întârziere pentru a permite afișarea indicatorului de loading (doar la prima încărcare)
        const processData = () => {
            $tbody.empty(); // Golim din nou pentru a ne asigura că nu mai există indicatorul de loading
            if (activeKeywordSubtab === 'gsc_plus_data') {
                renderGscPlusDataFlatRows(finalResults, $tbody);
                updatePaginationInfo();
                updatePaginationControls();
                return;
            }
            let visualGroupIndex = 0;
            
            // Check if results are already grouped or are individual keywords
            finalResults.forEach(function(item, index) {
                let group;
                
                // If item has mainKeyword property, it's already a group
                if (item.mainKeyword) {
                    group = item;
                } else {
                    // If it's a regular keyword, treat it as a standalone group
                    group = {
                        mainKeyword: item,
                        secondaryKeywords: [],
                        association: null
                    };
                }
                
                // Process main keyword first
                if (group.mainKeyword) {
                    if (isKeywordSuggestionsTab) {
                        group.secondaryKeywords = [];
                    }
                    const result = group.mainKeyword;
                    const zebraClass = (visualGroupIndex % 2 === 0) ? 'aysa-zebra-light' : 'aysa-zebra-white';
                    visualGroupIndex++;
                    const difficultyClass = getDifficultyClass(result.difficulty);
                    const resolvedMainIntent = checkKeywordIntent(result)
                        ? String(result.intent || '').trim()
                        : getIntentFallback(String(result.keyword || ''));
                    const intentIndicators = getIntentIndicators(resolvedMainIntent, result.intentProbabilities || null);
                    if (!checkKeywordIntent(result) && resolvedMainIntent) {
                        result.intent = resolvedMainIntent;
                    }
                
                // Find ALL associations for this keyword
                const keywordAssociations = isKeywordSuggestionsTab ? [] : getAssociationsForKeyword(result.keyword);
                let urlCellContent = '';
                let pageType = '';
                
                if (keywordAssociations.length > 0) {
                    console.log('Found associations:', keywordAssociations);
                    
                    if (keywordAssociations.length === 1) {
                        // Single association - display as before
                        const association = keywordAssociations[0];
                        let editUrl = '';
                        switch(association.associatedOn) {
                            case 'Category':
                                editUrl = `${window.location.origin}/wp-admin/term.php?taxonomy=product_cat&tag_ID=${association.idIntern}&post_type=product&wp_http_referer=${encodeURIComponent('/wp-admin/edit-tags.php?taxonomy=product_cat&post_type=product')}`;
                                break;
                            case 'Product':
                                editUrl = `${window.location.origin}/wp-admin/post.php?post=${association.idIntern}&action=edit`;
                                break;
                            case 'Page':
                                editUrl = `${window.location.origin}/wp-admin/post.php?post=${association.idIntern}&action=edit`;
                                break;
                        }
                        
                        if (editUrl) {
                            urlCellContent = `<a href="${editUrl}" class="aysa-url-link">${association.value}</a>`;
                            // Set page type based on association type
                            pageType = getPageTypeFromAssociation(association.associatedOn);
                        }
                    } else {
                        // Multiple associations - display all with type indicators
                        const associationLinks = keywordAssociations.map(association => {
                            let editUrl = '';
                            let typeIcon = '';
                            
                            switch(association.associatedOn) {
                                case 'Category':
                                    editUrl = `${window.location.origin}/wp-admin/term.php?taxonomy=product_cat&tag_ID=${association.idIntern}&post_type=product&wp_http_referer=${encodeURIComponent('/wp-admin/edit-tags.php?taxonomy=product_cat&post_type=product')}`;
                                    typeIcon = '📁';
                                    break;
                                case 'Product':
                                    editUrl = `${window.location.origin}/wp-admin/post.php?post=${association.idIntern}&action=edit`;
                                    typeIcon = '🛍️';
                                    break;
                                case 'Page':
                                    editUrl = `${window.location.origin}/wp-admin/post.php?post=${association.idIntern}&action=edit`;
                                    typeIcon = '📄';
                                    break;
                            }
                            
                            if (editUrl) {
                                return `<div class="aysa-multi-association">
                                    <span class="aysa-association-type">${typeIcon}</span>
                                    <a href="${editUrl}" class="aysa-url-link" title="${association.associatedOn}: ${association.value}">${association.value}</a>
                                </div>`;
                            }
                            return '';
                        }).filter(link => link !== '');
                        
                        urlCellContent = `<div class="aysa-multiple-associations">${associationLinks.join('')}</div>`;
                        // For multiple associations, show "Mixed" type
                        const associationTypes = keywordAssociations.map(a => a.associatedOn);
                        const uniqueTypes = [...new Set(associationTypes)];
                        if (uniqueTypes.length === 1) {
                            pageType = getPageTypeFromAssociation(uniqueTypes[0]);
                        } else {
                            pageType = '<span class="aysa-page-type aysa-page-type-mixed">Mixed</span>';
                        }
                    }
                    console.log('Created URL content:', urlCellContent);
                } else {
                    if (result.targetUrl && result.targetUrl !== 'N/A') {
                        const safeTargetUrl = escapeAttr(result.targetUrl);
                        urlCellContent = `<a href="${safeTargetUrl}" class="aysa-url-link" target="_blank" rel="noopener noreferrer">${escapeHtml(result.targetUrl)}</a>`;
                        pageType = getPageType(result.targetUrl);
                    }
                    const keywordHintKey = String(result.keyword || '').trim().toLowerCase();
                    const gscHint = window.aysaGoogleKeywordUrlHints && window.aysaGoogleKeywordUrlHints[keywordHintKey]
                        ? window.aysaGoogleKeywordUrlHints[keywordHintKey]
                        : null;
                    if (gscHint && gscHint.item) {
                        const safeHintName = escapeHtml(gscHint.item.name || gscHint.url || '');
                        const safeHintUrl = escapeAttr(gscHint.url || '');
                        urlCellContent = `<span class="aysa-url-link" title="Suggested by Google Search Console: ${safeHintUrl}">Suggested: ${safeHintName}</span>`;
                        pageType = `<span class="aysa-page-type aysa-page-type-unknown">Suggested ${escapeHtml(gscHint.item.type || '')}</span>`;
                    } else {
                        const ga4Hint = findBestGa4HintForKeyword(result.keyword);
                        if (ga4Hint && ga4Hint.item) {
                            const safeHintName = escapeHtml(ga4Hint.item.name || '');
                            const safePath = escapeAttr(ga4Hint.page_path || '');
                            const sessions = Math.round(Number(ga4Hint.sessions || 0));
                            urlCellContent = `<span class="aysa-url-link" title="Suggested by Google Analytics (page path: ${safePath}, sessions: ${sessions})">Suggested: ${safeHintName}</span>`;
                            pageType = `<span class="aysa-page-type aysa-page-type-unknown">Suggested ${escapeHtml(ga4Hint.item.type || '')}</span>`;
                        } else {
                            const compositeHint = getCompositeRecommendation(result);
                            if (compositeHint && compositeHint.item && compositeHint.score >= 0.55) {
                                const safeHintName = escapeHtml(compositeHint.item.name || '');
                                const hintPct = Math.round(Number(compositeHint.score || 0) * 100);
                                const hintSource = escapeHtml(String(compositeHint.source || 'composite').toUpperCase());
                                urlCellContent = `<span class="aysa-url-link" title="Suggested by lexical + semantic + intent fit (${hintSource}, score: ${hintPct}%)">Suggested: ${safeHintName}</span>`;
                                pageType = `<span class="aysa-page-type aysa-page-type-unknown">Suggested ${escapeHtml(compositeHint.item.type || '')}</span>`;
                                if (!window.aysaKeywordConfidenceMap) {
                                    window.aysaKeywordConfidenceMap = {};
                                }
                                window.aysaKeywordConfidenceMap[String(result.keyword || '').toLowerCase()] = {
                                    confidence: compositeHint.confidence,
                                    source: 'match'
                                };
                            }
                        }
                    }
                }
                const trafficValue = formatNumber(result.traffic);
                const trafficPctValue = formatPercentValue(result.trafficPct);
                const cpcValue = formatCpcValue(result.cpc);
                const updatedValue = formatUpdatedAgo(result.updatedAt || result.createdDate);
                const serpFeaturesHtml = formatSerpFeatures(result.itemTypes);

                const confidenceInfo = window.aysaKeywordConfidenceMap
                    ? window.aysaKeywordConfidenceMap[String(result.keyword || '').toLowerCase()]
                    : null;
                let confidenceBadge = '';
                if (confidenceInfo && confidenceInfo.confidence) {
                    const rawLabel = String(confidenceInfo.confidence);
                    const label = rawLabel.charAt(0).toUpperCase() + rawLabel.slice(1).toLowerCase();
                    const cls = label === 'High'
                        ? 'aysa-confidence-high'
                        : (label === 'Medium' ? 'aysa-confidence-medium' : 'aysa-confidence-low');
                    const sourceText = confidenceInfo.source ? ` (${String(confidenceInfo.source).toUpperCase()})` : '';
                    confidenceBadge = `<div class="aysa-confidence-chip ${cls}" title="Auto-match confidence${sourceText}">${label}${sourceText}</div>`;
                }

                const gscRows = getGscRowsForKeyword(result.keyword, 2);
                const semanticTopMatches = getTopSemanticMatches(result.keyword, 3);
                let semanticDebugHtml = '';
                if (semanticTopMatches.length > 0) {
                    const topScore = semanticTopMatches[0].score;
                    const secondScore = semanticTopMatches[1] ? semanticTopMatches[1].score : 0;
                    const conf = confidenceLabelFromScore(topScore, topScore - secondScore);
                    const itemsHtml = semanticTopMatches.map(match => {
                        const pct = Math.round(match.score * 100);
                        return `<div class="aysa-semantic-debug-item">${escapeHtml(match.type)}: ${escapeHtml(match.name)} (${pct}%)</div>`;
                    }).join('');
                    semanticDebugHtml = `<div class="aysa-semantic-debug"><div class="aysa-semantic-debug-title">Semantic top (${escapeHtml(conf)})</div>${itemsHtml}</div>`;
                } else {
                    if (gscRows.length > 0) {
                        semanticDebugHtml = `<div class="aysa-semantic-debug"><div class="aysa-semantic-debug-title">Semantic top</div><div class="aysa-semantic-debug-item">No semantic candidate, but GSC signal exists.</div></div>`;
                    } else {
                        semanticDebugHtml = `<div class="aysa-semantic-debug"><div class="aysa-semantic-debug-title">Semantic top</div><div class="aysa-semantic-debug-item">No candidate above threshold.</div></div>`;
                    }
                }

                let googleSignalsHtml = '';
                if (gscRows.length > 0) {
                    const rowsHtml = gscRows.map(row => {
                        const page = String((row && row.page) || '');
                        const clicks = Math.round(Number((row && row.clicks) || 0));
                        const pos = Number((row && row.position) || 0).toFixed(1);
                        return `<div class="aysa-google-signal-item">• ${escapeHtml(page)} | pos ${escapeHtml(pos)} | ${escapeHtml(String(clicks))} clicks</div>`;
                    }).join('');
                    const matchCurrent = hasGscMatchForCurrentAssociation(keywordAssociations, gscRows);
                    const statusHtml = keywordAssociations.length > 0
                        ? (matchCurrent
                            ? '<span class="aysa-google-status aysa-google-status-ok">GSC Match</span>'
                            : '<span class="aysa-google-status aysa-google-status-warn">GSC Mismatch</span>')
                        : '';
                    googleSignalsHtml = `<div class="aysa-google-signals"><strong>Google signals (GSC)</strong>${rowsHtml}${statusHtml}</div>`;
                }

                // Determine row class based on associations (3-color system)
                let rowClass = '';
                let borderColor = '';
                
                if (keywordAssociations.length > 0) {
                    // Associated keyword
                    rowClass = 'aysa-main-associated';
                    borderColor = '#d8e1ec';
                } else {
                    // No association
                    rowClass = 'aysa-no-association';
                    borderColor = '#d8e1ec';
                }

                // Create dropdown content
                let dropdownContent = `
                    <a href="#">Associate Category</a>
                    <a href="#">Associate Product</a>
                    <a href="#">Associate Page</a>
                    <a href="#">Edit in Page</a>
                    <a href="#">Associate</a>
                    <a href="#">Optimize</a>
                `;

                // Build secondary keywords HTML if any (keeping for backward compatibility)
                let secondaryKeywordsHtml = '';
                if (group.secondaryKeywords && group.secondaryKeywords.length > 0) {
                    console.log(`🔗 Building secondary keywords HTML for ${group.secondaryKeywords.length} keywords`);
                    secondaryKeywordsHtml = `
                        <div class="aysa-secondary-keywords-count">
                            <span class="aysa-secondary-count-text">${group.secondaryKeywords.length} secondary keyword${group.secondaryKeywords.length > 1 ? 's' : ''}</span>
                        </div>
                    `;
                }

                const groupKeywords = [result].concat(group.secondaryKeywords || []);
                const normalizedGroupKeywordSet = new Set(
                    groupKeywords.map(k => String((k && k.keyword) || '').trim().toLowerCase()).filter(Boolean)
                );
                const groupAssociations = (window.aysaAssociations || []).filter(a =>
                    normalizedGroupKeywordSet.has(String((a && a.keyword) || '').trim().toLowerCase())
                );
                const associatedKeywordCount = new Set(
                    groupAssociations.map(a => String((a && a.keyword) || '').trim().toLowerCase())
                ).size;
                const totalKeywordCount = normalizedGroupKeywordSet.size || 1;
                const isFullyAssociated = associatedKeywordCount === totalKeywordCount;
                const isPartiallyAssociated = associatedKeywordCount > 0 && !isFullyAssociated;
                const associationState = isFullyAssociated ? 'linked' : (isPartiallyAssociated ? 'partial' : 'unlinked');
                const associationStatusClass = isFullyAssociated ? 'is-linked' : (isPartiallyAssociated ? 'is-partial' : 'is-unlinked');
                const associationStatusLabel = isFullyAssociated
                    ? `Associated ${associatedKeywordCount}/${totalKeywordCount}`
                    : (isPartiallyAssociated
                        ? `Partially associated ${associatedKeywordCount}/${totalKeywordCount}`
                        : `Not associated 0/${totalKeywordCount}`);
                const associationSignalHtml = isFullyAssociated
                    ? `<span class="aysa-association-check" title="Matched URL and association set">✓ Associated</span>`
                    : '';
                const hasSemanticCandidate = Array.isArray(semanticTopMatches) && semanticTopMatches.length > 0 && Number(semanticTopMatches[0].score || 0) >= 0.62;
                const hasGscCandidate = Array.isArray(gscRows) && gscRows.length > 0;
                const hasTargetUrlCandidate = !!(result.targetUrl && result.targetUrl !== 'N/A');
                const todoPlan = determineKeywordTodoPlan({
                    keyword: result.keyword,
                    intent: resolvedMainIntent,
                    hasAssociation: keywordAssociations.length > 0,
                    hasExistingCandidate: hasGscCandidate || hasSemanticCandidate || hasTargetUrlCandidate
                });
                const todoPlanHtml = isKeywordSuggestionsTab ? renderKeywordTodoPlan(todoPlan) : '';

                const safeKeyword = escapeHtml(result.keyword || '');
                const safeKeywordAttr = escapeAttr(result.keyword || '');
                const isSeedKeyword = !!(result.isTargetKeyword || String(result.source || '').toLowerCase() === 'target');
                const seedKeywordBadge = isSeedKeyword ? '<div class="aysa-seed-keyword-pill">SEED KEYWORD</div>' : '';
                const keywordSource = String(result.source || '').toLowerCase();
                const gscPlusDataBadge = activeKeywordSubtab === 'gsc_plus_data'
                    ? (
                        (keywordSource === 'gsc' || keywordSource === 'gsc-query' || keywordSource === 'gsc_query' || keywordSource === 'gsc_query_only')
                            ? '<div class="aysa-seed-keyword-pill">GSC</div>'
                            : '<div class="aysa-legacy-keyword-pill">DATA</div>'
                    )
                    : '';
                const isLegacyKeywordInSuggestions = activeKeywordSubtab === 'keyword_suggestions'
                    && keywordSource
                    && !['keyword_suggestion', 'related_keyword', 'suggested'].includes(keywordSource);
                const legacyKeywordBadge = isLegacyKeywordInSuggestions
                    ? '<div class="aysa-legacy-keyword-pill">LEGACY ASSOCIATION</div>'
                    : '';
                const semanticVariantsForKeyword = window.aysaKeywordSemanticVariants
                    ? window.aysaKeywordSemanticVariants[String(result.keyword || '').trim().toLowerCase()]
                    : [];
                let semanticVariantsHtml = '';
                if (Array.isArray(semanticVariantsForKeyword) && semanticVariantsForKeyword.length > 0) {
                    const variantItemsHtml = semanticVariantsForKeyword.slice(0, 5).map(variant => {
                        const label = escapeHtml(String(variant.keyword || ''));
                        const sourceLabel = String(variant.source || '').toLowerCase() === 'gsc-query'
                            ? 'GSC query'
                            : 'variant';
                        return `<span class="aysa-keyword-variant-chip" title="Grouped semantic variant">${label} <em>(${escapeHtml(sourceLabel)})</em></span>`;
                    }).join('');
                    semanticVariantsHtml = `<div class="aysa-keyword-variants"><span class="aysa-keyword-variants-label">Grouped variants:</span>${variantItemsHtml}</div>`;
                }
                const $row = $(`
                    <tr class="aysa-group-main-row ${rowClass} ${zebraClass}" data-keyword-id="${result.id || ''}" style="border-left: 3px solid ${borderColor};">
                        <td class="aysa-keyword-col">
                                <div class="aysa-main-keyword">
                                    <div class="aysa-keyword-wrapper">
                                        <span class="aysa-keyword-text">${safeKeyword}</span>
                                        ${associationSignalHtml}
                                    </div>
                                    ${gscPlusDataBadge}
                                    ${seedKeywordBadge}
                                    ${legacyKeywordBadge}
                                    ${todoPlanHtml}
                                    ${semanticVariantsHtml}
                                    ${secondaryKeywordsHtml}
                                    <div class="aysa-association-status-chip ${associationStatusClass}">${associationStatusLabel}</div>
                                </div>
                        </td>
                        <td class="aysa-intent-col">
                            <div class="aysa-keyword-indicators">
                                ${intentIndicators}
                            </div>
                        </td>
                        <td class="aysa-volume-col">${formatNumber(result.searchVolume)}</td>
                        <td class="aysa-difficulty-col">${formatDifficulty(result.difficulty)}</td>
                        <td class="aysa-cpc-col">${cpcValue}</td>
                        <td class="aysa-serp-col">${serpFeaturesHtml}</td>
                        <td class="aysa-updated-col">${updatedValue}</td>
                        <td class="aysa-traffic-col">${trafficValue}</td>
                        <td class="aysa-traffic-pct-col">${trafficPctValue}</td>
                        <td class="aysa-url-col">${urlCellContent}${googleSignalsHtml}</td>
                        <td class="aysa-page-type-col">${(pageType || '<span class="aysa-page-type aysa-page-type-unknown">-</span>') + confidenceBadge + semanticDebugHtml}</td>
                        <td class="aysa-desired-col">
                            <div class="aysa-desired-wrapper">
                                <select class="aysa-desired-position" data-keyword="${safeKeywordAttr}">
                                    <option value="" selected>Select position</option>
                                    <option value="1-3">Position 1-3</option>
                                    <option value="4-10">Position 4-10</option>
                                    <option value="10+">Position 10+</option>
                                </select>
                            </div>
                        </td>
                    </tr>
                `);

                // If associated, also style the action button to be green
                if (keywordAssociations.length > 0) {
                    $row.find('.aysa-action-btn').addClass('aysa-btn-associated');
                    
                    console.log(`🔍 DEBUG: Processing keyword "${result.keyword}"`);
                    console.log(`🔍 DEBUG: Found ${keywordAssociations.length} associations:`, keywordAssociations.map(a => ({
                        keyword: a.keyword,
                        desiredPosition: a.desiredPosition,
                        isMain: a.isMain
                    })));
                    
                    // Find the association for THIS specific keyword (not just the first one)
                    const currentKeywordAssociation = keywordAssociations.find(a => 
                        a.keyword.toLowerCase().trim() === result.keyword.toLowerCase().trim()
                    );
                    
                    console.log(`🔍 DEBUG: Current keyword association:`, currentKeywordAssociation);
                    
                    // Set desired position dropdown value from the correct association
                    if (currentKeywordAssociation && currentKeywordAssociation.desiredPosition) {
                        // Convert number to dropdown value (2 -> "1-3", 7 -> "4-10", 15 -> "10+")
                        let dropdownValue = ''; // default to placeholder
                        if (currentKeywordAssociation.desiredPosition >= 1 && currentKeywordAssociation.desiredPosition <= 3) {
                            dropdownValue = '1-3';
                        } else if (currentKeywordAssociation.desiredPosition >= 4 && currentKeywordAssociation.desiredPosition <= 10) {
                            dropdownValue = '4-10';
                        } else if (currentKeywordAssociation.desiredPosition > 10) {
                            dropdownValue = '10+';
                        }
                        
                        console.log(`🎯 Setting desired position for "${result.keyword}": ${currentKeywordAssociation.desiredPosition} -> "${dropdownValue}"`);
                        
                        $row.find('.aysa-desired-position').val(dropdownValue);
                        $row.data('desiredTarget', dropdownValue);
                        $row.data('desiredPosition', currentKeywordAssociation.desiredPosition);
                    } else {
                        console.log(`⚠️ No desiredPosition found for "${result.keyword}"`);
                    }
                }

                $tbody.append($row);

                // Secondary association row for better UX: keep research metrics on main row,
                // and expose matching/association context in a dedicated panel row.
                const associationPanelHtml = `
                    <tr class="aysa-association-detail-row ${zebraClass}" data-parent-keyword="${safeKeywordAttr}" data-association-state="${associationState}">
                        <td colspan="99" class="aysa-association-detail-cell">
                            <div class="aysa-association-detail-grid">
                                <div class="aysa-association-detail-block">
                                    <div class="aysa-association-detail-title">Matched Page</div>
                                    <div class="aysa-association-detail-content">${urlCellContent || 'N/A'}${googleSignalsHtml || ''}</div>
                                </div>
                                <div class="aysa-association-detail-block">
                                    <div class="aysa-association-detail-title">Association Signals</div>
                                    <div class="aysa-association-detail-content">${(pageType || '<span class="aysa-page-type aysa-page-type-unknown">-</span>') + confidenceBadge + semanticDebugHtml}</div>
                                </div>
                                <div class="aysa-association-detail-block aysa-association-detail-block-actions">
                                    <div class="aysa-association-detail-title">Quick Actions</div>
                                    <div class="aysa-association-detail-actions">
                                        <div class="aysa-association-detail-hint">Manage association and target directly from this panel.</div>
                                        <div class="aysa-action-dropdown aysa-manage-action-dropdown">
                                            <button class="aysa-action-btn aysa-manage-association-btn">Manage Association</button>
                                            <div class="aysa-dropdown-content">
                                                ${dropdownContent}
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </td>
                    </tr>
                `;
                if (!isKeywordSuggestionsTab) {
                    const $associationRow = $(associationPanelHtml);
                    if (keywordAssociations.length > 0) {
                        $associationRow.find('.aysa-manage-association-btn').addClass('aysa-btn-associated');
                    }
                    $tbody.append($associationRow);
                }

                // Create separate rows for secondary keywords with light green background
                if (!isKeywordSuggestionsTab && group.secondaryKeywords && group.secondaryKeywords.length > 0) {
                    group.secondaryKeywords.forEach((secondaryKeyword, index) => {
                        const resolvedSecondaryIntent = checkKeywordIntent(secondaryKeyword)
                            ? String(secondaryKeyword.intent || '').trim()
                            : getIntentFallback(String(secondaryKeyword.keyword || ''));
                        if (!checkKeywordIntent(secondaryKeyword) && resolvedSecondaryIntent) {
                            secondaryKeyword.intent = resolvedSecondaryIntent;
                        }
                        // Determine intent indicators for secondary keyword (use same function as main)
                        const secondaryIntentIndicators = getIntentIndicators(
                            resolvedSecondaryIntent,
                            secondaryKeyword.intentProbabilities || result.intentProbabilities || null
                        );

                        // Find associations for THIS specific secondary keyword (not main keyword)
                        const secondaryKeywordAssociations = getAssociationsForKeyword(secondaryKeyword.keyword);
                        
                        // Secondary keywords use the same URL as main keyword
                        let secondaryUrlCellContent = urlCellContent; // Inherit from main keyword

                        // Secondary keywords use the same page type as main keyword
                        let secondaryPageType = pageType; // Inherit from main keyword

                        // Build dropdown content for secondary keyword (inherits from main keyword)
                        let secondaryDropdownContent = dropdownContent; // Use same dropdown as main keyword

                        // Determine row class for secondary keyword - light green if main has association
                        let secondaryRowClass = `aysa-secondary-keyword-row ${zebraClass}`;
                        let secondaryBorderColor = '#d8e1ec';
                        
                        if (keywordAssociations.length > 0) {
                            secondaryRowClass += ' aysa-secondary-associated';
                        }

                        const safeSecondaryKeyword = escapeHtml(secondaryKeyword.keyword || '');
                        const safeParentKeyword = escapeAttr(result.keyword || '');
                        const secondarySerp = formatSerpFeatures(secondaryKeyword.itemTypes || result.itemTypes);
                        const secondaryTraffic = formatNumber(
                            (secondaryKeyword.traffic !== undefined && secondaryKeyword.traffic !== null && secondaryKeyword.traffic !== '')
                                ? secondaryKeyword.traffic
                                : result.traffic
                        );
                        const secondaryTrafficPct = formatPercentValue(
                            (secondaryKeyword.trafficPct !== undefined && secondaryKeyword.trafficPct !== null && secondaryKeyword.trafficPct !== '')
                                ? secondaryKeyword.trafficPct
                                : result.trafficPct
                        );
                        const secondaryCpc = formatCpcValue(
                            (secondaryKeyword.cpc !== undefined && secondaryKeyword.cpc !== null && secondaryKeyword.cpc !== '')
                                ? secondaryKeyword.cpc
                                : result.cpc
                        );
                        const secondaryUpdated = formatUpdatedAgo(secondaryKeyword.updatedAt || result.updatedAt || result.createdDate);
                        const $secondaryRow = $(`
                            <tr class="${secondaryRowClass}" data-keyword-id="${secondaryKeyword.id || ''}" data-parent-keyword="${safeParentKeyword}" style="border-left: 3px solid ${secondaryBorderColor};">
                                <td class="aysa-keyword-col">
                                    <div class="aysa-secondary-keyword-main">
                                        <div class="aysa-keyword-wrapper">
                                            <span class="aysa-secondary-icon">📌</span>
                                            <span class="aysa-keyword-text">${safeSecondaryKeyword}</span>
                                        </div>
                                    </div>
                                </td>
                                <td class="aysa-intent-col">
                                    <div class="aysa-keyword-indicators">
                                        ${secondaryIntentIndicators}
                                    </div>
                                </td>
                                <td class="aysa-volume-col">${secondaryKeyword.searchVolume !== 'N/A' ? formatNumber(secondaryKeyword.searchVolume) : 'N/A'}</td>
                                <td class="aysa-difficulty-col">${formatDifficulty(secondaryKeyword.difficulty)}</td>
                                <td class="aysa-cpc-col">${secondaryCpc}</td>
                                <td class="aysa-serp-col">${secondarySerp}</td>
                                <td class="aysa-updated-col">${secondaryUpdated}</td>
                                <td class="aysa-traffic-col">${secondaryTraffic}</td>
                                <td class="aysa-traffic-pct-col">${secondaryTrafficPct}</td>
                                <td class="aysa-url-col">${secondaryUrlCellContent}</td>
                                <td class="aysa-page-type-col">${secondaryPageType || '<span class="aysa-page-type aysa-page-type-unknown">-</span>'}</td>
                                <td class="aysa-desired-col">
                                    <div class="aysa-desired-wrapper">
                                        <select class="aysa-desired-position" data-keyword="${secondaryKeyword.keyword}">
                                            <option value="1-3">Position 1-3</option>
                                            <option value="4-10">Position 4-10</option>
                                            <option value="10+">Position 10+</option>
                                        </select>
                                    </div>
                                </td>
                            </tr>
                        `);

                        // If associated, also style the action button to be green AND set desired position
                        if (secondaryKeywordAssociations.length > 0) {
                            $secondaryRow.find('.aysa-action-btn').addClass('aysa-btn-associated');
                            
                            // Find the association for THIS specific secondary keyword
                            const currentSecondaryAssociation = secondaryKeywordAssociations.find(a => 
                                a.keyword.toLowerCase().trim() === secondaryKeyword.keyword.toLowerCase().trim()
                            );
                            
                            // Set desired position dropdown value from the correct association
                            if (currentSecondaryAssociation && currentSecondaryAssociation.desiredPosition) {
                                // Convert number to dropdown value (2 -> "1-3", 7 -> "4-10", 15 -> "10+")
                                let dropdownValue = ''; // default to placeholder
                                if (currentSecondaryAssociation.desiredPosition >= 1 && currentSecondaryAssociation.desiredPosition <= 3) {
                                    dropdownValue = '1-3';
                                } else if (currentSecondaryAssociation.desiredPosition >= 4 && currentSecondaryAssociation.desiredPosition <= 10) {
                                    dropdownValue = '4-10';
                                } else if (currentSecondaryAssociation.desiredPosition > 10) {
                                    dropdownValue = '10+';
                                }
                                
                                console.log(`🎯 Setting desired position for SECONDARY "${secondaryKeyword.keyword}": ${currentSecondaryAssociation.desiredPosition} -> "${dropdownValue}"`);
                                
                                $secondaryRow.find('.aysa-desired-position').val(dropdownValue);
                                $secondaryRow.data('desiredTarget', dropdownValue);
                                $secondaryRow.data('desiredPosition', currentSecondaryAssociation.desiredPosition);
                            }
                        }

                        $tbody.append($secondaryRow);

                    });
                }

                // COMMENTED OUT: Get the current domain and make API call to get optimization score
                // const domain = window.location.hostname;
                // $.ajax({
                //     url: 'http://api.aysa.localhost:8093/api/AysaKeyowrdsTable/score',
                //     type: 'GET',
                //     data: {
                //         domain: domain,
                //         keyword: result.keyword
                //     },
                //     success: function(score) {
                //         const $scoreCell = $row.find('.aysa-score-col');
                //         $scoreCell.html(score);
                //     },
                //     error: function(xhr, status, error) {
                //         const $scoreCell = $row.find('.aysa-score-col');
                //         $scoreCell.html('N/A');
                //         console.error('Failed to get optimization score:', error);
                //     }
                // });

                // COMMENTED OUT: Make API call to get current position and calculate if target is achieved
                // $.ajax({
                //     url: 'http://api.aysa.localhost:8093/api/AysaKeyowrdsTable/rank',
                //     type: 'GET',
                //     data: {
                //         domain: domain,
                //         keyword: result.keyword,
                //         projectId: projectId
                //     },
                //     success: function(response) {
                //         const currentPosition = parseInt(response.rank);
                //         
                //         // Store current position in row data to be used by the on-change handler
                //         $row.data('currentPosition', currentPosition);
                //     },
                //     error: function(xhr, status, error) {
                //         console.error('Failed to get rank:', error);
                //     }
                // });

                // COMMENTED OUT: Make API call to get external links
                // $.ajax({
                //     url: AysaAPI.getEndpointUrl('external_links'),
                //     type: 'GET',
                //     data: {
                //         competitorDomain: result.competitors || domain,
                //         limit: 10
                //     },
                //     success: function(response) {
                //         const $externalLinksCell = $row.find('.aysa-external-col');
                //         $externalLinksCell.html(response.total_links);
                //     },
                //     error: function(xhr, status, error) {
                //         const $externalLinksCell = $row.find('.aysa-external-col');
                //         $externalLinksCell.html('N/A');
                //         console.error('Failed to get backlinks:', error);
                //     }
                // });

                // COMMENTED OUT: Count internal links to eliminate unnecessary fetch calls
                // const $internalLinksCell = $row.find('.aysa-internal-col');
                // const siteHomeUrl = (typeof aysaParams !== 'undefined' && aysaParams.home_url) ? aysaParams.home_url : (window.location.origin + '/');
                // 
                // // Get base host from site home URL
                // const baseUrl = new URL(siteHomeUrl);
                // const baseHost = baseUrl.host;
                // 
                // // Fetch the page content and count internal links
                // fetch(siteHomeUrl)
                //     .then(response => response.text())
                //     .then(html => {
                //         // Create a temporary div to parse the HTML
                //         const parser = new DOMParser();
                //         const doc = parser.parseFromString(html, 'text/html');
                //         
                //         // Get all links
                //         const links = doc.getElementsByTagName('a');
                //         let internalCount = 0;
                //         
                //         // Count internal links
                //         for (let link of links) {
                //             const href = link.getAttribute('href');
                //             if (!href || href === '#') continue;
                //             
                //             try {
                //                 const linkUrl = new URL(href, siteHomeUrl);
                //                 
                //                 // Count links that point to the same host (internal links)
                //                 if (linkUrl.host === baseHost) {
                //                     internalCount++;
                //                 }
                //             } catch (e) {
                //                 // Invalid URL, skip it
                //                 continue;
                //             }
                //         }
                //         
                //         $internalLinksCell.html(internalCount);
                //     })
                //     .catch(error => {
                //         console.error('Failed to fetch page:', error);
                //         $internalLinksCell.html('N/A');
                //     });

                // Restore saved selection if exists
                const savedValue = savedSelections[result.keyword];
                if (savedValue) {
                    $row.find('.aysa-desired-position').val(savedValue);
                }
                
                // Secondary keywords are now included in the main keyword cell HTML above
                console.log(`✅ Main keyword row created with ${group.secondaryKeywords ? group.secondaryKeywords.length : 0} secondary keywords`);
                }
            });

            // Update pagination controls after displaying results
            if (updatePagination) {
                updatePaginationInfo();
                updatePaginationControls();
            }
            syncStickyHeaderOffset();
            
            // ✅ Show loading indicators for keywords without proper intent
            setTimeout(() => {
                const keywordsNeedIntent = dataToDisplay.some(group => {
                    const mainIntent = group.keyword?.intent || group.intent;
                    return !mainIntent || 
                           mainIntent === 'N/A' || 
                           mainIntent === 'Unknown' || 
                           mainIntent === '';
                });
                
                if (keywordsNeedIntent) {
                    // Some keywords need intent, showing loading indicators
                    showIntentLoadingInTable();
                }
            }, 100); // Small delay to ensure DOM is updated
        };

        // Use timeout only for initial load, otherwise process immediately
        if (updatePagination && dataToDisplay.length < 5) {
            setTimeout(processData, 500); // Adăugăm o mică întârziere pentru a permite afișarea indicatorului de loading
        } else {
            processData();
        }
    }

    // Helper function to format numbers
    function formatNumber(number) {
        if (!number || number === 'N/A') return 'N/A';
        return new Intl.NumberFormat().format(number);
    }

    function formatPercentValue(value) {
        if (value === null || value === undefined || value === '' || value === 'N/A') {
            return 'N/A';
        }
        const num = Number(value);
        if (!Number.isFinite(num)) {
            return 'N/A';
        }
        return `${num.toFixed(2)}%`;
    }

    function formatPositionValue(value) {
        if (value === null || value === undefined || value === '' || value === 'N/A') {
            return 'N/A';
        }
        const num = Number(value);
        if (!Number.isFinite(num) || num <= 0) {
            return 'N/A';
        }
        return `#${num.toFixed(2).replace(/\\.00$/, '')}`;
    }

    function formatCpcValue(value) {
        if (value === null || value === undefined || value === '' || value === 'N/A') {
            return '0.00';
        }
        const num = Number(value);
        if (!Number.isFinite(num)) {
            return '0.00';
        }
        return num.toFixed(2);
    }

    function formatUpdatedAgo(value) {
        if (!value || value === 'N/A') {
            return 'N/A';
        }
        const dt = new Date(value.replace(' ', 'T'));
        if (!Number.isFinite(dt.getTime())) {
            return 'N/A';
        }
        const diffMs = Date.now() - dt.getTime();
        if (diffMs < 0) {
            return 'just now';
        }
        const days = Math.floor(diffMs / 86400000);
        if (days < 1) return 'today';
        if (days < 7) return `${days} day${days === 1 ? '' : 's'}`;
        const weeks = Math.floor(days / 7);
        if (weeks < 5) return `${weeks} week${weeks === 1 ? '' : 's'}`;
        const months = Math.floor(days / 30);
        return `${months} month${months === 1 ? '' : 's'}`;
    }

    function formatSerpFeatures(itemTypes) {
        if (!Array.isArray(itemTypes) || itemTypes.length === 0) {
            return 'N/A';
        }
        const maxVisible = 3;
        const visible = itemTypes.slice(0, maxVisible).map(item => {
            const label = escapeHtml(String(item || '').replace(/_/g, ' ').trim());
            return `<span class="aysa-serp-chip">${label}</span>`;
        }).join(' ');
        const rest = itemTypes.length - maxVisible;
        const extra = rest > 0 ? ` <span class="aysa-serp-more">+${rest}</span>` : '';
        return `<div class="aysa-serp-features-wrap">${visible}${extra}</div>`;
    }

    // Helper function to get difficulty class
    function getDifficultyClass(difficulty) {
        if (!difficulty) return '';
        if (difficulty >= 70) return 'high';
        if (difficulty >= 30) return 'medium';
        return 'low';
    }

    // Helper function to detect page type from URL
    function getPageType(url) {
        if (!url || url === 'N/A') {
            return '<span class="aysa-page-type aysa-page-type-unknown">-</span>';
        }
        
        // Convert to lowercase for easier matching
        const lowerUrl = url.toLowerCase();
        
        // Check for WooCommerce product pages
        if (lowerUrl.includes('/product/') || lowerUrl.includes('?post_type=product') || 
            lowerUrl.includes('/shop/') || lowerUrl.match(/\/[^\/]*product[^\/]*\//)) {
            return '<span class="aysa-page-type aysa-page-type-product">Product</span>';
        }
        
        // Check for WooCommerce category pages
        if (lowerUrl.includes('/product-category/') || lowerUrl.includes('?taxonomy=product_cat') ||
            lowerUrl.includes('/category/') || lowerUrl.match(/\/[^\/]*categor[^\/]*\//)) {
            return '<span class="aysa-page-type aysa-page-type-category">Category</span>';
        }
        
        // Default to Page for all other URLs
        return '<span class="aysa-page-type aysa-page-type-page">Page</span>';
    }

    // Helper function to get page type from association type
    function getPageTypeFromAssociation(associationType) {
        switch(associationType) {
            case 'Product':
                return '<span class="aysa-page-type aysa-page-type-product">Product</span>';
            case 'Category':
                return '<span class="aysa-page-type aysa-page-type-category">Category</span>';
            case 'Page':
                return '<span class="aysa-page-type aysa-page-type-page">Page</span>';
            default:
                return '<span class="aysa-page-type aysa-page-type-unknown">-</span>';
        }
    }

    // Helper function to get intent indicators
    // Helper function to format difficulty values
    function formatDifficulty(difficulty) {
        if (!difficulty || difficulty === 'N/A' || difficulty === 'N/A%') {
            return 'N/A';
        }
        
        // If it's a number, add %
        const numValue = parseFloat(difficulty);
        if (!isNaN(numValue)) {
            return numValue + '%';
        }
        
        // If it already has %, return as is
        if (typeof difficulty === 'string' && difficulty.includes('%')) {
            return difficulty;
        }
        
        // Otherwise, assume it's a number and add %
        return difficulty + '%';
    }

    function formatIntentProbabilitiesTooltip(intentProbabilities) {
        if (!intentProbabilities || typeof intentProbabilities !== 'object') {
            return '';
        }
        const keys = ['informational', 'navigational', 'commercial', 'transactional'];
        const parts = [];
        keys.forEach((k) => {
            if (!(k in intentProbabilities)) return;
            const raw = Number(intentProbabilities[k]);
            if (!Number.isFinite(raw)) return;
            const pct = raw > 1 ? raw : raw * 100;
            parts.push(`${k}: ${pct.toFixed(1)}%`);
        });
        return parts.join(' | ');
    }

    function getIntentIndicators(intent, intentProbabilities = null) {
        // Don't show loading for empty, N/A, or Unknown intents - just return empty
        if (!intent || intent === 'N/A' || intent === 'Unknown' || intent === 'unknown') {
            return '';
        }
        
        const indicators = [];
        const intentMap = {
            'commercial': { letter: 'C', class: 'aysa-commercial' },
            'transactional': { letter: 'T', class: 'aysa-transactional' },
            'navigational': { letter: 'N', class: 'aysa-navigational' },
            'informational': { letter: 'I', class: 'aysa-informational' },
            // Add variations for keyword intent formats
            'commercial intent': { letter: 'C', class: 'aysa-commercial' },
            'transactional intent': { letter: 'T', class: 'aysa-transactional' },
            'navigational intent': { letter: 'N', class: 'aysa-navigational' },
            'informational intent': { letter: 'I', class: 'aysa-informational' },
            // Add single-letter mappings for Target keywords
            'target': { letter: '⭐', class: 'aysa-target-intent' }
        };

        const intents = intent.toLowerCase().split(',').map(i => i.trim());
        
        const probTooltip = formatIntentProbabilitiesTooltip(intentProbabilities);
        intents.forEach(i => {
            if (intentMap[i]) {
                const tooltip = probTooltip ? `${i} | ${probTooltip}` : i;
                const indicator = `<span class="aysa-indicator ${intentMap[i].class}" title="${escapeAttr(tooltip)}">${intentMap[i].letter}</span>`;
                indicators.push(indicator);
            } else {
                // Improved fallback - try to match partial intent names
                let matched = false;
                for (const [key, value] of Object.entries(intentMap)) {
                    if (i.includes(key.split(' ')[0]) || key.includes(i)) {
                        const tooltip = probTooltip ? `${i} | ${probTooltip}` : i;
                        const indicator = `<span class="aysa-indicator ${value.class}" title="${escapeAttr(tooltip)}">${value.letter}</span>`;
                        indicators.push(indicator);
                        matched = true;
                        break;
                    }
                }
                
                if (!matched) {
                    // For unrecognized intents, just show nothing instead of a placeholder
                    // This prevents showing "U" for "Unknown" which looks like a loading state
                    console.log(`ℹ️ Unrecognized intent: "${i}" - not displaying indicator`);
                }
            }
        });

        return indicators.join('');
    }

    // Handle sorting
    $('.aysa-keywords-table th').on('click', function() {
        const column = $(this).index();
        const $tbody = $('.aysa-keywords-table tbody');
        const rows = $tbody.find('tr').toArray();
        
        rows.sort((a, b) => {
            const aValue = $(a).find('td').eq(column).text();
            const bValue = $(b).find('td').eq(column).text();
            return aValue.localeCompare(bValue, undefined, { numeric: true });
        });
        
        $tbody.empty().append(rows);
    });

    // Handle filter button
    $('.aysa-filter-btn').on('click', function() {
        // Implement filter functionality
        alert('Filter functionality coming soon!');
    });

    // Handle export button
    $('.aysa-export-btn').on('click', function() {
        // Implement export functionality
        alert('Export functionality coming soon!');
    });

    // Add change handler for desired position dropdown
    $tbody.on('change', '.aysa-desired-position', function() {
        const $select = $(this);
        const $row = $select.closest('tr');
        const keyword = $select.data('keyword');
        const desiredPosition = $select.val();
        
        console.log(`🎯 Desired position changed for "${keyword}": ${desiredPosition}`);
        
        // Find the association for this keyword
        const keywordAssociations = getAssociationsForKeyword(keyword);
        
        if (keywordAssociations.length === 0) {
            console.warn(`⚠️ No association found for keyword "${keyword}". Cannot update desired position.`);
            showNotification(`Cannot set desired position for "${keyword}" - keyword is not associated with any page/product/category.`, 'warning');
            return;
        }
        
        // Use the first association (main one)
        const association = keywordAssociations[0];
        const associationId = association.id;
        
        // Convert position string to number (1-3 -> 2, 4-10 -> 7, 10+ -> 15)
        let positionValue;
        switch(desiredPosition) {
            case '1-3':
                positionValue = 2; // Middle of range
                break;
            case '4-10':
                positionValue = 7; // Middle of range
                break;
            case '10+':
                positionValue = 15; // Beyond 10
                break;
            default:
                positionValue = parseInt(desiredPosition) || null;
        }
        
        // Disable dropdown while updating
        $select.prop('disabled', true);
        
        // Make API call to update desired position
        const apiUrl = `${getApiBaseUrl()}/api/Association/${associationId}/desired-position`;
        
        $.ajax({
            url: apiUrl,
            type: 'PATCH',
            contentType: 'application/json',
            data: JSON.stringify({
                DesiredPosition: positionValue
            }),
            success: function(response) {
                console.log('✅ Desired position updated:', response);
                showNotification(`Desired position for "${keyword}" set to ${desiredPosition}`, 'success');
                
                // Update the association in cache
                if (window.aysaAssociations) {
                    const assocIndex = window.aysaAssociations.findIndex(a => a.id === associationId);
                    if (assocIndex !== -1) {
                        window.aysaAssociations[assocIndex].desiredPosition = positionValue;
                    }
                }
                
                // Store the desired target value in row data
                $row.data('desiredTarget', desiredPosition);
                $row.data('desiredPosition', positionValue);
            },
            error: function(xhr, status, error) {
                console.error('❌ Error updating desired position:', error);
                showNotification(`Error setting desired position for "${keyword}"`, 'error');
                
                // Reset dropdown to previous value if available
                const previousValue = $row.data('desiredTarget');
                if (previousValue) {
                    $select.val(previousValue);
                }
            },
            complete: function() {
                // Re-enable dropdown
                $select.prop('disabled', false);
            }
        });
    });

    // Display keyword gap data
    function displayKeywordGapData(data) {
        const $resultsTable = $('.aysa-results-table table tbody');
        $resultsTable.empty();

        // Remove duplicate keywords from our keywords array
        const uniqueKeywords = [...new Set(data?.rankedKeywords || [])];
        const ourKeywords = uniqueKeywords;
        const ourVolumes = data?.searchVolume || [];
        const competitors = data?.competitors || [];
        const competitorKeywordSets = data?.competitorRankedKeywords || [];
        const competitorVolumes = data?.competitorSearchVolumes || [];

        // Function to format volume numbers with commas
        function formatVolume(volume) {
            return parseInt(volume).toLocaleString();
        }

        // Function to detect page type from URL
        function getPageType(url) {
            if (!url || url === 'N/A') {
                return '<span class="aysa-page-type aysa-page-type-unknown">-</span>';
            }
            
            // Convert to lowercase for easier matching
            const lowerUrl = url.toLowerCase();
            
            // Check for WooCommerce product pages
            if (lowerUrl.includes('/product/') || lowerUrl.includes('?post_type=product') || 
                lowerUrl.includes('/shop/') || lowerUrl.match(/\/[^\/]*product[^\/]*\//)) {
                return '<span class="aysa-page-type aysa-page-type-product">Product</span>';
            }
            
            // Check for WooCommerce category pages
            if (lowerUrl.includes('/product-category/') || lowerUrl.includes('?taxonomy=product_cat') ||
                lowerUrl.includes('/category/') || lowerUrl.match(/\/[^\/]*categor[^\/]*\//)) {
                return '<span class="aysa-page-type aysa-page-type-category">Category</span>';
            }
            
            // Default to Page for all other URLs
            return '<span class="aysa-page-type aysa-page-type-page">Page</span>';
        }

        // Function to display keywords in table
        function displayKeywords(keywords, volumes, isCompetitor = false) {
            $resultsTable.empty();
            if (!keywords || keywords.length === 0) {
                $resultsTable.append(`
                    <tr>
                        <td colspan="2" class="aysa-td-center-padded">
                            No keywords found. Try adjusting your search parameters.
                        </td>
                    </tr>
                `);
                return;
            }

            keywords.forEach((keyword, index) => {
                const searchVolume = volumes[index] || '0';
                $resultsTable.append(`
                    <tr>
                        <td class="aysa-keyword-cell">
                            <a href="#" class="aysa-keyword-link">${keyword || ''}</a>
                            <i class="aysa-external-link"></i>
                        </td>
                        <td class="aysa-volume-cell">${formatVolume(searchVolume)}</td>
                    </tr>
                `);
            });
        }

        // Update competitor tabs
        const $tabButtons = $('.aysa-tab-buttons');
        $tabButtons.empty();
        $tabButtons.append('<button class="aysa-tab-btn active">You</button>');
        
        competitors.forEach((competitor, index) => {
            const domain = new URL(competitor).hostname;
            $tabButtons.append(`
                <button class="aysa-tab-btn" data-competitor-index="${index}">${domain}</button>
            `);
        });

        // Update competitor selector
        const $competitorSelector = $('.aysa-competitor-selector');
        $competitorSelector.empty();
        competitors.forEach((competitor, index) => {
            const domain = new URL(competitor).hostname;
            $competitorSelector.append(`
                <button class="aysa-competitor-btn ${index === 0 ? 'active' : ''}" 
                        data-competitor-index="${index}">${domain}</button>
            `);
        });

        // Initial display of your keywords
        displayKeywords(ourKeywords, ourVolumes);

        // Update domain boxes
        const currentDomain = window.location.hostname;
        $('.aysa-your-domain').text(currentDomain);

        // Update competitor domain boxes
        $('.competitor-box').hide(); // Hide all competitor boxes initially
        competitors.forEach((competitor, index) => {
            const domain = new URL(competitor).hostname;
            $(`.aysa-competitor-domain-${index + 1}`).text(domain);
            $(`.competitor-box:eq(${index})`).show();
        });

        // Function to update Venn diagram for a specific competitor
        function updateVennDiagram(competitorIndex) {
            const competitorKeywords = competitorKeywordSets[competitorIndex] || [];
            const commonKeywords = ourKeywords.filter(keyword => 
                competitorKeywords.includes(keyword)
            );

            const circleSize = 280; // Fixed size for both circles

            if (commonKeywords.length === 0) {
                // No overlap - separate circles
                $('.aysa-venn-left').css({
                    'width': `${circleSize}px`,
                    'height': `${circleSize}px`,
                    'left': 'calc(50% - 240px)',
                    'transform': 'translateX(0)'
                });
                
                $('.aysa-venn-right').css({
                    'width': `${circleSize}px`,
                    'height': `${circleSize}px`,
                    'left': 'calc(50% + 40px)',
                    'transform': 'translateX(0)'
                });
            } else {
                // Has overlap - calculate overlap based on common keywords
                const overlapRatio = commonKeywords.length / Math.max(ourKeywords.length, competitorKeywords.length);
                const overlapDistance = Math.min(120, 60 + (overlapRatio * 80));
                
                $('.aysa-venn-left').css({
                    'width': `${circleSize}px`,
                    'height': `${circleSize}px`,
                    'left': '50%',
                    'transform': `translateX(-${circleSize - overlapDistance}px)`
                });
                
                $('.aysa-venn-right').css({
                    'width': `${circleSize}px`,
                    'height': `${circleSize}px`,
                    'left': '50%',
                    'transform': `translateX(-${overlapDistance}px)`
                });
            }

            // Update legend
            $('.aysa-overlap-legend').empty();
            
            // Your domain legend item
            $('.aysa-overlap-legend').append(`
                <div class="aysa-legend-item">
                    <span class="aysa-checkbox-wrapper">
                        <input type="checkbox" checked class="aysa-checkbox aysa-checkbox-blue">
                        <span class="aysa-checkbox-label"></span>
                    </span>
                    <span class="aysa-domain-name">${currentDomain}</span>
                    <span class="aysa-keyword-count">${ourKeywords.length}</span>
                </div>
            `);

            // Competitor legend item
            const competitorDomain = new URL(competitors[competitorIndex]).hostname;
            $('.aysa-overlap-legend').append(`
                <div class="aysa-legend-item">
                    <span class="aysa-checkbox-wrapper">
                        <input type="checkbox" checked class="aysa-checkbox aysa-checkbox-green">
                        <span class="aysa-checkbox-label"></span>
                    </span>
                    <span class="aysa-domain-name">${competitorDomain}</span>
                    <span class="aysa-keyword-count">${competitorKeywords.length}</span>
                </div>
            `);
        }

        // Initialize with first competitor
        updateVennDiagram(0);

        // Handle tab switching
        $('.aysa-tab-btn').off('click').on('click', function() {
            $('.aysa-tab-btn').removeClass('active');
            $(this).addClass('active');
            
            const competitorIndex = $(this).data('competitor-index');
            if (typeof competitorIndex === 'undefined') {
                // "You" tab
                displayKeywords(ourKeywords, ourVolumes);
            } else {
                // Competitor tab
                const competitorKeywords = competitorKeywordSets[competitorIndex] || [];
                const competitorVols = competitorVolumes[competitorIndex] || [];
                displayKeywords(competitorKeywords, competitorVols, true);
                
                // Update Venn diagram and competitor selector when switching tabs
                $('.aysa-competitor-btn').removeClass('active');
                $(`.aysa-competitor-btn[data-competitor-index="${competitorIndex}"]`).addClass('active');
                updateVennDiagram(competitorIndex);
            }
        });

        // Handle competitor selector for Venn diagram
        $('.aysa-competitor-btn').off('click').on('click', function() {
            $('.aysa-competitor-btn').removeClass('active');
            $(this).addClass('active');
            
            const competitorIndex = $(this).data('competitor-index');
            
            // Update both Venn diagram and tab selection
            updateVennDiagram(competitorIndex);
            $('.aysa-tab-btn').removeClass('active');
            $(`.aysa-tab-btn[data-competitor-index="${competitorIndex}"]`).addClass('active');
            
            // Update keyword display
            const competitorKeywords = competitorKeywordSets[competitorIndex] || [];
            const competitorVols = competitorVolumes[competitorIndex] || [];
            displayKeywords(competitorKeywords, competitorVols, true);
        });
    }

    // Function to update table rows based on associations
    function updateTableRows(associations) {
        console.log('Updating table rows with associations:', associations);
        
        if (!Array.isArray(associations)) {
            console.error('Associations is not an array:', associations);
            return;
        }

        $('.aysa-keywords-table tbody tr').each(function() {
            const $row = $(this);
            const keyword = $row.find('.aysa-keyword-text').text().trim();
            
            // Find associations for this keyword
            const keywordAssociations = associations.filter(a => keywordsEqual(a && a.keyword, keyword));
            
            if (keywordAssociations.length > 0) {
                console.log('Found associations for keyword:', keyword, keywordAssociations);
                // Mark row as associated
                $row.addClass('aysa-row-associated');
                
                // Make action button green
                const $actionBtn = $row.find('.aysa-action-btn');
                $actionBtn.addClass('aysa-btn-associated');
                
                // Update URL column with the first association
                const firstAssociation = keywordAssociations[0];
                let editUrl = '';
                switch(firstAssociation.associatedOn) {
                    case 'Category':
                        editUrl = `${window.location.origin}/wp-admin/term.php?taxonomy=product_cat&tag_ID=${firstAssociation.idIntern}&post_type=product&wp_http_referer=${encodeURIComponent('/wp-admin/edit-tags.php?taxonomy=product_cat&post_type=product')}`;
                        break;
                    case 'Product':
                        editUrl = `${window.location.origin}/wp-admin/post.php?post=${firstAssociation.idIntern}&action=edit`;
                        break;
                    case 'Page':
                        editUrl = `${window.location.origin}/wp-admin/post.php?post=${firstAssociation.idIntern}&action=edit`;
                        break;
                }
                
                if (editUrl) {
                    const $urlCell = $row.find('.aysa-url-col');
                    const safeLinkText = escapeHtml(firstAssociation.value || '');
                    $urlCell.html(`<a href="${editUrl}" class="aysa-url-link">${safeLinkText}</a>`);
                }
                
                // Update Page Type column with association type
                const $pageTypeCell = $row.find('.aysa-page-type-col');
                const pageTypeBadge = `<span class="aysa-page-type aysa-page-type-${firstAssociation.associatedOn.toLowerCase()}">${firstAssociation.associatedOn}</span>`;
                $pageTypeCell.html(pageTypeBadge);
            }
        });
    }
    
    // Helper function to get the target cell based on association type
    function getTargetCell($row, type) {
        switch(type) {
            case 'Category':
                return $row.find('.aysa-category-col');
            case 'Product':
                return $row.find('.aysa-product-col');
            case 'Page':
                return $row.find('.aysa-page-col');
            default:
                return null;
        }
    }
    
    // Handle disassociate button click
    $(document).on('click', '.aysa-disassociate-btn', function(e) {
        e.preventDefault();
        e.stopPropagation();
        
        const $btn = $(this);
        const associationId = $btn.data('association-id');
        const $row = $btn.closest('tr');
        
        // Get keyword - check if it's a secondary keyword disassociation
        let keyword;
        if ($btn.closest('.aysa-secondary-keywords').length > 0) {
            // For secondary keywords, get keyword from the secondary keyword item data attribute
            keyword = $btn.closest('.aysa-secondary-keyword-item').data('keyword');
        } else {
            // For main keywords, get from the main keyword text
            keyword = $row.find('.aysa-keyword-text').text().trim();
        }
        const itemName = $btn.closest('.aysa-associated-item').find('.aysa-item-name').text();
        const itemType = $btn.closest('td').hasClass('aysa-category-col') ? 'Category' :
                        $btn.closest('td').hasClass('aysa-product-col') ? 'Product' : 'Page';
        
        // Pass additional info about whether this is a secondary keyword
        const isSecondaryKeyword = $btn.closest('.aysa-secondary-keywords').length > 0;
        const $targetRow = $btn.closest('tr');
        disassociateKeyword(associationId, keyword, itemName, itemType, isSecondaryKeyword, $targetRow);
    });

    // Function to disassociate keyword
    function disassociateKeyword(associationId, keyword, itemName, itemType, isSecondaryKeyword = false, $targetRow = null) {
        console.log('Disassociating:', {
            associationId: associationId,
            keyword: keyword,
            itemName: itemName,
            itemType: itemType,
            isSecondaryKeyword: isSecondaryKeyword
        });
        
        // Find the row and button before making the API call
        let $row, $actionBtn;
        if (isSecondaryKeyword && $targetRow) {
            // For secondary keywords, use the provided target row
            $row = $targetRow;
            // For secondary keywords, don't update the main action button unless the main keyword has no associations
            const mainKeyword = $row.find('.aysa-keyword-text').text().trim();
            $actionBtn = $row.find('.aysa-action-btn:not(.aysa-secondary-action-btn)'); // Main action button only
        } else {
            // For main keywords, find by keyword text
            $row = $('.aysa-keyword-text').filter(function() {
                return $(this).text().trim() === keyword;
            }).first().closest('tr');
            $actionBtn = $row.find('.aysa-action-btn');
        }
        const $targetCell = getTargetCell($row, itemType);
        
        // Get project ID
        const projectId = getProjectId();
        
        // Build the API URL with optional projectId parameter
        let apiUrl = `${getApiBaseUrl()}/api/Association/${associationId}`;
        if (projectId) {
            apiUrl += `?projectId=${projectId}`;
        }
        
        $.ajax({
            url: apiUrl,
            type: 'DELETE',
            success: function() {
                console.log('Successfully disassociated');
                showNotification(`Success! Keyword "${keyword}" disassociated from ${itemType.toLowerCase()} "${itemName}"`, 'success');
                
                // Update associations locally without reloading table first
                if (window.aysaAssociations) {
                    window.aysaAssociations = window.aysaAssociations.filter(a => a.id !== associationId);
                }
                
                if (isSecondaryKeyword) {
                    // For secondary keywords, only update UI if the main keyword no longer has any associations
                    const mainKeyword = $row.find('.aysa-keyword-text').text().trim();
                    const mainKeywordAssociations = window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, mainKeyword));
                    
                    // Always clear the target cell for the disassociated secondary keyword
                    if ($targetCell) {
                        $targetCell.removeClass('aysa-cell-associated');
                        $targetCell.empty();
                    }
                    
                    // Only update main button and row if main keyword has no associations left
                    if (mainKeywordAssociations.length === 0) {
                        $actionBtn.removeClass('aysa-btn-associated');
                        $row.removeClass('aysa-row-associated');
                        
                        // Reset Page Type column to unknown
                        const $pageTypeCell = $row.find('.aysa-page-type-col');
                        $pageTypeCell.html('<span class="aysa-page-type aysa-page-type-unknown">-</span>');
                    } else {
                        // Main keyword still has associations, update page type with first remaining association
                        const firstAssociation = mainKeywordAssociations[0];
                        const $pageTypeCell = $row.find('.aysa-page-type-col');
                        const pageTypeBadge = `<span class="aysa-page-type aysa-page-type-${firstAssociation.associatedOn.toLowerCase()}">${firstAssociation.associatedOn}</span>`;
                        $pageTypeCell.html(pageTypeBadge);
                    }
                } else {
                    // For main keywords, update UI as before
                    $actionBtn.removeClass('aysa-btn-associated');
                    $row.removeClass('aysa-row-associated');
                    
                    if ($targetCell) {
                        $targetCell.removeClass('aysa-cell-associated');
                        $targetCell.empty();
                    }
                    
                    // Check if there are any remaining associations for this keyword
                    const remainingAssociations = window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, keyword));
                    
                    if (remainingAssociations.length === 0) {
                        // If no more associations, ensure button is not green and reset page type
                        $actionBtn.removeClass('aysa-btn-associated');
                        
                        // Reset Page Type column to unknown
                        const $pageTypeCell = $row.find('.aysa-page-type-col');
                        $pageTypeCell.html('<span class="aysa-page-type aysa-page-type-unknown">-</span>');
                    } else {
                        // If there are remaining associations, update page type with the first one
                        const firstAssociation = remainingAssociations[0];
                        const $pageTypeCell = $row.find('.aysa-page-type-col');
                        const pageTypeBadge = `<span class="aysa-page-type aysa-page-type-${firstAssociation.associatedOn.toLowerCase()}">${firstAssociation.associatedOn}</span>`;
                        $pageTypeCell.html(pageTypeBadge);
                    }
                }
            },
            error: function(xhr, status, error) {
                console.error('Error disassociating:', error);
                showNotification('Error disassociating keyword', 'error');
            }
        });
    }

    // Function to get unassociated keywords
    function getUnassociatedKeywords() {
        const $tbody = $('.aysa-keywords-table tbody');
        const unassociatedKeywords = [];
        
        $tbody.find('tr').each(function() {
            const $row = $(this);
            const keyword = $row.find('.aysa-keyword-text').text().trim();
            const $urlCell = $row.find('.aysa-url-col');
            
            // Check if the URL cell is empty (no association)
            if ($urlCell.is(':empty') || $urlCell.text().trim() === '') {
                unassociatedKeywords.push(keyword);
            }
        });
        
        return unassociatedKeywords;
    }

    // Function to handle keyword deletion
    function handleKeywordBanning(keyword, $row) {
        // Close the dropdown first
        $('.aysa-action-dropdown').removeClass('open');
        
        // Show custom confirmation modal
        showBanConfirmationModal(keyword, $row);
    }

    // Function to handle keyword disassociation
    function handleKeywordDisassociation(keyword, $row) {
        // Show confirmation modal
        if (!confirm(`Are you sure you want to disassociate the keyword "${keyword}"? This will remove all associations for this keyword.`)) {
            return;
        }
        
        // Close the dropdown
        $('.aysa-action-dropdown.open').removeClass('open');
        $('.aysa-secondary-action-dropdown').removeClass('show-dropdown');
        
        // Get action button - check if it's a secondary keyword
        let $actionBtn;
        const isSecondaryKeyword = keyword !== $row.find('.aysa-keyword-text').text().trim();
        
        if (isSecondaryKeyword) {
            // For secondary keywords, find the specific secondary action button
            $actionBtn = $row.find(`.aysa-secondary-keyword-item[data-keyword="${keyword}"] .aysa-action-btn`);
        } else {
            // For main keywords, use the main action button
            $actionBtn = $row.find('.aysa-action-btn:not(.aysa-secondary-action-btn)');
        }
        
        // Change button text and add loading state
        const originalButtonText = $actionBtn.html();
        $actionBtn.html('<span class="dashicons dashicons-update aysa-spinning"></span> Removing...')
            .prop('disabled', true)
            .addClass('aysa-btn-waiting');
        
        // Get all associations for this keyword
        const keywordAssociations = window.aysaAssociations ? 
            window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, keyword)) : [];
        
        if (keywordAssociations.length === 0) {
            showNotification('No associations found for this keyword', 'info');
            // Restore button
            $actionBtn.html(originalButtonText)
                .prop('disabled', false)
                .removeClass('aysa-btn-waiting aysa-btn-associated');
            if (!isSecondaryKeyword) {
                $row.removeClass('aysa-row-associated');
            }
            return;
        }
        
        // Get project ID
        const projectId = getProjectId();
        
        // Delete all associations for this keyword
        const deletePromises = keywordAssociations.map(association => {
            // Build the API URL with optional projectId parameter
            let apiUrl = `${getApiBaseUrl()}/api/Association/${association.id}`;
            if (projectId) {
                apiUrl += `?projectId=${projectId}`;
            }
            
            return fetch(apiUrl, {
                method: 'DELETE'
            });
        });
        
        Promise.all(deletePromises).then(responses => {
            // Check if all deletions were successful
            const allSuccessful = responses.every(response => response.ok);
            
            if (allSuccessful) {
                // Remove associations from local storage
                window.aysaAssociations = window.aysaAssociations.filter(a => a.keyword !== keyword);
                
                // Show success notification
                showNotification(`Keyword "${keyword}" has been disassociated!`, 'success');
                
                // Update UI based on keyword type
                if (isSecondaryKeyword) {
                    // For secondary keywords, use the smart UI update logic we already have
                    const mainKeyword = $row.find('.aysa-keyword-text').text().trim();
                    const mainKeywordAssociations = window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, mainKeyword));
                    
                    // Clear target cells for the disassociated secondary keyword
                    const targetCells = ['aysa-category-col', 'aysa-product-col', 'aysa-page-col'];
                    targetCells.forEach(cellClass => {
                        const $targetCell = $row.find(`.${cellClass}`);
                        // Check if this cell has associations for the disassociated secondary keyword
                        const hasSecondaryKeywordAssociation = keywordAssociations.some(a => {
                            if (cellClass.includes('category')) return a.associatedOn === 'Category';
                            if (cellClass.includes('product')) return a.associatedOn === 'Product';
                            if (cellClass.includes('page')) return a.associatedOn === 'Page';
                            return false;
                        });
                        
                        if (hasSecondaryKeywordAssociation) {
                            // Clear only if no main keyword associations exist for this cell type
                            const cellType = cellClass.includes('category') ? 'Category' : 
                                           cellClass.includes('product') ? 'Product' : 'Page';
                            const mainKeywordHasThisType = mainKeywordAssociations.some(a => a.associatedOn === cellType);
                            
                            if (!mainKeywordHasThisType) {
                                $targetCell.removeClass('aysa-cell-associated').empty();
                            }
                        }
                    });
                    
                    // Only update main button and row if main keyword has no associations left
                    if (mainKeywordAssociations.length === 0) {
                        $row.find('.aysa-action-btn:not(.aysa-secondary-action-btn)').removeClass('aysa-btn-associated');
                        $row.removeClass('aysa-row-associated');
                        
                        // Reset Page Type column to unknown
                        const $pageTypeCell = $row.find('.aysa-page-type-col');
                        $pageTypeCell.html('<span class="aysa-page-type aysa-page-type-unknown">-</span>');
                        
                        // Clear URL cell
                        const $urlCell = $row.find('.aysa-url-col');
                        $urlCell.empty();
                    } else {
                        // Update page type with first remaining association
                        const firstAssociation = mainKeywordAssociations[0];
                        const $pageTypeCell = $row.find('.aysa-page-type-col');
                        const pageTypeBadge = `<span class="aysa-page-type aysa-page-type-${firstAssociation.associatedOn.toLowerCase()}">${firstAssociation.associatedOn}</span>`;
                        $pageTypeCell.html(pageTypeBadge);
                    }
                } else {
                    // For main keywords, update UI as before
                    $row.removeClass('aysa-row-associated');
                    $row.find('.aysa-action-btn').removeClass('aysa-btn-associated');
                    
                    // Clear all target cells
                    const targetCells = ['.aysa-category-col', '.aysa-product-col', '.aysa-page-col', '.aysa-url-col'];
                    targetCells.forEach(cellSelector => {
                        const $targetCell = $row.find(cellSelector);
                        $targetCell.removeClass('aysa-cell-associated').empty();
                    });
                    
                    // Reset Page Type column to unknown
                    const $pageTypeCell = $row.find('.aysa-page-type-col');
                    $pageTypeCell.html('<span class="aysa-page-type aysa-page-type-unknown">-</span>');
                }
                
                // Restore button
                $actionBtn.html(originalButtonText)
                    .removeClass('aysa-btn-waiting aysa-btn-associated')
                    .prop('disabled', false);
                
            } else {
                throw new Error('Some associations could not be deleted');
            }
        }).catch(error => {
            console.error('Error disassociating keyword:', error);
            showNotification(`Error disassociating keyword: ${error.message}`, 'error');
            
            // Restore button
            $actionBtn.html(originalButtonText)
                .removeClass('aysa-btn-waiting')
                .prop('disabled', false);
        });
    }

    // Function to show custom ban confirmation modal
    function showBanConfirmationModal(keyword, $row) {
        // First check if keyword has associations
        const hasAssociations = window.aysaAssociations && 
            window.aysaAssociations.some(a => a.keyword.toLowerCase() === keyword.toLowerCase());
        
        if (hasAssociations) {
            // Show association warning modal instead
            showAssociationWarningModal(keyword);
            return;
        }
        // Create modal HTML
        const modalHtml = `
            <div class="aysa-ban-modal-overlay">
                <div class="aysa-ban-modal">
                    <div class="aysa-ban-modal-header">
                        <h3>Confirm Delete Keyword</h3>
                        <button class="aysa-ban-modal-close">&times;</button>
                    </div>
                    <div class="aysa-ban-modal-body">
                        <div class="aysa-ban-icon">
                            <span class="dashicons dashicons-no-alt"></span>
                        </div>
                        <div class="aysa-ban-message">
                            <p>Are you sure you want to delete the keyword <strong>"${keyword}"</strong>?</p>
                            <p class="aysa-ban-warning">This keyword will be removed from discovery and filtered from future suggestions.</p>
                        </div>
                    </div>
                    <div class="aysa-ban-modal-footer">
                        <button class="aysa-ban-btn-cancel">Cancel</button>
                        <button class="aysa-ban-btn-confirm">Delete Keyword</button>
                    </div>
                </div>
            </div>
        `;
        
        // Add modal to page
        $('body').append(modalHtml);
        
        // Add event handlers
        $('.aysa-ban-modal-close, .aysa-ban-btn-cancel, .aysa-ban-modal-overlay').on('click', function(e) {
            if (e.target === this) {
                $('.aysa-ban-modal-overlay').remove();
            }
        });
        
        // Prevent modal from closing when clicking inside modal content
        $('.aysa-ban-modal').on('click', function(e) {
            e.stopPropagation();
        });
        
        // Handle confirm ban
        $('.aysa-ban-btn-confirm').on('click', function() {
            $('.aysa-ban-modal-overlay').remove();
            proceedWithKeywordBanning(keyword, $row);
        });
        
        // Show modal with animation
        setTimeout(() => {
            $('.aysa-ban-modal-overlay').addClass('aysa-modal-show');
        }, 10);
    }

    // Function to show association warning modal
    function showAssociationWarningModal(keyword) {
        // Count associations for this keyword
        const associationsCount = window.aysaAssociations ? 
            window.aysaAssociations.filter(a => a.keyword.toLowerCase() === keyword.toLowerCase()).length : 0;
        
        // Create warning modal HTML
        const modalHtml = `
            <div class="aysa-association-warning-modal-overlay">
                <div class="aysa-association-warning-modal">
                    <div class="aysa-association-warning-modal-header">
                        <div class="aysa-header-icon">
                            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M12 9V13M12 17H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <h3>Cannot Delete Keyword</h3>
                        <span class="aysa-association-warning-modal-close">&times;</span>
                    </div>
                    <div class="aysa-association-warning-modal-body">
                        <div class="aysa-warning-content">
                            <div class="aysa-warning-icon-large">
                                <svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path d="M12 9V13M12 17H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="#ff6b6b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            </div>
                            <div class="aysa-warning-message">
                                <h4>To delete keyword "<span class="aysa-keyword-highlight">${keyword}</span>" you must remove all associations first.</h4>
                                <div class="aysa-association-count">
                                    <span class="aysa-count-badge">${associationsCount}</span>
                                    <span class="aysa-count-text">association${associationsCount > 1 ? 's' : ''} found</span>
                                </div>
                                <p class="aysa-instructions">Please use the <strong>"Disassociate"</strong> option to remove all associations, then try deleting again.</p>
                            </div>
                        </div>
                    </div>
                    <div class="aysa-association-warning-modal-footer">
                        <button class="aysa-association-warning-btn-ok">
                            <span>Got it</span>
                        </button>
                    </div>
                </div>
            </div>
        `;
        
        // Add modal to page
        $('body').append(modalHtml);
        
        // Add event handlers
        $('.aysa-association-warning-modal-close, .aysa-association-warning-btn-ok').on('click', function() {
            $('.aysa-association-warning-modal-overlay').remove();
        });
        
        // Close modal when clicking outside
        $('.aysa-association-warning-modal-overlay').on('click', function(e) {
            if (e.target === this) {
                $('.aysa-association-warning-modal-overlay').remove();
            }
        });
        
        // Prevent modal content clicks from closing modal
        $('.aysa-association-warning-modal').on('click', function(e) {
            e.stopPropagation();
        });
        
        // Show modal with animation
        setTimeout(() => {
            $('.aysa-association-warning-modal-overlay').addClass('aysa-modal-show');
        }, 10);
    }

    // Function to proceed with actual keyword banning
    function proceedWithKeywordBanning(keyword, $row) {
        console.log('🚀 FUNCTION START: proceedWithKeywordBanning called for keyword:', keyword);
        
        // Show loading notification
        showNotification('Deleting keyword...', 'loading');
        
        // Note: Backend will block deletion if keyword has associations
        // User will be prompted to manually disassociate first
        
        // Ban the keyword using our WordPress AJAX endpoint
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            data: {
                action: 'aysa_ban_keyword',
                keyword: keyword,
                project_id: getProjectId() || 0,
                                    reason: 'Deleted from keyword discovery',
                nonce: '<?php echo wp_create_nonce("aysa_banned_keywords_nonce"); ?>'
            },
            success: function(response) {
                console.log('🎉 AJAX SUCCESS: Ban keyword response:', response);
                console.log('Response type:', typeof response.success, 'Value:', response.success);
                console.log('Equality check:', response.success === true, 'Truthy check:', !!response.success);
                
                if (response.success === true || response.success === 'true' || response.success == true) {
                    console.log('✅ SUCCESS BRANCH: Delete confirmed by server');
                    showNotification(`Keyword "${keyword}" deleted successfully!`, 'success');
                    
                    // Update banned keywords cache
                    if (bannedKeywordsCache) {
                        bannedKeywordsCache.push(keyword.toLowerCase().trim());
                    }
                    
                    // NOW remove from UI after server confirmation
                    allKeywords = allKeywords.filter(k => k.keyword !== keyword);
                    
                    // Update global keywords array
                    if (window.aysaKeywords) {
                        window.aysaKeywords = window.aysaKeywords.filter(k => k.keyword !== keyword);
                    }
                    
                    // Re-group keywords after deletion to maintain proper structure
                    if (typeof groupKeywordsByAssociation === 'function') {
                        filteredKeywords = groupKeywordsByAssociation(allKeywords);
                    } else {
                        filteredKeywords = allKeywords;
                    }
                    
                    // Remove the row from the table
                    $row.fadeOut(200, function() {
                        $row.remove();
                        
                        // Update pagination if needed
                        if (filteredKeywords.length <= (currentPage - 1) * itemsPerPage && currentPage > 1) {
                            currentPage--;
                        }
                        
                        // Refresh the current page display
                        displayCurrentPage();
                        updatePaginationInfo();
                        updatePaginationControls();
                        
                        // If no keywords left, show empty message
                        if (filteredKeywords.length === 0) {
                            $('.aysa-keywords-table tbody').html('<tr><td colspan="12" class="aysa-empty-message">No keywords found.</td></tr>');
                        }
                    });
                    
                    console.log('✅ SUCCESS BRANCH: Keyword removed from UI after server confirmation');
                    
                } else {
                    console.log('❌ ERROR BRANCH in SUCCESS callback - rolling back UI changes');
                    console.log('response.success is:', response.success, 'Type:', typeof response.success);
                    const errorMsg = response.data || response.message || 'Unknown error';
                    console.log('Error message will be:', errorMsg);
                    showNotification('Failed to delete keyword: ' + errorMsg, 'error');
                    console.error('Ban keyword failed in success callback:', response);
                    
                    // Note: Error occurred - keyword deletion failed
                    console.log('❌ Keyword deletion failed, keyword remains in UI (no rollback needed)');
                    // Since UI update happens only after success, keyword is still visible
                }
            },
            error: function(xhr, status, error) {
                console.log('❌ AJAX ERROR: Delete keyword failed - rolling back UI changes');
                console.error('Error deleting keyword:', error, xhr, status);
                let errorMessage = 'Failed to delete keyword';
                
                if (xhr.responseJSON && xhr.responseJSON.message) {
                    errorMessage = xhr.responseJSON.message;
                } else if (xhr.status === 0) {
                    errorMessage = 'Network error. Please check your connection';
                } else if (xhr.responseText) {
                    errorMessage = 'Server error: ' + xhr.responseText;
                }
                
                showNotification(errorMessage, 'error');
                
                // Note: Error occurred - keyword deletion failed  
                console.log('❌ Keyword deletion failed, keyword remains in UI (no rollback needed)');
                // Since UI update happens only after success, keyword is still visible
            }
        });
    }

    function resolveKeywordContext($sourceRow) {
        let $mainRow = $sourceRow;
        let keyword = '';

        if ($sourceRow.hasClass('aysa-association-detail-row')) {
            keyword = String($sourceRow.data('parent-keyword') || '').trim();
            const $candidateMainRow = $sourceRow.prevAll('tr.aysa-group-main-row').first();
            if ($candidateMainRow.length) {
                $mainRow = $candidateMainRow;
            }
        }

        if (!keyword) {
            keyword = String($mainRow.find('.aysa-keyword-text').first().text() || '').trim();
        }

        if (!keyword) {
            keyword = String($sourceRow.data('keyword') || $sourceRow.data('parent-keyword') || '').trim();
        }

        return { keyword, $mainRow };
    }

    function clearManageDropdownPosition($dropdown) {
        const contentEl = $dropdown.find('.aysa-dropdown-content').get(0);
        if (!contentEl) return;
        contentEl.style.removeProperty('position');
        contentEl.style.removeProperty('left');
        contentEl.style.removeProperty('top');
        contentEl.style.removeProperty('right');
        contentEl.style.removeProperty('z-index');
        contentEl.style.removeProperty('min-width');
    }

    function positionManageDropdown($dropdown) {
        const el = $dropdown.get(0);
        if (!el) return;
        const contentEl = $dropdown.find('.aysa-dropdown-content').get(0);
        if (!contentEl) return;

        const rect = el.getBoundingClientRect();
        const viewportWidth = window.innerWidth || document.documentElement.clientWidth || 1200;
        const contentWidth = Math.max(240, contentEl.offsetWidth || 240);
        let left = rect.left;
        if (left + contentWidth + 12 > viewportWidth) {
            left = Math.max(8, viewportWidth - contentWidth - 12);
        }

        contentEl.style.setProperty('position', 'fixed', 'important');
        contentEl.style.setProperty('left', `${left}px`, 'important');
        contentEl.style.setProperty('top', `${rect.bottom + 6}px`, 'important');
        contentEl.style.setProperty('right', 'auto', 'important');
        contentEl.style.setProperty('z-index', '100050', 'important');
        contentEl.style.setProperty('min-width', `${contentWidth}px`, 'important');
    }

    // Add click handler for action button dropdown
    $(document).on('click', '.aysa-action-btn', function(e) {
        e.preventDefault();
        e.stopPropagation();
        
        // Get the parent dropdown container
        const $dropdown = $(this).closest('.aysa-action-dropdown');
        
        // Reset loading states and close all other open dropdowns first
        $('.aysa-dropdown-content').removeClass('aysa-dropdown-loading aysa-dropdown-processing');
        $('.aysa-dropdown-content a').removeClass('aysa-disabled-link').css({
            'pointer-events': 'auto',
            'opacity': '1',
            'cursor': 'pointer'
        });
        
        // Re-enable all action buttons
        $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
            'pointer-events': 'auto',
            'opacity': '1',
            'cursor': 'pointer',
            'background-color': '',
            'color': ''
        });
        
        $('.aysa-action-dropdown.open').not($dropdown).removeClass('open');
        $('.aysa-secondary-dropdown').remove();
        
        const $sourceRow = $(this).closest('tr');
        const context = resolveKeywordContext($sourceRow);
        const keyword = context.keyword;
        
        // Check if there are any associations for this keyword
        if (window.aysaAssociations && Array.isArray(window.aysaAssociations)) {
            const keywordAssociations = window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, keyword));
            const hasAnyAssociations = keywordAssociations.length > 0;
            
            // Update the dropdown items to highlight those with associations
            const $dropdownContent = $dropdown.find('.aysa-dropdown-content');
            
            // Update dropdown content
            $dropdownContent.find('a').each(function() {
                const $link = $(this);
                const text = $link.text().trim().toLowerCase();
                
                // Remove any existing associated class
                $link.removeClass('dropdown-item-associated');
                
                // Check if this is an association action and if there are associations of this type
                if (text.includes('associate category') && 
                    keywordAssociations.some(a => a.associatedOn === 'Category')) {
                    $link.addClass('dropdown-item-associated');
                } else if (text.includes('associate product') && 
                    keywordAssociations.some(a => a.associatedOn === 'Product')) {
                    $link.addClass('dropdown-item-associated');
                } else if (text.includes('associate page') && 
                    keywordAssociations.some(a => a.associatedOn === 'Page')) {
                    $link.addClass('dropdown-item-associated');
                }
            });
            
        }
        
        // Toggle the open class for this dropdown
        $dropdown.toggleClass('open');

        if ($dropdown.hasClass('aysa-manage-action-dropdown')) {
            if ($dropdown.hasClass('open')) {
                positionManageDropdown($dropdown);
            } else {
                clearManageDropdownPosition($dropdown);
            }
        }
    });
    
    // Close dropdown when clicking outside
    $(document).on('click', function(e) {
        if (!$(e.target).closest('.aysa-action-dropdown').length) {
            $('.aysa-action-dropdown.open').removeClass('open');
            $('.aysa-manage-action-dropdown').each(function() {
                clearManageDropdownPosition($(this));
            });
        }
    });
    
    // Prevent dropdown from closing when clicking inside it
    $(document).on('click', '.aysa-dropdown-content', function(e) {
        e.stopPropagation();
    });

    // Add click handler for association options
    $(document).on('click', '.aysa-dropdown-content a', function(e) {
        e.preventDefault();
        e.stopPropagation();
        
        const $link = $(this);
        const action = $link.text().trim();
        const $sourceRow = $link.closest('tr');
        const context = resolveKeywordContext($sourceRow);
        const $row = context.$mainRow;
        
        // Get keyword - check if it's a secondary keyword action
        let keyword;
        if ($link.closest('.aysa-secondary-dropdown-content').length > 0) {
            // For secondary keywords, get keyword from the secondary keyword item data attribute
            keyword = $link.closest('.aysa-secondary-keyword-item').data('keyword');
        } else {
            keyword = context.keyword;
        }
        
        // Prevent spam clicking - check if any operation is in progress
        if ($link.hasClass('aysa-disabled-link') || $('.aysa-dropdown-loading').length > 0) {
            return;
        }
        
        if (action.includes('Associate') && !action.includes('Category') && !action.includes('Product') && !action.includes('Page')) {
            // Handle standalone Associate (like Associate All Keywords but for single keyword)
            handleSingleKeywordAssociation(keyword, $row);
        } else if (action.includes('Associate')) {
            // Disable all dropdown links and add loading state
            const $mainDropdown = $link.closest('.aysa-dropdown-content');
            $mainDropdown.addClass('aysa-dropdown-loading');
            $mainDropdown.find('a').addClass('aysa-disabled-link').css({
                'pointer-events': 'none',
                'opacity': '0.5',
                'cursor': 'not-allowed'
            });
            
            // Disable all other action buttons in the table while loading items
            $('.aysa-action-btn').not($row.find('.aysa-action-btn')).addClass('aysa-action-disabled').css({
                'pointer-events': 'none',
                'opacity': '0.4',
                'cursor': 'not-allowed',
                'background-color': '#f8f9fa',
                'color': '#6c757d'
            });
            
            // Add loading indicator to the clicked link
            const originalText = $link.text();
            $link.html(`<span class="dashicons dashicons-update aysa-spinning"></span> ${originalText}`);
            
            // Remove any existing secondary dropdowns
            $('.aysa-secondary-dropdown').remove();
            
            // Create secondary dropdown
            const $secondaryDropdown = $('<div class="aysa-secondary-dropdown"></div>');
            const $loadingItem = $('<div class="aysa-loading-item">Loading items...</div>');
            $secondaryDropdown.append($loadingItem);
            
            // Position the secondary dropdown
            $secondaryDropdown.css({
                position: 'absolute',
                left: '-220px',
                top: '0',
                width: '200px',
                backgroundColor: 'white',
                boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
                borderRadius: '4px',
                zIndex: 100000,
                border: '1px solid #ddd'
            });
            
            // Add to the main dropdown container
            $mainDropdown.append($secondaryDropdown);
            
            // Determine which type of items to load
            let type = '';
            if (action.includes('Category')) type = 'Category';
            else if (action.includes('Product')) type = 'Product';
            else if (action.includes('Page')) type = 'Page';
            
            // Load items based on type
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'aysa_get_items',
                    type: type,
                    nonce: '<?php echo wp_create_nonce("aysa_get_items_nonce"); ?>'
                },
                success: function(response) {
                    // Re-enable dropdown links
                    $mainDropdown.removeClass('aysa-dropdown-loading');
                    $mainDropdown.find('a').removeClass('aysa-disabled-link').css({
                        'pointer-events': 'auto',
                        'opacity': '1',
                        'cursor': 'pointer'
                    });
                    
                    // Re-enable all action buttons in the table
                    $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
                        'pointer-events': 'auto',
                        'opacity': '1',
                        'cursor': 'pointer',
                        'background-color': '',
                        'color': ''
                    });
                    
                    // Restore original text
                    $link.text(originalText);
                    
                    if (response.success && response.data) {
                        $secondaryDropdown.empty();
                        
                        // Get current associations for this keyword
                        const currentAssociations = window.aysaAssociations?.filter(a => 
                            keywordsEqual(a && a.keyword, keyword) && a.associatedOn === type
                        ) || [];
                        
                        const itemsList = Array.isArray(response.data) ? response.data.slice() : [];
                        const keywordLowerKey = String(keyword || '').trim().toLowerCase();
                        itemsList.sort((a, b) => {
                            const aKey = `${keywordLowerKey}|${type}|${a.id}`;
                            const bKey = `${keywordLowerKey}|${type}|${b.id}`;
                            const aRecommended = window.aysaGoogleKeywordRecommendations && window.aysaGoogleKeywordRecommendations[aKey] ? 1 : 0;
                            const bRecommended = window.aysaGoogleKeywordRecommendations && window.aysaGoogleKeywordRecommendations[bKey] ? 1 : 0;
                            if (aRecommended !== bRecommended) {
                                return bRecommended - aRecommended;
                            }

                            const aGa4 = getGa4KeywordScore(keywordLowerKey, type, a.id);
                            const bGa4 = getGa4KeywordScore(keywordLowerKey, type, b.id);
                            if (aGa4 !== bGa4) {
                                return bGa4 - aGa4;
                            }
                            return String(a.name || '').localeCompare(String(b.name || ''));
                        });

                        itemsList.forEach(function(item) {
                            const $item = $('<div class="aysa-dropdown-item"></div>');
                            $item.text(item.name);
                            $item.data('id', item.id);
                            $item.data('type', type);
                            
                            // Check if this item is currently associated with this keyword
                            const isAssociated = currentAssociations.some(a => a.idIntern === item.id);
                            if (isAssociated) {
                                $item.addClass('aysa-item-associated');
                            }
                            
                            // Check if this item has any associations with any keywords (mark with yellow)
                            const hasAnyAssociations = window.aysaAssociations?.some(a => 
                                a.associatedOn === type && a.idIntern === item.id
                            );
                            if (hasAnyAssociations && !isAssociated) {
                                $item.addClass('aysa-item-has-associations');
                            }

                            const recKey = `${keywordLowerKey}|${type}|${item.id}`;
                            const recommendation = window.aysaGoogleKeywordRecommendations
                                ? window.aysaGoogleKeywordRecommendations[recKey]
                                : null;
                            if (recommendation) {
                                $item.addClass('aysa-item-google-recommended');
                                $item.prepend('<span class="dashicons dashicons-star-filled aysa-icon-inline aysa-icon-inline--warn"></span>');
                                const roundedClicks = Math.round(Number(recommendation.clicks || 0));
                                $item.attr('title', `Suggested from Google Search Console (${roundedClicks} clicks)`);
                            } else {
                                const ga4Score = getGa4KeywordScore(keywordLowerKey, type, item.id);
                                if (ga4Score > 0) {
                                    const ga4Metric = window.aysaGa4ItemMetrics
                                        ? window.aysaGa4ItemMetrics[`${type}|${item.id}`]
                                        : null;
                                    const sessions = ga4Metric ? Math.round(Number(ga4Metric.sessions || 0)) : 0;
                                    $item.addClass('aysa-item-ga4-recommended');
                                    $item.prepend('<span class="dashicons dashicons-chart-area aysa-icon-inline aysa-icon-inline--teal"></span>');
                                    $item.attr('title', `Suggested from Google Analytics (${sessions} sessions)`);
                                }
                            }
                            
                            // Add click handler for item selection
                            $item.on('click', function() {
                                const $clickedItem = $(this);
                                
                                // Prevent multiple clicks
                                if ($clickedItem.hasClass('aysa-processing')) {
                                    return;
                                }
                                
                                const itemId = $clickedItem.data('id');
                                const itemType = $clickedItem.data('type');
                                const itemName = $clickedItem.text();
                                const isAssociated = $clickedItem.hasClass('aysa-item-associated');
                                
                                // Disable all dropdown options and secondary dropdown items during association
                                $mainDropdown.addClass('aysa-dropdown-processing');
                                $mainDropdown.find('a').addClass('aysa-disabled-link').css({
                                    'pointer-events': 'none',
                                    'opacity': '0.5',
                                    'cursor': 'not-allowed'
                                });
                                
                                // Disable all action buttons in the table
                                $('.aysa-action-btn').not($row.find('.aysa-action-btn')).addClass('aysa-action-disabled').css({
                                    'pointer-events': 'none',
                                    'opacity': '0.4',
                                    'cursor': 'not-allowed',
                                    'background-color': '#f8f9fa',
                                    'color': '#6c757d'
                                });
                                
                                // Disable all secondary dropdown items
                                $secondaryDropdown.find('.aysa-dropdown-item').not($clickedItem).css({
                                    'pointer-events': 'none',
                                    'opacity': '0.3',
                                    'cursor': 'not-allowed'
                                });
                                
                                // Add processing state
                                $clickedItem.addClass('aysa-processing');
                                $clickedItem.css('pointer-events', 'none');
                                
                                // Add loading indicator
                                const originalText = $clickedItem.text();
                                $clickedItem.html(`<span class="dashicons dashicons-update aysa-spinning"></span> ${isAssociated ? 'Removing...' : 'Adding...'}`);
                                
                                if (isAssociated) {
                                    showNotification(`"${keyword}" is already linked to this ${itemType.toLowerCase()}.`, 'info');

                                    $mainDropdown.removeClass('aysa-dropdown-processing');
                                    $mainDropdown.find('a').removeClass('aysa-disabled-link').css({
                                        'pointer-events': 'auto',
                                        'opacity': '1',
                                        'cursor': 'pointer'
                                    });

                                    $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
                                        'pointer-events': 'auto',
                                        'opacity': '1',
                                        'cursor': 'pointer',
                                        'background-color': '',
                                        'color': ''
                                    });

                                    $secondaryDropdown.find('.aysa-dropdown-item').css({
                                        'pointer-events': 'auto',
                                        'opacity': '1',
                                        'cursor': 'pointer'
                                    });

                                    $clickedItem.text(originalText);
                                    $clickedItem.removeClass('aysa-processing');
                                    $clickedItem.css('pointer-events', 'auto');
                                } else {
                                    // Get project ID
                                    const projectId = getProjectId();
                                    
                                    // Create association object
                                    const association = {
                                        keyword: keyword,
                                        associatedOn: itemType,
                                        idIntern: itemId,
                                        value: itemName
                                    };
                                    
                                    // Add projectId if available
                                    if (projectId) {
                                        association.projectId = parseInt(projectId);
                                    }
                                    
                                    // Send association to server
                                    $.ajax({
                                        url: `${getApiBaseUrl()}/api/Association/upsert`,
                                        type: 'PUT',
                                        contentType: 'application/json',
                                        data: JSON.stringify(association),
                                        success: function(response) {
                                            showNotification(`Successfully associated "${keyword}" with ${itemType.toLowerCase()} "${itemName}"`, 'success');
                                            
                                            // Re-enable all dropdown options
                                            $mainDropdown.removeClass('aysa-dropdown-processing');
                                            $mainDropdown.find('a').removeClass('aysa-disabled-link').css({
                                                'pointer-events': 'auto',
                                                'opacity': '1',
                                                'cursor': 'pointer'
                                            });
                                            
                                            // Re-enable all action buttons in the table
                                            $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
                                                'pointer-events': 'auto',
                                                'opacity': '1',
                                                'cursor': 'pointer',
                                                'background-color': '',
                                                'color': ''
                                            });
                                            
                                            // Update UI
                                            const $urlCell = $row.find('.aysa-url-col');
                                            let editUrl = '';
                                            
                                            switch(itemType) {
                                                case 'Category':
                                                    editUrl = `${window.location.origin}/wp-admin/term.php?taxonomy=product_cat&tag_ID=${itemId}&post_type=product&wp_http_referer=${encodeURIComponent('/wp-admin/edit-tags.php?taxonomy=product_cat&post_type=product')}`;
                                                    break;
                                                case 'Product':
                                                case 'Page':
                                                    editUrl = `${window.location.origin}/wp-admin/post.php?post=${itemId}&action=edit`;
                                                    break;
                                            }
                                            
                                            if (editUrl) {
                                                const safeItemName = escapeHtml(itemName || '');
                                                $urlCell.html(`<a href="${editUrl}" class="aysa-url-link">${safeItemName}</a>`);
                                            }
                                            
                                            // Update Page Type column with association type
                                            const $pageTypeCell = $row.find('.aysa-page-type-col');
                                            const pageTypeBadge = `<span class="aysa-page-type aysa-page-type-${itemType.toLowerCase()}">${itemType}</span>`;
                                            $pageTypeCell.html(pageTypeBadge);
                                            
                                            // Mark row as associated
                                            $row.addClass('aysa-row-associated');
                                            $row.find('.aysa-action-btn').addClass('aysa-btn-associated');
                                            
                                            // Update the item styling
                                            $clickedItem.addClass('aysa-item-associated');
                                            $clickedItem.removeClass('aysa-item-has-associations'); // Remove yellow since it's now green
                                            
                                            // Close dropdowns
                                            $('.aysa-secondary-dropdown').remove();
                                            $('.aysa-action-dropdown').removeClass('open');
                                            
                                            // Update associations without reloading the table
                                            if (!window.aysaAssociations) {
                                                window.aysaAssociations = [];
                                            }
                                            
                                            // Add new association to the local array
                                            window.aysaAssociations.push({
                                                keyword: keyword,
                                                associatedOn: itemType,
                                                idIntern: itemId,
                                                value: itemName,
                                                id: response.id || Date.now() // Use response ID or fallback
                                            });

                                            const candidateItem = {
                                                type: itemType,
                                                id: itemId,
                                                name: itemName
                                            };
                                            propagateAssociationToSemanticCluster(projectId, keyword, candidateItem)
                                                .then(clusterResult => {
                                                    if (clusterResult.created > 0) {
                                                        showNotification(
                                                            `Cluster semantic: ${clusterResult.created} variante asociate automat la aceeasi pagina`,
                                                            'info'
                                                        );
                                                    }
                                                    if (clusterResult.failed > 0) {
                                                        showNotification(
                                                            `Cluster semantic: ${clusterResult.failed} variante nu au putut fi asociate`,
                                                            'warning'
                                                        );
                                                    }
                                                })
                                                .catch(() => {});
                                        },
                                        error: function(xhr, status, error) {
                                            showNotification('Error creating association: ' + error, 'error');
                                            
                                            // Re-enable all dropdown options on error
                                            $mainDropdown.removeClass('aysa-dropdown-processing');
                                            $mainDropdown.find('a').removeClass('aysa-disabled-link').css({
                                                'pointer-events': 'auto',
                                                'opacity': '1',
                                                'cursor': 'pointer'
                                            });
                                            
                                            // Re-enable all action buttons in the table
                                            $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
                                                'pointer-events': 'auto',
                                                'opacity': '1',
                                                'cursor': 'pointer',
                                                'background-color': '',
                                                'color': ''
                                            });
                                            
                                            // Re-enable secondary dropdown items
                                            $secondaryDropdown.find('.aysa-dropdown-item').css({
                                                'pointer-events': 'auto',
                                                'opacity': '1',
                                                'cursor': 'pointer'
                                            });
                                            
                                            // Reset item state on error
                                            $clickedItem.text(originalText);
                                            $clickedItem.removeClass('aysa-processing');
                                            $clickedItem.css('pointer-events', 'auto');
                                        }
                                    });
                                }
                            });
                            
                            $secondaryDropdown.append($item);
                        });
                    } else {
                        $secondaryDropdown.html('<div class="aysa-error-item">Failed to load items</div>');
                    }
                },
                error: function(xhr, status, error) {
                    // Re-enable dropdown links on error
                    $mainDropdown.removeClass('aysa-dropdown-loading');
                    $mainDropdown.find('a').removeClass('aysa-disabled-link').css({
                        'pointer-events': 'auto',
                        'opacity': '1',
                        'cursor': 'pointer'
                    });
                    
                    // Re-enable all action buttons in the table
                    $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
                        'pointer-events': 'auto',
                        'opacity': '1',
                        'cursor': 'pointer',
                        'background-color': '',
                        'color': ''
                    });
                    
                    // Restore original text
                    $link.text(originalText);
                    
                    $secondaryDropdown.html('<div class="aysa-error-item">Failed to load items</div>');
                }
            });
        }
    });

    // Close dropdowns when clicking outside
    $(document).on('click', function(e) {
        if (!$(e.target).closest('.aysa-action-dropdown, .aysa-secondary-dropdown').length) {
            // Reset any loading states before closing
            $('.aysa-dropdown-content').removeClass('aysa-dropdown-loading aysa-dropdown-processing');
            $('.aysa-dropdown-content a').removeClass('aysa-disabled-link').css({
                'pointer-events': 'auto',
                'opacity': '1',
                'cursor': 'pointer'
            });
            
            // Re-enable all action buttons
            $('.aysa-action-btn').removeClass('aysa-action-disabled').css({
                'pointer-events': 'auto',
                'opacity': '1',
                'cursor': 'pointer',
                'background-color': '',
                'color': ''
            });
            
            $('.aysa-action-dropdown.open').removeClass('open');
            $('.aysa-secondary-dropdown').remove();
            $('.aysa-manage-action-dropdown').each(function() {
                clearManageDropdownPosition($(this));
            });
        }
    });

    $(window).on('resize scroll', function() {
        $('.aysa-manage-action-dropdown.open').each(function() {
            positionManageDropdown($(this));
        });
    });

    // Add styles for secondary dropdown
    const styles = `
    .aysa-secondary-dropdown {
        background: white;
        border: 1px solid #ddd;
        border-radius: 4px;
        max-height: 300px;
        overflow-y: auto;
        position: absolute !important;
        z-index: 100000 !important;
    }

    .aysa-dropdown-item {
        padding: 8px 12px;
        cursor: pointer;
        border-bottom: 1px solid #eee;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .aysa-dropdown-item:last-child {
        border-bottom: none;
    }

    .aysa-dropdown-item:hover {
        background-color: #f5f5f5;
    }

    .aysa-dropdown-item.aysa-item-associated {
        background-color: #e8f5e9;
        color: #2e7d32;
        font-weight: 500;
    }

    .aysa-dropdown-item.aysa-item-associated:hover {
        background-color: #c8e6c9;
    }

    .aysa-dropdown-item.aysa-item-has-associations {
        background-color: #fff3cd;
        color: #856404;
        font-weight: 500;
    }

    .aysa-dropdown-item.aysa-item-has-associations:hover {
        background-color: #ffeaa7;
    }

    .aysa-dropdown-item.aysa-processing {
        background-color: #f8f9fa !important;
        color: #6c757d !important;
        cursor: not-allowed !important;
        opacity: 0.8;
    }

    .aysa-dropdown-item.aysa-processing .dashicons {
        animation: aysa-spin 1s linear infinite;
        margin-right: 5px;
    }

    .aysa-loading-item,
    .aysa-error-item {
        padding: 8px 12px;
        color: #666;
        font-style: italic;
    }

    .aysa-error-item {
        color: #dc3545;
    }

    .aysa-action-dropdown {
        position: relative;
    }

    .aysa-dropdown-content {
        position: absolute;
        right: 0;
        top: 100%;
        z-index: 99999;
        background-color: white;
        box-shadow: 0 4px 12px rgba(0,0,0,0.2);
        border: 1px solid #ddd;
        min-width: 200px;
        border-radius: 4px;
        display: none;
        overflow: visible !important;
    }

    .aysa-action-dropdown.open .aysa-dropdown-content {
        display: block !important;
    }

    .aysa-dropdown-content a {
        display: block;
        padding: 8px 12px;
        color: #333;
        text-decoration: none;
        border-bottom: 1px solid #eee;
    }

    .aysa-dropdown-content a:last-child {
        border-bottom: none;
    }

    .aysa-dropdown-content a:hover {
        background-color: #f5f5f5;
    }

    .aysa-ban-keyword {
        color: #dc3545 !important;
        border-top: 1px solid #eee;
        margin-top: 4px;
        padding-top: 12px !important;
    }

    .aysa-ban-keyword:hover {
        background-color: #f8d7da !important;
        color: #721c24 !important;
    }

    /* Row deletion state */
    .aysa-row-deleting {
        background-color: #f8d7da !important;
        transition: opacity 0.3s ease;
    }

    .aysa-row-deleting * {
        pointer-events: none !important;
    }

    .aysa-row-deleting td {
        position: relative;
    }

    .aysa-row-deleting td::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: repeating-linear-gradient(
            45deg,
            transparent,
            transparent 4px,
            rgba(220, 53, 69, 0.1) 4px,
            rgba(220, 53, 69, 0.1) 8px
        );
        pointer-events: none;
        z-index: 1;
    }

    /* Loading and processing states for dropdowns */
    .aysa-dropdown-loading {
        position: relative;
    }

    .aysa-dropdown-loading::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(255, 255, 255, 0.8);
        z-index: 1;
        border-radius: 4px;
    }

    .aysa-dropdown-processing {
        position: relative;
    }

    .aysa-dropdown-processing::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(255, 255, 255, 0.9);
        z-index: 1;
        border-radius: 4px;
    }

    .aysa-disabled-link {
        position: relative;
        z-index: 2;
    }

    .aysa-disabled-link:hover {
        background-color: transparent !important;
    }

    /* Enhanced visual feedback for processing items */
    .aysa-dropdown-item.aysa-processing {
        background-color: #f8f9fa !important;
        color: #6c757d !important;
        cursor: not-allowed !important;
        opacity: 0.8;
        position: relative;
    }

    .aysa-dropdown-item.aysa-processing::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(45deg, transparent 25%, rgba(255,255,255,0.5) 25%, rgba(255,255,255,0.5) 50%, transparent 50%, transparent 75%, rgba(255,255,255,0.5) 75%);
        background-size: 20px 20px;
        animation: aysa-loading-stripes 1s linear infinite;
        border-radius: 4px;
    }

    @keyframes aysa-loading-stripes {
        0% {
            background-position: 0 0;
        }
        100% {
            background-position: 20px 0;
        }
    }

    .aysa-dropdown-item.aysa-processing .dashicons {
        animation: aysa-spin 1s linear infinite;
        margin-right: 5px;
        z-index: 1;
        position: relative;
    }

    /* Disabled action buttons */
    .aysa-action-btn.aysa-action-disabled {
        position: relative;
        transition: all 0.2s ease;
    }

    .aysa-action-btn.aysa-action-disabled:hover {
        background-color: #f8f9fa !important;
        color: #6c757d !important;
    }

    .aysa-action-btn.aysa-action-disabled::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: repeating-linear-gradient(
            45deg,
            transparent,
            transparent 4px,
            rgba(0,0,0,0.05) 4px,
            rgba(0,0,0,0.05) 8px
        );
        border-radius: 4px;
        pointer-events: none;
    }

    /* Visual feedback for processing state */
    .aysa-action-btn.aysa-action-disabled {
        box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
        border-color: #e9ecef;
    }

    /* Multiple associations display */
    .aysa-multiple-associations {
        display: flex;
        flex-direction: column;
        gap: 4px;
        max-height: 80px;
        overflow-y: auto;
    }

    .aysa-multi-association {
        display: flex;
        align-items: center;
        gap: 6px;
        padding: 2px 4px;
        background-color: #f8f9fa;
        border-radius: 3px;
        border-left: 3px solid #e9ecef;
    }

    .aysa-multi-association:nth-child(1) {
        border-left-color: #28a745; /* Green for first */
    }

    .aysa-multi-association:nth-child(2) {
        border-left-color: #17a2b8; /* Blue for second */
    }

    .aysa-multi-association:nth-child(3) {
        border-left-color: #ffc107; /* Yellow for third */
    }

    .aysa-association-type {
        font-size: 12px;
        line-height: 1;
        min-width: 16px;
        text-align: center;
    }

    .aysa-multi-association .aysa-url-link {
        font-size: 12px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        flex-grow: 1;
        min-width: 0;
    }

    .aysa-multi-association:hover {
        background-color: #e9ecef;
    }

    /* Improved tooltip for multiple associations */
    .aysa-multi-association .aysa-url-link[title] {
        position: relative;
    }

    /* Make URL column slightly wider to accommodate multiple associations */
    .aysa-url-col {
        width: 14%; /* Increased from 12% */
    }

    /* Custom Ban Confirmation Modal Styles */
    .aysa-ban-modal-overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.6);
        z-index: 999999;
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        visibility: hidden;
        transition: all 0.3s ease;
    }

    .aysa-ban-modal-overlay.aysa-modal-show {
        opacity: 1;
        visibility: visible;
    }

    .aysa-ban-modal {
        background: white;
        border-radius: 8px;
        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
        max-width: 500px;
        width: 90%;
        max-height: 90vh;
        overflow: hidden;
        transform: scale(0.7) translateY(-50px);
        transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
    }

    .aysa-ban-modal-overlay.aysa-modal-show .aysa-ban-modal {
        transform: scale(1) translateY(0);
    }

    .aysa-ban-modal-header {
        padding: 20px 24px;
        border-bottom: 1px solid #e5e5e5;
        display: flex;
        justify-content: space-between;
        align-items: center;
        background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
    }

    .aysa-ban-modal-header h3 {
        margin: 0;
        font-size: 18px;
        font-weight: 600;
        color: #dc3545;
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .aysa-ban-modal-header h3::before {
        content: "⚠️";
        font-size: 20px;
    }

    .aysa-ban-modal-close {
        background: none;
        border: none;
        font-size: 24px;
        color: #6c757d;
        cursor: pointer;
        padding: 0;
        width: 30px;
        height: 30px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 50%;
        transition: all 0.2s ease;
    }

    .aysa-ban-modal-close:hover {
        background-color: #f8f9fa;
        color: #dc3545;
        transform: scale(1.1);
    }

    .aysa-ban-modal-body {
        padding: 24px;
        display: flex;
        align-items: flex-start;
        gap: 16px;
    }

    .aysa-ban-icon {
        flex-shrink: 0;
        width: 48px;
        height: 48px;
        border-radius: 50%;
        background: linear-gradient(135deg, #ffeaa7 0%, #fdcb6e 100%);
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: 0 4px 12px rgba(253, 203, 110, 0.4);
    }

    .aysa-ban-icon .dashicons {
        color: #e17055;
        font-size: 24px;
        width: 24px;
        height: 24px;
    }

    .aysa-ban-message {
        flex-grow: 1;
    }

    .aysa-ban-message p {
        margin: 0 0 12px 0;
        font-size: 16px;
        line-height: 1.5;
        color: #333;
    }

    .aysa-ban-message p:last-child {
        margin-bottom: 0;
    }

    .aysa-ban-warning {
        font-size: 14px !important;
        color: #6c757d !important;
        font-style: italic;
    }

    .aysa-ban-modal-footer {
        padding: 20px 24px;
        border-top: 1px solid #e5e5e5;
        display: flex;
        justify-content: flex-end;
        gap: 12px;
        background: #f8f9fa;
    }

    .aysa-ban-btn-cancel,
    .aysa-ban-btn-confirm {
        padding: 10px 20px;
        border: none;
        border-radius: 6px;
        font-size: 14px;
        font-weight: 500;
        cursor: pointer;
        transition: all 0.2s ease;
        min-width: 100px;
        position: relative;
        overflow: hidden;
    }

    .aysa-ban-btn-cancel {
        background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
        color: #6c757d;
        border: 1px solid #dee2e6;
    }

    .aysa-ban-btn-cancel:hover {
        background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
        color: #495057;
        transform: translateY(-1px);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }

    .aysa-ban-btn-confirm {
        background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
        color: white;
        box-shadow: 0 4px 12px rgba(220, 53, 69, 0.3);
    }

    .aysa-ban-btn-confirm:hover {
        background: linear-gradient(135deg, #c82333 0%, #bd2130 100%);
        transform: translateY(-2px);
        box-shadow: 0 6px 16px rgba(220, 53, 69, 0.4);
    }

    .aysa-ban-btn-confirm:active {
        transform: translateY(0);
        box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
    }

    /* Button ripple effect */
    .aysa-ban-btn-cancel::before,
    .aysa-ban-btn-confirm::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;
        border-radius: 50%;
        background: rgba(255, 255, 255, 0.3);
        transform: translate(-50%, -50%);
        transition: width 0.3s ease, height 0.3s ease;
    }

    .aysa-ban-btn-cancel:active::before,
    .aysa-ban-btn-confirm:active::before {
        width: 200px;
        height: 200px;
    }

    /* Mobile responsiveness */
    @media (max-width: 768px) {
        .aysa-ban-modal {
            margin: 20px;
            width: calc(100% - 40px);
        }

        .aysa-ban-modal-body {
            padding: 20px;
            flex-direction: column;
            text-align: center;
        }

        .aysa-ban-modal-footer {
            flex-direction: column-reverse;
            gap: 8px;
        }

        .aysa-ban-btn-cancel,
        .aysa-ban-btn-confirm {
            width: 100%;
        }
    }

    /* Improved animation */
    @keyframes aysa-modal-bounce-in {
        0% {
            opacity: 0;
            transform: scale(0.3) translateY(-100px);
        }
        50% {
            opacity: 1;
            transform: scale(1.05) translateY(-10px);
        }
        70% {
            transform: scale(0.9) translateY(0);
        }
        100% {
            opacity: 1;
            transform: scale(1) translateY(0);
        }
    }

    .aysa-ban-modal-overlay.aysa-modal-show .aysa-ban-modal {
        animation: aysa-modal-bounce-in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
    }

    /* Association Warning Modal Styles */
    .aysa-association-warning-modal-overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(15, 23, 42, 0.7);
        backdrop-filter: blur(4px);
        z-index: 10000;
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
        visibility: hidden;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .aysa-association-warning-modal-overlay.aysa-modal-show {
        opacity: 1;
        visibility: visible;
    }

    .aysa-association-warning-modal {
        background: white;
        border-radius: 16px;
        box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.05);
        max-width: 480px;
        width: 90%;
        transform: scale(0.9) translateY(-10px);
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        overflow: hidden;
    }

    .aysa-association-warning-modal-overlay.aysa-modal-show .aysa-association-warning-modal {
        transform: scale(1) translateY(0);
    }

    .aysa-association-warning-modal-header {
        padding: 20px 24px 16px;
        background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
        color: white;
        display: flex;
        align-items: center;
        gap: 12px;
        position: relative;
    }

    .aysa-header-icon {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        background: rgba(255, 255, 255, 0.2);
        border-radius: 8px;
        flex-shrink: 0;
    }

    .aysa-association-warning-modal-header h3 {
        margin: 0;
        font-size: 18px;
        font-weight: 600;
        flex: 1;
    }

    .aysa-association-warning-modal-close {
        font-size: 20px;
        cursor: pointer;
        opacity: 0.8;
        transition: all 0.2s ease;
        color: white;
        background: rgba(255, 255, 255, 0.1);
        border: none;
        padding: 8px;
        border-radius: 6px;
        line-height: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
    }

    .aysa-association-warning-modal-close:hover {
        opacity: 1;
        background: rgba(255, 255, 255, 0.2);
        transform: scale(1.05);
    }

    .aysa-association-warning-modal-body {
        padding: 32px 24px;
    }

    .aysa-warning-content {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 24px;
    }

    .aysa-warning-icon-large {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 80px;
        height: 80px;
        background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
        border-radius: 20px;
        border: 2px solid #fecaca;
    }

    .aysa-warning-message {
        flex: 1;
    }

    .aysa-warning-message h4 {
        margin: 0 0 16px 0;
        font-size: 16px;
        font-weight: 600;
        color: #1f2937;
        line-height: 1.5;
    }

    .aysa-keyword-highlight {
        color: #ef4444;
        font-weight: 700;
        background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
        padding: 2px 6px;
        border-radius: 4px;
        border: 1px solid #fecaca;
    }

    .aysa-association-count {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        margin: 16px 0;
        padding: 12px 16px;
        background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
        border-radius: 12px;
        border: 1px solid #e2e8f0;
    }

    .aysa-count-badge {
        display: flex;
        align-items: center;
        justify-content: center;
        min-width: 24px;
        height: 24px;
        background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
        color: white;
        border-radius: 6px;
        font-size: 12px;
        font-weight: 700;
        padding: 0 6px;
    }

    .aysa-count-text {
        font-size: 14px;
        font-weight: 500;
        color: #64748b;
    }

    .aysa-instructions {
        margin: 16px 0 0 0;
        color: #64748b;
        line-height: 1.6;
        font-size: 14px;
    }

    .aysa-instructions strong {
        color: #1f2937;
        font-weight: 600;
    }

    .aysa-association-warning-modal-footer {
        padding: 20px 24px;
        background: #f8fafc;
        text-align: center;
    }

    .aysa-association-warning-btn-ok {
        background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
        color: white;
        border: none;
        padding: 12px 32px;
        border-radius: 8px;
        cursor: pointer;
        font-size: 14px;
        font-weight: 600;
        transition: all 0.2s ease;
        box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
        display: inline-flex;
        align-items: center;
        gap: 8px;
    }

    .aysa-association-warning-btn-ok:hover {
        background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
        transform: translateY(-1px);
        box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4);
    }

    .aysa-association-warning-btn-ok:active {
        transform: translateY(0);
    }

    @media (max-width: 768px) {
        .aysa-association-warning-modal {
            margin: 20px;
            width: calc(100% - 40px);
    border-radius: 12px;
}

.aysa-gsc-data-clusters {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin-top: 18px;
}

.aysa-gsc-data-clusters.aysa-hidden {
    display: none !important;
}

.aysa-cluster-card {
    border: 1px solid #dbe6f2;
    border-radius: 16px;
    background: #ffffff;
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.04);
    overflow: hidden;
}

.aysa-cluster-card-header {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 20px;
    background: linear-gradient(180deg, #f7fbff 0%, #eef5ff 100%);
    border-bottom: 1px solid #dbe6f2;
}

.aysa-cluster-card-title {
    font-size: 18px;
    font-weight: 800;
    color: #15324b;
    margin: 0;
}

.aysa-cluster-card-meta {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: center;
}

.aysa-cluster-stat {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 999px;
    background: #ffffff;
    border: 1px solid #d7e3ef;
    font-size: 12px;
    color: #466177;
    font-weight: 700;
}

.aysa-cluster-card-body {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
    gap: 18px;
    padding: 18px 20px 20px;
}

.aysa-cluster-keyword-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.aysa-cluster-keyword-row {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) 90px 90px 110px 120px;
    gap: 12px;
    align-items: center;
    padding: 12px 14px;
    border: 1px solid #e6edf5;
    border-radius: 12px;
    background: #fbfdff;
}

.aysa-cluster-keyword-row.is-primary {
    background: #eef6ff;
    border-color: #bfd6f3;
}

.aysa-cluster-keyword-main {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.aysa-cluster-keyword-name {
    font-size: 15px;
    font-weight: 700;
    color: #17324d;
}

.aysa-cluster-keyword-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.aysa-cluster-keyword-cell {
    font-size: 13px;
    color: #425466;
    font-weight: 600;
}

.aysa-cluster-summary {
    border: 1px solid #e6edf5;
    border-radius: 14px;
    background: #f8fbff;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.aysa-cluster-summary-title {
    font-size: 14px;
    font-weight: 800;
    color: #17324d;
}

.aysa-cluster-summary-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.aysa-cluster-summary-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.aysa-cluster-summary-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #6b7f92;
    font-weight: 700;
}

.aysa-cluster-summary-value {
    font-size: 14px;
    color: #17324d;
    font-weight: 700;
}

@media screen and (max-width: 1180px) {
    .aysa-cluster-card-body {
        grid-template-columns: 1fr;
    }
}

@media screen and (max-width: 860px) {
    .aysa-cluster-keyword-row {
        grid-template-columns: 1fr;
    }
}

        .aysa-warning-content {
            gap: 20px;
        }

        .aysa-association-warning-modal-body {
            padding: 24px 20px;
        }

        .aysa-warning-icon-large {
            width: 64px;
            height: 64px;
        }
    }

    /* Secondary Keywords in Same Cell Styling */
    .aysa-main-keyword {
        width: 100%;
        word-wrap: break-word;
        word-break: break-word;
        hyphens: auto;
    }

    .aysa-secondary-keywords {
        margin-top: 8px;
        padding: 8px;
        background: #f8f9fa;
        border-left: 3px solid #ffc107;
        border-radius: 4px;
        overflow: visible !important; /* Crucial for dropdown */
        max-width: 100%;
    }

    .aysa-secondary-label {
        font-size: 11px;
        color: #6c757d;
        font-weight: 600;
        text-transform: uppercase;
        margin-bottom: 6px;
        letter-spacing: 0.5px;
    }

    .aysa-secondary-keyword-item {
        display: flex;
        align-items: flex-start;
        gap: 8px;
        padding: 3px 0;
        border-bottom: 1px solid #e9ecef;
        min-height: 28px;
    }

    .aysa-secondary-keyword-item:last-child {
        border-bottom: none;
    }

    .aysa-secondary-keyword-item .aysa-secondary-icon {
        font-size: 12px;
        margin-top: 2px;
        flex-shrink: 0;
    }

    .aysa-secondary-keyword-item .aysa-secondary-text {
        flex: 1;
        font-size: 12px;
        color: #6c757d;
        font-style: italic;
        word-wrap: break-word;
        word-break: break-word;
        hyphens: auto;
        line-height: 1.3;
        min-width: 0;
        margin-right: 10px; /* Space for action button */
        padding-right: 5px;
    }

    /* Secondary action dropdown customizations */
    .aysa-secondary-action-dropdown .aysa-action-btn {
        font-size: 10px;
        padding: 4px 8px;
        min-width: 50px;
    }

    .aysa-secondary-action-dropdown .aysa-dropdown-content {
        position: absolute;
        top: 100%;
        right: 0;
        z-index: 9999;
        min-width: 160px;
        display: none;
    }

    /* Ensure parent containers don't clip dropdown */
    .aysa-secondary-keywords {
        overflow: visible !important;
    }

    .aysa-keyword-col {
        overflow: visible !important;
        word-wrap: break-word;
        word-break: break-word;
        hyphens: auto;
        max-width: 200px; /* Set reasonable max width */
        vertical-align: top !important;
        line-height: 1.4;
    }

    .aysa-main-keyword {
        overflow: visible !important;
    }

    .aysa-secondary-action-dropdown.show-dropdown .aysa-dropdown-content {
        display: block !important;
    }

    /* New Secondary Keyword Rows Styling */
    .aysa-secondary-keyword-row {
        background-color: #fafbfc;
        border-left: 3px solid #007cba;
        height: 35px; /* Smaller height than main rows */
        font-size: 12px; /* Smaller font size */
    }

    .aysa-secondary-keyword-row td {
        padding: 6px 8px; /* Reduced padding */
        vertical-align: middle;
        font-size: 12px; /* Smaller font for all cells */
    }

    .aysa-secondary-keyword-row:hover {
        background-color: #f0f6fc;
    }

    .aysa-secondary-keyword-row.aysa-associated-keyword {
        border-left-color: #46b450;
        background-color: #f7fcf0;
    }

    .aysa-secondary-keyword-row.aysa-associated-keyword:hover {
        background-color: #eef7e7;
    }

    .aysa-secondary-keyword-main {
        position: relative;
    }

    .aysa-secondary-keyword-main .aysa-keyword-wrapper {
        display: flex;
        align-items: center;
        padding-left: 20px; /* More indentation to show hierarchy */
    }

    .aysa-secondary-keyword-main .aysa-secondary-icon {
        margin-right: 6px;
        color: #007cba;
        font-size: 12px; /* Smaller icon */
    }

    .aysa-secondary-keyword-main .aysa-keyword-text {
        font-size: 12px; /* Smaller text */
        color: #666; /* Lighter color to show it's secondary */
        font-weight: 400; /* Less bold than main */
    }

    /* Smaller elements in secondary rows */
    .aysa-secondary-keyword-row .aysa-intent-indicator {
        font-size: 10px;
        padding: 2px 4px;
    }

    .aysa-secondary-keyword-row .aysa-action-btn {
        font-size: 10px;
        padding: 4px 8px;
        min-height: 24px; /* Smaller button */
    }

    .aysa-secondary-keyword-row .aysa-desired-position {
        font-size: 11px;
        padding: 2px 4px;
        height: 24px; /* Smaller select */
    }

    .aysa-secondary-keyword-row .aysa-page-type {
        font-size: 9px;
        padding: 2px 4px;
    }

    .aysa-secondary-keyword-row .aysa-url-link {
        font-size: 11px;
    }

    /* Secondary keywords count display */
    .aysa-secondary-keywords-count {
        margin-top: 8px;
        padding: 6px 8px;
        background: #f8f9fa;
        border-radius: 4px;
        border-left: 3px solid #007cba;
        font-size: 11px;
        color: #666;
        font-style: italic;
    }

    .aysa-secondary-count-text {
        font-weight: 500;
    }

    /* Intent Indicators Styling for Secondary Keywords - Match main keywords exactly */
    .aysa-secondary-keyword-row .aysa-intent-indicator {
        display: inline-block;
        width: 16px;
        height: 16px;
        border-radius: 50%;
        text-align: center;
        line-height: 16px;
        font-size: 9px;
        font-weight: bold;
        color: white;
        margin-right: 3px;
        vertical-align: middle;
    }

    .aysa-secondary-keyword-row .aysa-commercial {
        background-color: #1e88e5;
    }

    .aysa-secondary-keyword-row .aysa-transactional {
        background-color: #4caf50;
    }

    .aysa-secondary-keyword-row .aysa-navigational {
        background-color: #ff9800;
    }

    .aysa-secondary-keyword-row .aysa-informational {
        background-color: #9c27b0;
    }

    .aysa-secondary-keyword-row .aysa-target-intent {
        background-color: #ffd700;
        color: #333;
    }

    .aysa-secondary-keyword-row .aysa-unknown {
        background-color: #9e9e9e;
        color: #fff;
    }
    `;

    // Add styles to page
    $('<style>').text(styles).appendTo('head');

    // Handle secondary action dropdown positioning
    $(document).on('click', '.aysa-secondary-action-dropdown .aysa-action-btn', function(e) {
        e.preventDefault();
        e.stopPropagation();
        
        const $dropdown = $(this).closest('.aysa-secondary-action-dropdown');
        const $content = $dropdown.find('.aysa-dropdown-content');
        const $btn = $(this);
        
        // Get the secondary keyword for this dropdown
        const secondaryKeyword = $dropdown.closest('.aysa-secondary-keyword-item').data('keyword');
        
        // Check if this dropdown is already open
        const isCurrentlyOpen = $dropdown.hasClass('show-dropdown');
        
        // Close ALL dropdowns first (both main and secondary)
        $('.aysa-action-dropdown').removeClass('show-dropdown');
        $('.aysa-secondary-action-dropdown').removeClass('show-dropdown');
        
        // If it wasn't open, open this one and update content
        if (!isCurrentlyOpen) {
            // Update dropdown content based on associations for this secondary keyword
            if (window.aysaAssociations && Array.isArray(window.aysaAssociations)) {
                const keywordAssociations = window.aysaAssociations.filter(a => keywordsEqual(a && a.keyword, secondaryKeyword));
                const hasAnyAssociations = keywordAssociations.length > 0;
                
                // Update dropdown content
                $content.find('a').each(function() {
                    const $link = $(this);
                    const text = $link.text().trim().toLowerCase();
                    
                    // Remove any existing associated class
                    $link.removeClass('dropdown-item-associated');
                    
                    // Check if this is an association action and if there are associations of this type
                    if (text.includes('associate category') && 
                        keywordAssociations.some(a => a.associatedOn === 'Category')) {
                        $link.addClass('dropdown-item-associated');
                    } else if (text.includes('associate product') && 
                        keywordAssociations.some(a => a.associatedOn === 'Product')) {
                        $link.addClass('dropdown-item-associated');
                    } else if (text.includes('associate page') && 
                        keywordAssociations.some(a => a.associatedOn === 'Page')) {
                        $link.addClass('dropdown-item-associated');
                    }
                });
                
            }
            
            $dropdown.addClass('show-dropdown');
        }
    });
    
    // Also handle main action buttons to close secondary dropdowns
    $(document).on('click', '.aysa-action-btn:not(.aysa-secondary-action-dropdown .aysa-action-btn)', function() {
        $('.aysa-secondary-action-dropdown').removeClass('show-dropdown');
    });
    
    // Hide dropdown when clicking outside
    $(document).on('click', function(e) {
        if (!$(e.target).closest('.aysa-action-dropdown').length) {
            $('.aysa-action-dropdown').removeClass('show-dropdown');
            $('.aysa-secondary-action-dropdown').removeClass('show-dropdown');
        }
    });

    document.addEventListener('DOMContentLoaded', function() {
        const textElement = document.getElementById('aysa-dynamic-text-keyword-discovery-intro');
        const textToType = "Keyword Discovery is about finding the exact words your customers are searching for. This insight is the key to creating perfectly optimized content, driving high-quality traffic to your site, and boosting your search engine visibility. Ready to uncover the keywords that will grow your business? Let's get started!";
        let currentIndex = 0;
        const typingSpeed = 30;
        function typeWriter() {
            if (textElement && currentIndex < textToType.length) {
                textElement.innerHTML += textToType.charAt(currentIndex);
                currentIndex++;
                setTimeout(typeWriter, typingSpeed);
            } else if (textElement) {
                textElement.classList.add('typing-done');
            }
        }
        if (textElement) {
            textElement.innerHTML = '';
            typeWriter();
        }
    });

    // Handle single keyword association (standalone Associate button)
    function handleSingleKeywordAssociation(keyword, $row) {
        const $actionBtn = $row.find('.aysa-action-btn');
        
        // Prevent spam clicking - check if button is already processing
        if ($actionBtn.hasClass('aysa-btn-waiting') || $actionBtn.prop('disabled')) {
            return;
        }
        
        // Close any open dropdowns
        $('.aysa-action-dropdown.open').removeClass('open');
        
        // Change button to show only processing icon during association
        $actionBtn.html(`<span class="dashicons dashicons-update aysa-spinning"></span>`)
            .prop('disabled', true)
            .addClass('aysa-btn-waiting aysa-btn-pulsing');
        
        // Show processing notification
        showNotification(`Processing association for "${keyword}"...`, 'loading');
        
        // Use the existing generateKeywordAssociations function for single keyword
        generateKeywordAssociations([keyword]).then((result) => {
            // Show success notification
            showNotification(`Keyword "${keyword}" has been associated!`, 'success');
            
            // Update button to show only success icon briefly
            $actionBtn.html(`<span class="dashicons dashicons-yes"></span>`)
                .removeClass('aysa-btn-waiting aysa-btn-pulsing')
                .addClass('aysa-btn-success');
            
            // Reset button after 2 seconds
            setTimeout(() => {
                $actionBtn.html('Manage Association')
                    .prop('disabled', false)
                    .removeClass('aysa-btn-success');
            }, 2000);
            
            // Update stored associations if result contains them
            if (result && result.createdAssociations) {
                if (!window.aysaAssociations) {
                    window.aysaAssociations = [];
                }
                window.aysaAssociations = window.aysaAssociations.concat(result.createdAssociations);
            }
            
        }).catch(error => {
            // If error occurs, restore the button
            console.error('Error associating keyword:', error);
            showNotification(`Error associating keyword: ${error.message}`, 'error');
            
            $actionBtn.html('Manage Association')
                .prop('disabled', false)
                .removeClass('aysa-btn-waiting aysa-btn-pulsing');
        });
    }

    // Handle deleted keywords link click for auto-tab activation
    $('.aysa-banned-keywords-link').on('click', function(e) {
        // Set localStorage to auto-activate deleted keywords tab
        if (typeof(Storage) !== "undefined") {
            localStorage.setItem('aysa_auto_activate_tab', 'banned-keywords');
        }
        // Let the link navigate normally
    });
});
</script>
