/**
 * Newsroom OS (v1.9.0) - Client Side Logic (Global i18n & Local AI Decision Engine)
 * Event-Driven Performance Update, Smart FAQ Engine, Inception Fixes
 */

function nrosIsBlockEditor() {
    if (!jQuery('body').hasClass('block-editor-page')) {
        return false;
    }
    try {
        return !!(window.wp && wp.data && wp.data.select('core/block-editor'));
    } catch (e) {
        return false;
    }
}

function nrosGetTitle() {
    if (nrosIsBlockEditor()) {
        try {
            var editor = wp.data.select('core/editor');
            if (editor) {
                var t = editor.getEditedPostAttribute('title');
                if (t) {
                    return t;
                }
            }
        } catch (e) {}
    }
    return jQuery("#title").val() || jQuery(".wp-block-post-title").text() || jQuery(".editor-post-title__input").val() || "";
}

function nrosGetContent() {
    if (nrosIsBlockEditor()) {
        try {
            var editor = wp.data.select('core/editor');
            if (editor && typeof editor.getEditedPostContent === 'function') {
                var c = editor.getEditedPostContent();
                if (c) {
                    return c;
                }
            }
        } catch (e) {}
    }
    if (typeof tinymce !== 'undefined' && tinymce.activeEditor && !tinymce.activeEditor.isHidden()) {
        return tinymce.activeEditor.getContent();
    }
    return jQuery("#content").val() || "";
}

function nrosCopyToClipboard(text, btnElement, originalText) {
    if (navigator.clipboard && window.isSecureContext) {
        navigator.clipboard.writeText(text).then(() => {
            if(btnElement) { btnElement.text('✅'); setTimeout(() => { btnElement.html(originalText); }, 2000); }
        }).catch(() => { nrosFallbackCopy(text, btnElement, originalText); });
    } else { nrosFallbackCopy(text, btnElement, originalText); }
}

function nrosFallbackCopy(text, btnElement, originalText) {
    let textArea = document.createElement("textarea");
    textArea.value = text;
    textArea.style.top = "0"; textArea.style.left = "0"; textArea.style.position = "fixed";
    document.body.appendChild(textArea);
    textArea.focus(); textArea.select();
    try { document.execCommand('copy'); if(btnElement) btnElement.text('✅'); } catch (err) { }
    document.body.removeChild(textArea);
    if(btnElement) { setTimeout(() => { btnElement.html(originalText); }, 2000); }
}

function nrosInsertIntoEditor(html, prependAtTop) {
    if (nrosIsBlockEditor() && typeof wp !== 'undefined' && wp.blocks && wp.data) {
        var blockEditor = wp.data.dispatch('core/block-editor') || wp.data.dispatch('core/editor');
        if (blockEditor && typeof blockEditor.insertBlocks === 'function') {
            var block = wp.blocks.createBlock('core/html', { content: html });
            if (prependAtTop) {
                blockEditor.insertBlocks([block], 0, undefined, false);
            } else {
                blockEditor.insertBlocks([block]);
            }
            return;
        }
    }
    if (typeof tinymce !== 'undefined' && tinymce.activeEditor && !tinymce.activeEditor.isHidden()) {
        if (prependAtTop) {
            tinymce.activeEditor.setContent(html + tinymce.activeEditor.getContent());
        } else {
            tinymce.activeEditor.execCommand('mceInsertContent', false, html);
        }
        return;
    }
    var $content = jQuery('#content');
    if (prependAtTop) {
        $content.val(html + '\n\n' + $content.val());
    } else {
        $content.val($content.val() + '\n\n' + html);
    }
}

function nrosCountLiveHeadings(content) {
    content = String(content || '');
    var n = 0;
    var re = /<h([23])\b[^>]*>/gi;
    var m;
    while ((m = re.exec(content)) !== null) {
        n++;
    }
    var re2 = /"level"\s*:\s*([23])\b/g;
    while ((m = re2.exec(content)) !== null) {
        n++;
    }
    return n;
}

function nrosInsertLiveUpdateBlock() {
    var d = new Date();
    var hh = String(d.getHours()).padStart(2, '0');
    var mm = String(d.getMinutes()).padStart(2, '0');
    var headingText = hh + ':' + mm + ' — ' + (typeof __ === 'function'
        ? __('Update', 'newsroom-ai-assistant')
        : 'Update');
    if (nrosIsBlockEditor() && typeof wp !== 'undefined' && wp.blocks && wp.data) {
        try {
            var block = wp.blocks.createBlock('core/heading', { level: 3, content: headingText });
            var ed = wp.data.dispatch('core/block-editor');
            if (ed && typeof ed.insertBlocks === 'function') {
                ed.insertBlocks([block]);
                return;
            }
        } catch (e) {}
    }
    nrosInsertIntoEditor('<h3>' + nrosEscHtml(headingText) + '</h3>\n<p></p>');
}

function nrosUpdateBreakingHeadingWarn() {
    var panel = jQuery('#nros-breaking-panel');
    if (!panel.length) {
        return;
    }
    var on = !panel.hasClass('is-idle');
    var warnEl = jQuery('#nros-breaking-heading-warn');
    var okEl = jQuery('#nros-breaking-heading-ok');
    if (!on) {
        warnEl.hide();
        okEl.hide();
        return;
    }
    var n = nrosCountLiveHeadings(nrosGetContent());
    if (n < 1) {
        var warnMsg = panel.data('warn-no-headings');
        if (warnMsg) {
            warnEl.html('⚠️ ' + nrosEscHtml(String(warnMsg)));
        }
        warnEl.show();
        okEl.hide();
    } else {
        warnEl.hide();
        var tpl = panel.data('headings-ok-template') || '%d live update headings in content';
        okEl.text(String(tpl).replace('%d', String(n))).show();
    }
}

function nrosEscHtml(str) {
    return String(str || '')
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}

function nrosIsPlaceholderKeypoint(text) {
    var t = String(text || '').trim();
    if (!t) { return true; }
    return /^(Σημείο|Point)\s*\d+\.{0,3}$/i.test(t);
}

/** Client-side Structure detectors — keep in sync with PHP nros_readiness_content_has_*(). */
function nrosContentHasKeyTakeaways(content) {
    var c = String(content || '');
    if (!c) { return false; }
    if (/(newsai-key-points|nros-geo-summary|editorial-summary|key-takeaways|quick-summary)/i.test(c)) {
        return true;
    }
    return /(Γρήγορη\s+Σύνοψη|Βασικά\s+Σημεία|Key\s+Takeaways|TL;?DR)/i.test(c);
}

function nrosContentHasFaq(content) {
    var c = String(content || '');
    if (!c) { return false; }
    if (/(newsai-faq|schema\.org\/FAQPage|itemtype=["']https?:\/\/schema\.org\/FAQPage)/i.test(c)) {
        return true;
    }
    var faqHeading = /<(h[1-6])[^>]*>[^<]*(FAQ|Συχνές\s+Ερωτήσεις|Frequently\s+Asked)[^<]*<\/\1>/i.test(c);
    var dtCount = (c.match(/<dt\b/gi) || []).length;
    var ddCount = (c.match(/<dd\b/gi) || []).length;
    if (faqHeading && dtCount >= 2 && ddCount >= 2) {
        return true;
    }
    return (c.match(/<dt\b[^>]*>[\s\S]*?<\/dt>\s*<dd\b/gi) || []).length >= 2;
}

function nrosClientCountWords(text) {
    var t = String(text || '').trim();
    if (!t) { return 0; }
    return t.split(/\s+/).filter(Boolean).length;
}

function nrosClientCountExternalLinks(content) {
    var c = String(content || '');
    if (!c) { return 0; }
    var host = '';
    try {
        host = String((typeof newsai_vars !== 'undefined' && newsai_vars.home_url)
            ? newsai_vars.home_url.replace(/^https?:\/\//i, '').replace(/\/.*$/, '')
            : (window.location && window.location.hostname) || '').toLowerCase();
    } catch (eHome) { host = ''; }
    var re = /<a\b[^>]*href=["']([^"']+)["'][^>]*>/gi;
    var m;
    var count = 0;
    while ((m = re.exec(c)) !== null) {
        var href = String(m[1] || '').trim();
        if (!href || href.charAt(0) === '#' || /^mailto:|^tel:/i.test(href)) { continue; }
        if (/^https?:\/\//i.test(href) || /^\/\//.test(href)) {
            try {
                var abs = href.indexOf('//') === 0 ? 'https:' + href : href;
                var linkHost = new URL(abs).hostname.toLowerCase();
                if (!host || (linkHost !== host && linkHost.slice(-(host.length + 1)) !== '.' + host)) {
                    count++;
                }
            } catch (eUrl) {
                count++;
            }
        }
    }
    return count;
}

function nrosClientInformationGainQuick(content, hasTimeline, hasTakeaways) {
    var plain = String(content || '').replace(/<[^>]+>/g, ' ').replace(/[ \t]+/g, ' ').trim();
    var words = nrosClientCountWords(plain);
    var stats = (plain.match(/\b\d{1,3}(?:[.,]\d+)?%?\b/g) || []).length;
    var hasQuotes = /[«""][^«""]{12,}[»""]/.test(plain);
    var score = 0;
    if (words >= 600) { score += 30; }
    else if (words >= 350) { score += 18; }
    else if (words >= 180) { score += 8; }
    if (stats >= 3) { score += 25; }
    else if (stats >= 1) { score += 12; }
    if (hasQuotes) { score += 15; }
    if (hasTimeline) { score += 15; }
    if (hasTakeaways) { score += 15; }
    return { pct: Math.max(0, Math.min(100, score)), word_count: words };
}

function nrosBuildKeypointsHtml(points, titleLabel, aiBadge) {
    var list = '';
    var i;
    var count = 0;
    for (i = 0; i < points.length; i++) {
        var pt = String(points[i] || '').trim();
        if (!pt || nrosIsPlaceholderKeypoint(pt)) { continue; }
        if (pt.slice(-1) !== '.' && pt.slice(-1) !== ';' && pt.slice(-1) !== '·') {
            pt += '.';
        }
        list += '<li class="newsai-key-points__item">' + nrosEscHtml(pt) + '</li>';
        count++;
    }
    if (count < 1) { return ''; }
    var heading = String(titleLabel || '').trim();
    if (!heading) { heading = 'Key Takeaways'; }
    var aria = heading.replace(/[:：]\s*$/, '');
    var html = '<aside class="newsai-key-points" role="note" aria-label="' + nrosEscHtml(aria) + '">';
    html += '<h3 class="newsai-key-points__heading">💡 ' + nrosEscHtml(heading);
    if (aiBadge) {
        html += ' <span class="newsai-key-points__badge">(AI)</span>';
    }
    html += '</h3><ul class="newsai-key-points__list">' + list + '</ul></aside>';
    return html;
}

function nrosBuildKeypointsHtmlLocal(contentText, isGr) {
    var cleanText = contentText.replace(/(💡|Key Takeaways:|Βασικά Σημεία:)/gi, ' ');
    var sentences = cleanText.split(/[.?!;\n:]/).map(function (s) { return s.trim(); }).filter(function (s) {
        return s.length > 40 && s.length < 350;
    });
    var points = [];
    if (sentences.length > 0) {
        sentences.sort(function (a, b) { return b.length - a.length; });
        points.push(sentences[0]);
        if (sentences.length > 1) { points.push(sentences[1]); }
    }
    var title = isGr ? 'Βασικά Σημεία:' : 'Key Takeaways:';
    return nrosBuildKeypointsHtml(points, title, false);
}

function nrosBuildGeoSummaryHtml(data, titleLabel, aiBadge) {
    if (!data || typeof data !== 'object') { return ''; }
    var summary = String(data.summary || '').trim();
    var qa = Array.isArray(data.qa) ? data.qa : [];
    var pairs = [];
    var i;
    for (i = 0; i < qa.length; i++) {
        var row = qa[i] || {};
        var q = String(row.q || row.question || '').trim();
        var a = String(row.a || row.answer || '').trim();
        if (q && a) { pairs.push({ q: q, a: a }); }
        if (pairs.length >= 4) { break; }
    }
    if (!summary && pairs.length < 1) { return ''; }
    var heading = String(data.heading || titleLabel || '').trim() || 'Quick answers';
    var html = '<section class="nros-geo-summary" itemscope itemtype="https://schema.org/FAQPage" aria-labelledby="nros-geo-summary-heading">';
    html += '<h2 id="nros-geo-summary-heading" class="nros-geo-summary__heading">' + nrosEscHtml(heading);
    if (aiBadge) {
        html += ' <span class="nros-geo-summary__badge">(AI)</span>';
    }
    html += '</h2>';
    if (summary) {
        html += '<p class="nros-geo-summary__lead">' + nrosEscHtml(summary) + '</p>';
    }
    if (pairs.length) {
        html += '<div class="nros-geo-summary__qa">';
        for (i = 0; i < pairs.length; i++) {
            html += '<div class="nros-geo-summary__item" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">';
            html += '<h3 class="nros-geo-summary__question" itemprop="name">' + nrosEscHtml(pairs[i].q) + '</h3>';
            html += '<div class="nros-geo-summary__answer" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">';
            html += '<p class="nros-geo-summary__answer-text" itemprop="text">' + nrosEscHtml(pairs[i].a) + '</p></div></div>';
        }
        html += '</div>';
    }
    html += '</section>';
    return html;
}

function nrosBuildFaqHtml(pairs, title) {
    if (!Array.isArray(pairs) || pairs.length === 0) { return ''; }
    var itemsHtml = '';
    var i;
    for (i = 0; i < pairs.length; i++) {
        var q = String((pairs[i] && pairs[i].q) || '').trim();
        var a = String((pairs[i] && pairs[i].a) || '').trim();
        if (!q) { continue; }
        itemsHtml += '<div class="newsai-faq__item" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">';
        itemsHtml += '<strong class="newsai-faq__question" itemprop="name">' + nrosEscHtml(q) + '</strong>';
        if (a) {
            itemsHtml += '<div class="newsai-faq__answer" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">';
            itemsHtml += '<p class="newsai-faq__answer-text" itemprop="text">' + nrosEscHtml(a) + '</p></div>';
        }
        itemsHtml += '</div>';
    }
    if (!itemsHtml) { return ''; }
    var heading = String(title || '').trim() || 'FAQ';
    var html = '<section class="newsai-faq" itemscope itemtype="https://schema.org/FAQPage" aria-labelledby="newsai-faq-heading">';
    html += '<h3 id="newsai-faq-heading" class="newsai-faq__heading">' + nrosEscHtml(heading) + '</h3>';
    html += itemsHtml + '</section>';
    return html;
}

jQuery(document).ready(function($) {
    // gettext bridge for the editor sidebar. wp.i18n is enqueued as a dependency in
    // newsai_enqueue_assets(); translations are loaded per-locale from
    // /languages/json/newsroom-ai-assistant-{locale}-newsai-script.json. Falls back to the
    // English source string if wp-i18n is unavailable (e.g. very old WP, or the script
    // ran before wp-i18n initialized).
    var __ = (typeof wp !== 'undefined' && wp.i18n && typeof wp.i18n.__ === 'function')
        ? function (text) { return wp.i18n.__(text, 'newsroom-ai-assistant'); }
        : function (text) { return text; };
    // Legacy var: a handful of toggles still read it. Pull it from wp.i18n so that the
    // chosen UI locale (el/de/es/en) keeps working with the historical isGr check.
    var isGr = (typeof newsai_vars !== 'undefined' && String(newsai_vars.lang).indexOf('el') !== -1);
    var nrosI18n = (typeof newsai_vars !== 'undefined' && newsai_vars.ui_text) ? newsai_vars.ui_text : {};
    var nrosDiscoverUiMap = (typeof newsai_vars !== 'undefined' && newsai_vars.discover_ui) ? newsai_vars.discover_ui : {};
    /** @param {string} key @param {string} fallback */
    function nrosDiscoverUi(key, fallback) {
        var v = nrosDiscoverUiMap[key];
        return (v !== undefined && v !== null && String(v) !== '') ? String(v) : fallback;
    }
    var nrosFeatures = (typeof newsai_vars !== 'undefined' && newsai_vars.features) ? newsai_vars.features : {};
    function nrosToast(message) {
        const toast = $('<div class="nros-toast"></div>').text(message);
        $('body').append(toast);
        setTimeout(() => { toast.fadeOut(220, () => toast.remove()); }, 1800);
    }
    function nrosRenderRadarSkeleton(targets) {
        const skeletonHtml = [
            '<div class="nros-skeleton-card"><span class="nros-skeleton nros-skeleton-line-sm"></span><span class="nros-skeleton nros-skeleton-line-lg"></span></div>',
            '<div class="nros-skeleton-card"><span class="nros-skeleton nros-skeleton-line-sm"></span><span class="nros-skeleton nros-skeleton-line-lg"></span></div>',
            '<div class="nros-skeleton-card"><span class="nros-skeleton nros-skeleton-line-sm"></span><span class="nros-skeleton nros-skeleton-line-lg"></span></div>'
        ].join('');
        targets.html(skeletonHtml);
    }

    // --- TABS (Index-based Logic) ---
    $(document).on('click', '.newsai-tab', function(e) {
        e.preventDefault();
        var $this = $(this);
        var parentTabs = $this.parent();
        var container = $this.closest('#nros-sb-pane-radar, .nros-radar-panel, .postbox, .nros-sb-card, .newsai-card, .wrap, .newsai-section');
        if (container.length === 0) container = $this.closest('.nros-sb-wrapper');
        if (container.length === 0) container = $this.parent().parent();
        
        var tabIndex = parentTabs.find('.newsai-tab').index($this);
        parentTabs.find('.newsai-tab').removeClass('active');
        $this.addClass('active');
        
        var contents = container.find('.newsai-tab-content');
        contents.hide().attr('hidden', 'hidden');
        var targetPane = contents.eq(tabIndex);
        targetPane.show().removeAttr('hidden');
        
        var isNews = $this.text().toLowerCase().includes('news');
        var isTrends = $this.text().toLowerCase().includes('trend');
        // Match EN "Loading..." and EL "Φόρτωση..." (and skeleton state) — otherwise the
        // NEWS tab never fires fetchNews() on Greek installs.
        var paneText = (targetPane.text() || '').toLowerCase();
        var stillPlaceholder = targetPane.is(':empty')
            || targetPane.find('.nros-radar-idle').length > 0
            || paneText.indexOf('loading') !== -1
            || paneText.indexOf('φόρτωση') !== -1
            || paneText.indexOf('open this section') !== -1
            || paneText.indexOf('tap news') !== -1
            || paneText.indexOf('tap trend') !== -1
            || paneText.indexOf('άνοιξε') !== -1
            || targetPane.find('.nros-skeleton-card').length > 0;

        if (isNews && stillPlaceholder) { fetchNews(); }
        else if (isTrends && stillPlaceholder) { fetchTrends(); }
    });

    $(document).on('change', '#newsai-trends-geo, #newsai-post-geo', function(e) {
        var resolved = nrosResolveEditorGeo();
        if (typeof newsai_vars !== 'undefined') {
            newsai_vars.geo = resolved;
        }
        $('#nros-pane-trends, #nros-pane-news, #newsai-trends-list, #newsai-news-list').removeAttr('data-nros-radar-loaded');
        fetchTrends();
        fetchNews();
    });
    $(document).on('click', '#newsai-refresh-trends', function(e) { e.preventDefault(); fetchTrends(); fetchNews(); });

    function nrosRadarPaneNeedsFetch($pane) {
        if (!$pane || !$pane.length) { return false; }
        if ($pane.attr('data-nros-radar-loaded') === '1') { return false; }
        return $pane.find('.nros-radar-idle').length > 0
            || $pane.find('.nros-skeleton-card').length > 0
            || ($pane.text() || '').toLowerCase().indexOf('loading') !== -1
            || ($pane.text() || '').toLowerCase().indexOf('φόρτωση') !== -1
            || $pane.is(':empty');
    }

    function nrosMaybeFetchRadarTrends() {
        if (nrosFeatures.skip_radar || nrosFeatures.lite_mode) { return; }
        var $pane = $('#nros-pane-trends');
        if ($pane.length && nrosRadarPaneNeedsFetch($pane)) {
            fetchTrends();
            return;
        }
        var $dashTrends = $('#newsai-trends-list');
        if ($dashTrends.length && $dashTrends.is(':visible') && nrosRadarPaneNeedsFetch($dashTrends)) {
            fetchTrends();
        }
    }

    function nrosMaybeFetchRadarFeeds() {
        if (nrosFeatures.skip_radar || nrosFeatures.lite_mode) { return; }
        nrosMaybeFetchRadarTrends();
    }

    $(document).on('toggle', 'details.nros-accordion[data-nros-persist="radar"]', function () {
        if (this.open) { nrosMaybeFetchRadarFeeds(); }
    });

    (function nrosSidebarTabs() {
        var storeKey = 'nros_sb_tab_v2';
        var $tabs = jQuery('.nros-sb-tab');
        if (!$tabs.length) {
            return;
        }
        function showPane(id) {
            id = String(id || 'readiness');
            if (id === 'desk' || id === 'tools') {
                id = 'readiness';
            }
            jQuery('.nros-sb-tab').removeClass('nros-sb-tab--active').attr('aria-selected', 'false');
            jQuery('.nros-sb-tab[data-sb-pane="' + id + '"]').addClass('nros-sb-tab--active').attr('aria-selected', 'true');
            jQuery('.nros-sb-pane').removeClass('nros-sb-pane--active');
            jQuery('#nros-sb-pane-' + id).addClass('nros-sb-pane--active');
            if (id === 'radar') {
                nrosMaybeFetchRadarFeeds();
            }
            if (id === 'readiness' && typeof nrosTriggerUpdate === 'function') {
                nrosTriggerUpdate(true);
            }
        }
        try {
            var stored = localStorage.getItem(storeKey);
            if (stored) {
                showPane(stored);
            }
        } catch (eTab) {}
        jQuery(document).on('click', '.nros-sb-tab', function (e) {
            e.preventDefault();
            var pane = jQuery(this).data('sb-pane');
            showPane(pane);
            try {
                localStorage.setItem(storeKey, pane);
            } catch (eStore) {}
        });
    })();

    // --- AJAX MARK AS DONE ---
    $(document).on('click', '#nros-mark-done-btn', function(e) {
        e.preventDefault();
        var btn = $(this); var taskId = btn.data('id');
        var orgText = btn.html();
        btn.html('⏳...').prop('disabled', true);
        $.post(newsai_vars.ajax_url, { action: 'newsai_mark_task_done', task_id: taskId, nonce: newsai_vars.nonce }, function(response) {
            if (response.success) { btn.closest('div').slideUp(); } else { btn.html(orgText).prop('disabled', false); }
        }).fail(function() { btn.html(orgText).prop('disabled', false); });
    });


    // --- 🚀 THE DECISION ENGINE: PUBLISH CONFIDENCE & NEXT BEST ACTION ---
    let nrosLastEvalHash = '';
    let nrosDiscoverTimer = null;
    let nrosLastFocusForDiscover = { score: 0, actions: [] };
    let nrosLastSavedDiscover = -1;
    let nrosDiscoverSaveTimer = null;
    let nrosDiscoverSaveBusy = false;
    let nrosLastReadinessState = { search: 0, discover: 0, entity: 0, structure: 0, structureActions: [] };
    let nrosLastReadinessComposite = null;
    let nrosLastDiscoverActions = [];

    function nrosClientLargestChunkWords(content) {
        content = String(content || '');
        if (!content.trim()) {
            return 0;
        }
        const marked = content.replace(/<\/?(?:h[1-6]|p|li|section|aside|article|blockquote|div|ul|ol|figure|figcaption|table|tr|td|th|dl|dt|dd|hr|br)\b[^>]*>/gi, '\n\n');
        const text = marked.replace(/<[^>]+>/g, ' ').replace(/[ \t]+/g, ' ').trim();
        const parts = text.split(/\n\s*\n+/).map(function (s) { return s.trim(); }).filter(Boolean);
        let max = 0;
        parts.forEach(function (chunk) {
            const wc = chunk.split(/\s+/).filter(Boolean).length;
            max = Math.max(max, wc);
        });
        return max;
    }

    function nrosClientStructureQuickPack(content) {
        content = String(content || '');
        let score = 0;
        const actions = [];
        const lc = nrosClientLargestChunkWords(content);
        if (lc <= 300) {
            score += 30;
        } else if (lc <= 420) {
            score += 15;
            actions.push({
                prio: 'MEDIUM',
                impact: 7,
                domain: 'structure',
                text: __( 'Largest text block is long — split into shorter paragraphs.', 'newsroom-ai-assistant' )
            });
        } else if (lc > 0) {
            actions.push({
                prio: 'HIGH',
                impact: 3,
                domain: 'structure',
                text: __( 'Largest semantic chunk is too long — break it up for AI extraction.', 'newsroom-ai-assistant' )
            });
        }
        const headings = (content.match(/<h[23]\b/gi) || []).length;
        const lists = (content.match(/<(ul|ol)\b/gi) || []).length;
        const hasTakeaways = nrosContentHasKeyTakeaways(content);
        const hasFaq = nrosContentHasFaq(content);
        const hasGeo = /nros-geo-summary/i.test(content);
        const answerBlocks = headings + lists + (hasFaq ? 2 : 0) + (hasGeo ? 1 : 0);
        if (answerBlocks >= 4) {
            score += 25;
        } else if (answerBlocks >= 2) {
            score += 12;
        }
        const hasTimeline = /\[(newsroom_timeline|nros_timeline)\b/i.test(content)
            || /(newsai-story-cluster|nros-timeline|timeline-item)/i.test(content)
            || nrosIsAutoTimelineOnForCurrentEdit();
        if (hasTimeline) {
            score += 20;
        }
        if (hasTakeaways) {
            score += 15;
        }
        if (hasFaq) {
            score += 10;
        }
        const igQuick = nrosClientInformationGainQuick(content, hasTimeline, hasTakeaways);
        return {
            pct: Math.max(0, Math.min(100, score)),
            actions: actions,
            largest_chunk: lc,
            answer_blocks: answerBlocks,
            answer_target: 4,
            has_timeline: hasTimeline,
            has_takeaways: hasTakeaways,
            has_faq: hasFaq,
            has_geo_summary: hasGeo,
            external_sources: nrosClientCountExternalLinks(content),
            word_count: igQuick.word_count,
            igain_pct: igQuick.pct
        };
    }

    function nrosReadinessScoreColor(pct) {
        pct = parseInt(pct, 10) || 0;
        if (pct >= 80) {
            return '#10b981';
        }
        if (pct >= 55) {
            return '#f59e0b';
        }
        return '#dc2626';
    }

    function nrosPaintReadinessPillar(key, pct) {
        pct = Math.max(0, Math.min(100, parseInt(pct, 10) || 0));
        const color = nrosReadinessScoreColor(pct);
        jQuery('#nros-pillar-' + key + '-val').text(pct + '%').css('color', color);
        jQuery('#nros-pillar-' + key + '-fill').css({ width: pct + '%', background: color });
    }

    function nrosReadinessComposite(search, discover, entity, structure) {
        return Math.round(
            (parseInt(search, 10) || 0) * 0.30
            + (parseInt(discover, 10) || 0) * 0.30
            + (parseInt(entity, 10) || 0) * 0.20
            + (parseInt(structure, 10) || 0) * 0.20
        );
    }

    function nrosPaintReadinessHero(composite) {
        composite = Math.max(0, Math.min(100, parseInt(composite, 10) || 0));
        const color = nrosReadinessScoreColor(composite);
        jQuery('#nros-readiness-score').text(composite + '%').css('color', color);
        const ring = document.getElementById('nros-readiness-ring');
        if (ring && nrosFeatures.circular_gauge !== false) {
            ring.style.background = 'conic-gradient(' + color + ' 0% ' + composite + '%, #e5e7eb ' + composite + '% 100%)';
            if (nrosLastReadinessComposite !== null && nrosLastReadinessComposite !== composite) {
                ring.classList.remove('nros-readiness-ring--pulse');
                void ring.offsetWidth;
                ring.classList.add('nros-readiness-ring--pulse');
            }
            nrosLastReadinessComposite = composite;
        }
        if (jQuery('#nros-readiness-bar').length) {
            jQuery('#nros-readiness-bar').css({ width: composite + '%', background: color });
        }
    }

    function nrosStructureActionsFromPack(structure) {
        if (!structure || !Array.isArray(structure.actions)) {
            return [];
        }
        return structure.actions.slice();
    }

    function nrosMergeReadinessTopActions(focusActions, discoverActions, structureActions, limit) {
        limit = limit || 3;
        const prioRank = { HIGH: 0, MEDIUM: 1, LOW: 2 };
        const merged = (focusActions || []).concat(discoverActions || []).concat(structureActions || []);
        if (!merged.length) {
            return [];
        }
        merged.sort(function (a, b) {
            const pa = prioRank[a.prio] !== undefined ? prioRank[a.prio] : 3;
            const pb = prioRank[b.prio] !== undefined ? prioRank[b.prio] : 3;
            if (pa !== pb) {
                return pa - pb;
            }
            return (a.impact || 0) - (b.impact || 0);
        });
        return merged.slice(0, limit);
    }

    function nrosPaintReadinessTop3(actions) {
        const $list = jQuery('#nros-readiness-top3');
        if (!$list.length) {
            return;
        }
        if (!actions || !actions.length) {
            $list.html(
                '<li><span class="nros-readiness-top3__badge">OK</span><span>'
                + nrosDiscoverUi('great_state_title', 'Great state: ready to publish.')
                + '</span></li>'
            );
            return;
        }
        $list.html(actions.map(function (a, i) {
            const p = String(a.prio || 'LOW').toLowerCase();
            let badgeClass = '';
            if (p === 'high') {
                badgeClass = ' nros-readiness-top3__badge--high';
            } else if (p === 'medium') {
                badgeClass = ' nros-readiness-top3__badge--medium';
            }
            return '<li><span class="nros-readiness-top3__badge' + badgeClass + '">' + (i + 1)
                + '</span><span>' + String(a.text || '') + '</span></li>';
        }).join(''));
    }

    function nrosPaintReadinessEngine(state, focusActions, discoverActions) {
        state = state || nrosLastReadinessState;
        nrosPaintReadinessPillar('search', state.search);
        nrosPaintReadinessPillar('discover', state.discover);
        nrosPaintReadinessPillar('entity', state.entity);
        nrosPaintReadinessPillar('structure', state.structure);
        nrosPaintReadinessHero(nrosReadinessComposite(state.search, state.discover, state.entity, state.structure));
        const top3 = nrosMergeReadinessTopActions(
            focusActions,
            discoverActions,
            state.structureActions || [],
            3
        );
        nrosPaintReadinessTop3(top3);
        const best = top3.length ? top3[0] : null;
        nrosPaintNextActionCard(best, state.search, state.discover, focusActions);
    }

    function nrosUpdateStructureChecklist(structure) {
        if (!structure || !jQuery('#nros-structure-checklist').length) {
            return;
        }
        const ok = '<span style="color:#00a32a;">';
        const bad = '<span style="color:#d63638;">';
        const mid = '<span style="color:#646970;">';
        const lc = parseInt(structure.largest_chunk || 0, 10);
        let chunkLine = mid + __( 'Largest block:', 'newsroom-ai-assistant' ) + '</span> ';
        if (lc <= 300) {
            chunkLine += ok + lc + ' ' + __( 'words', 'newsroom-ai-assistant' ) + '</span>';
        } else if (lc <= 420) {
            chunkLine += mid + lc + ' ' + __( 'words — consider splitting', 'newsroom-ai-assistant' ) + '</span>';
        } else {
            chunkLine += bad + lc + ' ' + __( 'words — split for AI extraction', 'newsroom-ai-assistant' ) + '</span>';
        }
        jQuery('#st-chunk').html('<span class="nros-icon-wrapper">📄</span> <span>' + chunkLine + '</span>');

        const ab = parseInt(structure.answer_blocks || 0, 10);
        const at = parseInt(structure.answer_target || 4, 10);
        let ansLine = mid + __( 'Answer blocks:', 'newsroom-ai-assistant' ) + '</span> ';
        if (ab >= at) {
            ansLine += ok + ab + '/' + at + '</span>';
        } else {
            ansLine += bad + ab + '/' + at + '</span>';
        }
        jQuery('#st-answers').html('<span class="nros-icon-wrapper">❓</span> <span>' + ansLine + '</span>');

        const tlOk = !!(structure.has_timeline);
        jQuery('#st-timeline').html(
            '<span class="nros-icon-wrapper">🕐</span> <span>'
            + (tlOk ? ok + __( 'Timeline / story cluster present', 'newsroom-ai-assistant' ) + '</span>'
                : bad + __( 'No timeline cluster', 'newsroom-ai-assistant' ) + '</span>')
        );
        const tkOk = !!(structure.has_takeaways);
        jQuery('#st-takeaways').html(
            '<span class="nros-icon-wrapper">✅</span> <span>'
            + (tkOk ? ok + __( 'Quick summary / Key Takeaways present', 'newsroom-ai-assistant' ) + '</span>'
                : bad + __( 'Add a quick summary or Key Takeaways block', 'newsroom-ai-assistant' ) + '</span>')
        );
        const faqOk = !!(structure.has_faq);
        jQuery('#st-faq').html(
            '<span class="nros-icon-wrapper">💬</span> <span>'
            + (faqOk ? ok + __( 'FAQ section present', 'newsroom-ai-assistant' ) + '</span>'
                : mid + __( 'No FAQ section yet (optional)', 'newsroom-ai-assistant' ) + '</span>')
        );

        const ext = parseInt(structure.external_sources || (structure.citation && structure.citation.external) || 0, 10);
        const geoOk = !!(structure.has_geo_summary || (structure.citation && structure.citation.has_geo));
        let citLine = mid + __( 'AI Citation:', 'newsroom-ai-assistant' ) + '</span> ';
        if (geoOk && ext >= 2) {
            citLine += ok + ext + ' ' + __( 'sources + GEO summary', 'newsroom-ai-assistant' ) + '</span>';
        } else if (ext >= 1 || geoOk) {
            citLine += mid + ext + ' ' + __( 'sources', 'newsroom-ai-assistant' )
                + (geoOk ? ' · GEO' : '') + '</span>';
        } else {
            citLine += bad + __( 'Add sources & GEO summary', 'newsroom-ai-assistant' ) + '</span>';
        }
        if (jQuery('#st-citation').length) {
            jQuery('#st-citation').html('<span class="nros-icon-wrapper">📚</span> <span>' + citLine + '</span>');
        }

        const wc = parseInt(structure.word_count || (structure.information_gain && structure.information_gain.word_count) || 0, 10);
        const igPct = parseInt(structure.igain_pct || (structure.information_gain && structure.information_gain.pct) || 0, 10);
        let igLine = mid + __( 'Information gain:', 'newsroom-ai-assistant' ) + '</span> ';
        if (igPct >= 70) {
            igLine += ok + wc + ' ' + __( 'words', 'newsroom-ai-assistant' ) + ' · ' + igPct + '%</span>';
        } else if (igPct >= 45) {
            igLine += mid + wc + ' ' + __( 'words', 'newsroom-ai-assistant' ) + ' · ' + igPct + '%</span>';
        } else {
            igLine += bad + wc + ' ' + __( 'words — add depth & data', 'newsroom-ai-assistant' ) + '</span>';
        }
        if (jQuery('#st-igain').length) {
            jQuery('#st-igain').html('<span class="nros-icon-wrapper">📈</span> <span>' + igLine + '</span>');
        }
    }

    function nrosComputeHeadlineDiscoverScore(title, maxPts) {
        const max = typeof maxPts === 'number' ? maxPts : 25;
        let score = 0;
        let penalty = 0;
        const t = String(title || '').trim();
        const len = t.length;
        if (len >= 55 && len <= 70) {
            score += 10;
        } else if (len >= 45 && len <= 80) {
            score += 5;
        } else if (len < 25 || len > 95) {
            penalty += 4;
        }
        const words = t.split(/\s+/).filter(Boolean);
        if (words.length >= 6 && words.length <= 14) {
            score += 3;
        }
        if (/\d/.test(t)) {
            score += 3;
        }
        if (/σήμερα|χθες|χτες|σημερα|σήμερα|today|yesterday|202[4-9]|breaking|live\b/i.test(t)) {
            score += 3;
        }
        if (/!{2,}|\?\?|you won'?t believe|δεν θα πιστεύτε|δεν θα πιστεψεις|σοκ\b|shock\b|outrage|scandal|απίστευτο|unbelievable|εξοργισ|morid/i.test(t)) {
            penalty += 8;
        }
        if ((t.match(/!/g) || []).length >= 2) {
            penalty += 4;
        }
        if (/^[Α-ΩA-ZΆΈΉΊΌΎΏ\s!?\-–—]{18,}$/.test(t)) {
            penalty += 5;
        }
        if (/\b(εξαιρετικ|απίστευτ|σοκ|SHOCK|OMG|WOW)\b/i.test(t)) {
            penalty += 3;
        }
        score = Math.max(0, Math.min(max, score - penalty));
        return { score: score, max: max, penalty: penalty };
    }

    function nrosGetFeaturedIdForDiscover() {
        let featuredId = 0;
        try {
            if (nrosIsBlockEditor()) {
                featuredId = parseInt(wp.data.select('core/editor').getEditedPostAttribute('featured_media') || 0, 10);
            }
        } catch (e) {}
        if (!featuredId) {
            featuredId = parseInt(jQuery('#_thumbnail_id').val() || 0, 10);
        }
        return featuredId;
    }

    function nrosIsAutoTimelineOnForCurrentEdit() {
        const timelineDisabled = jQuery('input[name="newsai_disable_auto_timeline"]').is(':checked');
        const proOk = typeof newsai_vars !== 'undefined' && !!newsai_vars.is_pro;
        const storytellingAuto = !!(nrosFeatures.storytelling_auto && proOk);
        return storytellingAuto && !timelineDisabled;
    }

    function nrosResolveEditorPostId() {
        let postId = parseInt(newsai_vars.post_id, 10) || 0;
        if (!postId && nrosIsBlockEditor()) {
            try {
                const editor = wp.data.select('core/editor');
                if (editor && typeof editor.getCurrentPostId === 'function') {
                    postId = parseInt(editor.getCurrentPostId(), 10) || 0;
                }
            } catch (e) {}
        }
        if (!postId) {
            const pidField = document.getElementById('post_ID');
            if (pidField && pidField.value) {
                postId = parseInt(pidField.value, 10) || 0;
            }
        }
        return postId;
    }

    function nrosDiscoverActionsFromSignals(data, headlinePack, focusActions) {
        const out = [];
        if (!data || !data.breakdown) {
            return out;
        }
        const b = data.breakdown;
        const focusHasLinks = Array.isArray(focusActions) && focusActions.some(function (a) {
            const x = String(a.text || '').toLowerCase();
            return x.indexOf('link') !== -1 || x.indexOf('σύνδεσμ') !== -1;
        });
        if (b.image && b.image.status === 'missing') {
            out.push({ prio: 'HIGH', impact: 0, text: __( 'Set a featured image at least 1200px wide in 16:9 (Google Discover).', 'newsroom-ai-assistant' ), domain: 'discover' });
        } else if (b.image && b.image.ratio_16x9 === false) {
            out.push({ prio: 'MEDIUM', impact: 6, text: __( 'Use a 16:9 landscape hero (e.g. 1280×720) — the current image is not 16:9.', 'newsroom-ai-assistant' ), domain: 'discover' });
        } else if (b.image && b.image.weighted < (b.image.weight_max || 35) * 0.5) {
            out.push({ prio: 'MEDIUM', impact: 8, text: __( 'Improve the hero image: 1200px+, 16:9, 300k+ pixels, descriptive alt.', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        const trendN = parseInt(data.trend_tokens_count || 0, 10);
        if (b.momentum && b.momentum.weighted < 1 && trendN > 0) {
            out.push({ prio: 'LOW', impact: 11, text: __( 'Optional: align the topic with a rising regional trend (Trend Radar).', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        const headlineMax = headlinePack ? (headlinePack.max || 25) : 25;
        if (headlinePack && headlinePack.score < headlineMax * 0.7) {
            out.push({ prio: 'MEDIUM', impact: 7, text: __( 'Use a clear 55–70 character headline that reflects the story (avoid clickbait).', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        const entMax = (b.entities && b.entities.weight_max) ? b.entities.weight_max : 15;
        if (b.entities && b.entities.weighted < entMax * 0.7) {
            out.push({ prio: 'MEDIUM', impact: 8, text: __( 'Add tags, category, or a place cue so the topic is clear.', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        if (b.og && (b.og.weighted || 0) < 1 && b.og.source !== 'featured_fallback') {
            out.push({ prio: 'LOW', impact: 13, text: __( 'Set a featured image or a custom Open Graph image in Yoast/Rank Math.', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        if (b.author && b.author.weighted < ((b.author.weight_max || 5) * 0.7)) {
            out.push({ prio: 'LOW', impact: 12, text: __( 'Strengthen author trust signals (bio, job title, social links).', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        const linksCovered = b.links && (b.links.covered === true || b.links.story === true || b.links.auto_timeline === true);
        if (!focusHasLinks && b.links && b.links.weighted < (b.links.max || 5) && !linksCovered) {
            out.push({ prio: 'LOW', impact: 15, text: __( 'Add internal links or a storytelling timeline cluster.', 'newsroom-ai-assistant' ), domain: 'discover' });
        }
        return out;
    }

    function nrosPickBestMergedAction(focusActions, discoverActions) {
        const prioRank = { HIGH: 0, MEDIUM: 1, LOW: 2 };
        const merged = (focusActions || []).concat(discoverActions || []);
        if (!merged.length) {
            return null;
        }
        merged.sort(function (a, b) {
            const pa = prioRank[a.prio] !== undefined ? prioRank[a.prio] : 3;
            const pb = prioRank[b.prio] !== undefined ? prioRank[b.prio] : 3;
            if (pa !== pb) {
                return pa - pb;
            }
            return (a.impact || 0) - (b.impact || 0);
        });
        return merged[0];
    }

    function nrosPaintNextActionCard(bestAction, focusScore, discoverTotal, focusActions) {
        const actionBox = jQuery('#nros-next-action-box');
        const actionBadge = jQuery('#nros-action-priority');
        const actionText = jQuery('#nros-next-action-text');
        const fa = focusActions || [];
        const focusReady = focusScore === 100 || fa.length === 0;
        if (focusReady && discoverTotal >= 80) {
            jQuery('#nros-focus-action').text(nrosDiscoverUi('great_state_title', 'Great state: ready to publish.'));
            if (actionBox.length) {
                actionBox.css({ background: '#ecfdf5', borderColor: '#a7f3d0', borderLeftColor: '#10b981' });
            }
            if (actionBadge.length) {
                actionBadge.text(nrosDiscoverUi('badge_ready', 'READY')).css('background', '#10b981');
            }
            if (actionText.length) {
                actionText.text(nrosDiscoverUi('all_perfect', 'Everything looks perfect! Ready to publish.')).css('color', '#065f46');
            }
            return;
        }
        if (!bestAction) {
            jQuery('#nros-focus-action').text(nrosDiscoverUi('open_discover_hint', 'Open the Discover tab for details.'));
            return;
        }
        if (actionText.length) {
            actionText.text(bestAction.text);
        }
        jQuery('#nros-focus-action').text(bestAction.text);
        if (bestAction.prio === 'HIGH') {
            if (actionBox.length) {
                actionBox.css({ background: '#fef2f2', borderColor: '#fecaca', borderLeftColor: '#dc2626' });
            }
            if (actionBadge.length) {
                actionBadge.text(nrosDiscoverUi('badge_high', 'HIGH PRIORITY')).css('background', '#dc2626');
            }
            if (actionText.length) {
                actionText.css('color', '#991b1b');
            }
        } else if (bestAction.prio === 'MEDIUM') {
            if (actionBox.length) {
                actionBox.css({ background: '#fffbeb', borderColor: '#fde68a', borderLeftColor: '#f59e0b' });
            }
            if (actionBadge.length) {
                actionBadge.text(nrosDiscoverUi('badge_medium', 'MEDIUM')).css('background', '#d97706');
            }
            if (actionText.length) {
                actionText.css('color', '#92400e');
            }
        } else {
            if (actionBox.length) {
                actionBox.css({ background: '#f8f9fa', borderColor: '#e2e4e7', borderLeftColor: '#646970' });
            }
            if (actionBadge.length) {
                actionBadge.text(nrosDiscoverUi('badge_low', 'LOW')).css('background', '#646970');
            }
            if (actionText.length) {
                actionText.css('color', '#50575e');
            }
        }
    }

    function nrosDiscoverChecklistRow(icon, mainHtml, subHtml) {
        const sub = (subHtml && String(subHtml).trim() !== '')
            ? '<div class="nros-dc-sub">' + String(subHtml) + '</div>'
            : '';
        return '<span class="nros-icon-wrapper nros-dc-ico" aria-hidden="true">' + icon + '</span>'
            + '<div class="nros-dc-body"><div class="nros-dc-main">' + mainHtml + '</div>' + sub + '</div>';
    }

    function nrosUpdateDiscoverChecklist(data, headlinePack) {
        if (!data || !data.breakdown) {
            return;
        }
        const b = data.breakdown;
        const ok = '<span style="color:#00a32a;">';
        const bad = '<span style="color:#d63638;">';
        const mid = '<span style="color:#646970;">';
        const img = b.image || {};
        let imgHtml = mid + nrosDiscoverUi('image_label', 'Image:') + '</span><span>';
        if (img.status === 'missing') {
            imgHtml += bad + nrosDiscoverUi('featured_missing', 'Featured image missing') + '</span>';
        } else {
            imgHtml += ok + nrosDiscoverUi('up_to', 'Up to') + ' ' + (img.weighted || 0) + '/' + (img.weight_max || 35) + '</span>';
            if (img.ratio_16x9 === false && img.status === 'ok') {
                imgHtml += ' <span style="color:#d63638;">· ' + nrosDiscoverUi('not_16_9', 'not 16:9') + '</span>';
            }
        }
        jQuery('#dc-image').html(nrosDiscoverChecklistRow('🖼', imgHtml, ''));

        const mom = b.momentum || {};
        let momHtml = mid + nrosDiscoverUi('timeliness_label', 'Timeliness:') + '</span>';
        if (mom.auto_timeline === true) {
            momHtml += ok + nrosDiscoverUi('auto_timeline_active', 'Auto Timeline active') + '</span>';
        } else if ((mom.weighted || 0) > 0 && mom.matched && mom.matched.length) {
            momHtml += ok + nrosDiscoverUi('matches_open', 'Matches (') + mom.matched.slice(0, 3).join(', ') + ')</span>';
        } else if (parseInt(data.trend_tokens_count || 0, 10) === 0) {
            momHtml += mid + nrosDiscoverUi('trend_list_empty', 'Trend list warming up') + '</span>';
        } else {
            momHtml += bad + nrosDiscoverUi('no_trend_match', 'No trend match yet') + '</span>';
        }
        const age = parseFloat(data.trend_cache_age_hours || 0, 10);
        let ageSub = '';
        if (!isNaN(age) && age < 120) {
            const ageTpl = nrosDiscoverUi('trend_cache_age', 'Trend cache age: %s h');
            ageSub = ageTpl.replace('%s', String(age.toFixed(1)));
        }
        jQuery('#dc-momentum').html(nrosDiscoverChecklistRow('📈', momHtml, ageSub));

        const hp = headlinePack || { score: 0, max: 25 };
        const hColor = hp.score >= hp.max * 0.7 ? ok : (hp.score >= hp.max * 0.4 ? mid : bad);
        let hExtra = '';
        if (headlinePack && headlinePack.penalty > 0) {
            hExtra = ' <span style="color:#d63638;font-size:10px;">' + nrosDiscoverUi('clickbait_cues', 'clickbait cues') + '</span>';
        }
        const headMain = mid + nrosDiscoverUi('headline_label', 'Headline:') + '</span>' + hColor + hp.score + '/' + hp.max + '</span>' + hExtra;
        jQuery('#dc-headline').html(nrosDiscoverChecklistRow('✍️', headMain, ''));

        const ent = b.entities || {};
        const entMain = mid + nrosDiscoverUi('topic_label', 'Topic:') + '</span><span style="color:#1d2327;">' + (ent.weighted || 0) + '/' + (ent.weight_max || 15) + '</span>';
        jQuery('#dc-entities').html(nrosDiscoverChecklistRow('🏷', entMain, ''));

        const og = b.og || {};
        let ogMain = mid + nrosDiscoverUi('og_label', 'OG image:') + '</span>';
        let ogSub = '';
        if ((og.weighted || 0) > 0) {
            ogMain += ok + (og.weighted || 0) + '/' + (og.weight_max || 5) + '</span>';
            if (og.source === 'featured_fallback') {
                ogSub = '<span class="nros-dc-hint">' + nrosDiscoverUi('og_via_featured', 'via featured image (SEO plugin fallback)') + '</span>';
            } else if (og.source === 'explicit') {
                ogSub = '<span class="nros-dc-hint">' + nrosDiscoverUi('og_explicit', 'custom image in Yoast/Rank Math') + '</span>';
            }
        } else {
            ogMain += '<span style="color:#1d2327;">—</span>';
            ogSub = '<span class="nros-dc-hint">' + nrosDiscoverUi('og_save_hint', 'Set featured image or custom OG in Yoast/Rank Math') + '</span>';
        }
        if (jQuery('#dc-og').length) {
            jQuery('#dc-og').html(nrosDiscoverChecklistRow('📎', ogMain, ogSub));
        }

        const au = b.author || {};
        const auMain = mid + nrosDiscoverUi('author_label', 'Author:') + '</span><span style="color:#1d2327;">' + (au.weighted || 0) + '/' + (au.weight_max || 5) + '</span>';
        jQuery('#dc-author').html(nrosDiscoverChecklistRow('👤', auMain, ''));

        const ln = b.links || {};
        let lnMain = mid + nrosDiscoverUi('internal_links_label', 'Internal links:') + '</span>';
        if (ln.covered === true || ln.auto_timeline === true || ln.story === true) {
            lnMain += ok + nrosDiscoverUi('links_covered_timeline', 'Covered by Storytelling Timeline') + '</span>';
        } else {
            lnMain += '<span style="color:#1d2327;">' + (ln.weighted || 0) + '/' + (ln.max || 5) + '</span>';
        }
        jQuery('#dc-links').html(nrosDiscoverChecklistRow('🔗', lnMain, ''));
    }

    function nrosUpdateDiscoverGauge(total) {
        const pct = Math.max(0, Math.min(100, total));
        const color = pct >= 80 ? '#10b981' : (pct >= 55 ? '#f59e0b' : '#dc2626');
        jQuery('#nros-discover-score').text(pct + '%').css('color', color);
        const ring = document.getElementById('nros-discover-ring');
        if (ring && nrosFeatures.circular_gauge !== false) {
            ring.style.background = 'conic-gradient(' + color + ' 0% ' + pct + '%, #e5e7eb ' + pct + '% 100%)';
        }
        if (jQuery('#nros-discover-bar').length) {
            jQuery('#nros-discover-bar').css({ width: pct + '%', background: color });
        }
    }

    function nrosPersistDiscoverScore(total, data, headlinePack) {
        const score = parseInt(total, 10);
        if (isNaN(score) || score < 0 || score > 100) {
            return;
        }
        if (score === nrosLastSavedDiscover) {
            return;
        }
        if (typeof newsai_vars === 'undefined' || !newsai_vars || !newsai_vars.ajax_url || !newsai_vars.nonce) {
            return;
        }
        const postId = nrosResolveEditorPostId();
        if (!postId) {
            return;
        }
        if (nrosDiscoverSaveBusy) {
            return;
        }
        if (nrosDiscoverSaveTimer) {
            clearTimeout(nrosDiscoverSaveTimer);
        }
        const payload = {
            partial: data.partial,
            headline: headlinePack,
            breakdown: data.breakdown,
            trend_cache_age_hours: data.trend_cache_age_hours
        };
        nrosDiscoverSaveTimer = setTimeout(function () {
            nrosDiscoverSaveBusy = true;
            jQuery.post(newsai_vars.ajax_url, {
                action: 'newsai_save_discover_score',
                nonce: newsai_vars.nonce,
                post_id: postId,
                score: score,
                breakdown: JSON.stringify(payload)
            }).done(function (resp) {
                if (resp && resp.success) {
                    nrosLastSavedDiscover = score;
                }
            }).always(function () {
                nrosDiscoverSaveBusy = false;
            });
        }, 10000);
    }

    function nrosExecuteDiscoverFetch(title, content, focusScore, focusActions) {
        if (typeof newsai_vars === 'undefined' || !newsai_vars || !newsai_vars.ajax_url) {
            return;
        }
        const postId = nrosResolveEditorPostId();
        if (!postId) {
            return;
        }
        const featuredId = nrosGetFeaturedIdForDiscover();
        const autoTimelineOn = nrosIsAutoTimelineOnForCurrentEdit() ? 1 : 0;
        jQuery.post(newsai_vars.ajax_url, {
            action: 'newsai_discover_score_partial',
            nonce: newsai_vars.nonce,
            post_id: postId,
            title: title,
            content: content,
            featured_id: featuredId,
            auto_timeline_on: autoTimelineOn
        }).done(function (resp) {
            if (!resp || !resp.success || !resp.data) {
                return;
            }
            const headlinePack = nrosComputeHeadlineDiscoverScore(title, resp.data.headline_max || 20);
            const total = Math.min(100, parseInt(resp.data.partial || 0, 10) + parseInt(headlinePack.score || 0, 10));
            nrosUpdateDiscoverGauge(total);
            nrosUpdateDiscoverChecklist(resp.data, headlinePack);
            const dActions = nrosDiscoverActionsFromSignals(resp.data, headlinePack, focusActions);
            nrosLastDiscoverActions = dActions;
            const structure = resp.data.structure || {};
            const entityPct = parseInt(resp.data.entity_pillar_pct || 0, 10);
            const structurePct = parseInt(structure.pct || 0, 10);
            nrosLastReadinessState.discover = total;
            nrosLastReadinessState.entity = entityPct;
            nrosLastReadinessState.structure = structurePct;
            nrosLastReadinessState.structureActions = nrosStructureActionsFromPack(structure);
            nrosLastReadinessState.search = parseInt(focusScore, 10) || 0;
            nrosUpdateStructureChecklist(structure);
            let topForCard = nrosMergeReadinessTopActions(focusActions, dActions, nrosLastReadinessState.structureActions, 3);
            const readinessComposite = nrosReadinessComposite(
                nrosLastReadinessState.search,
                total,
                entityPct,
                structurePct
            );
            if (!topForCard.length && total < 80 && readinessComposite < 80) {
                topForCard = [{
                    prio: 'LOW',
                    impact: 20,
                    text: __( 'Open the Discover tab for image and headline tweaks.', 'newsroom-ai-assistant' ),
                    domain: 'readiness'
                }];
            }
            nrosPaintReadinessTop3(topForCard);
            nrosPaintReadinessPillar('search', nrosLastReadinessState.search);
            nrosPaintReadinessPillar('discover', nrosLastReadinessState.discover);
            nrosPaintReadinessPillar('entity', nrosLastReadinessState.entity);
            nrosPaintReadinessPillar('structure', nrosLastReadinessState.structure);
            nrosPaintReadinessHero(nrosReadinessComposite(
                nrosLastReadinessState.search,
                nrosLastReadinessState.discover,
                nrosLastReadinessState.entity,
                nrosLastReadinessState.structure
            ));
            nrosPaintNextActionCard(topForCard[0] || null, focusScore, total, focusActions);
            nrosPersistDiscoverScore(total, resp.data, headlinePack);
        }).fail(function () {
            jQuery('#nros-discover-score').text('—').css('color', '#9ca3af');
        });
    }

    function nrosResolveEditorGeo() {
        var $geo = $('#newsai-post-geo, #newsai-trends-geo').first();
        if ($geo.length) {
            var val = String($geo.val() || '').trim();
            if (val !== '') {
                return val;
            }
        }
        if (typeof newsai_vars !== 'undefined' && newsai_vars.site_geo) {
            return String(newsai_vars.site_geo);
        }
        return (typeof newsai_vars !== 'undefined' && newsai_vars.geo) ? String(newsai_vars.geo) : 'US';
    }

    var nrosSeoMetaCache = { excerpt: '', yoast: '', rankmath: '', bound: false };

    function nrosReadSeoMetaFromEditorStore() {
        if (!nrosIsBlockEditor()) {
            return null;
        }
        try {
            var editor = wp.data.select('core/editor');
            if (!editor) {
                return null;
            }
            var meta = editor.getEditedPostAttribute('meta') || {};
            var excerptData = editor.getEditedPostAttribute('excerpt');
            return {
                excerpt: typeof excerptData === 'string' ? excerptData : '',
                yoast: (meta._yoast_wpseo_metadesc && String(meta._yoast_wpseo_metadesc)) || '',
                rankmath: (meta.rank_math_description && String(meta.rank_math_description)) || ''
            };
        } catch (eStore) {
            return null;
        }
    }

    function nrosRefreshSeoMetaCache() {
        var fromStore = nrosReadSeoMetaFromEditorStore();
        if (fromStore) {
            nrosSeoMetaCache.excerpt = fromStore.excerpt || '';
            nrosSeoMetaCache.yoast = fromStore.yoast || '';
            nrosSeoMetaCache.rankmath = fromStore.rankmath || '';
            return;
        }
        nrosSeoMetaCache.excerpt = String(jQuery('#excerpt').val() || '');
        var yoastEl = document.querySelector('#yoast_wpseo_metadesc, textarea[name="_yoast_wpseo_metadesc"]');
        if (yoastEl) {
            nrosSeoMetaCache.yoast = String(yoastEl.value || '');
        }
        var rmEl = document.querySelector('#rank_math_description, textarea[name="rank_math_description"]');
        if (rmEl) {
            nrosSeoMetaCache.rankmath = String(rmEl.value || '');
        }
    }

    function nrosSeoMetaHasContent() {
        nrosRefreshSeoMetaCache();
        return [nrosSeoMetaCache.excerpt, nrosSeoMetaCache.yoast, nrosSeoMetaCache.rankmath].some(function (v) {
            return String(v || '').trim().length > 10;
        });
    }

    function nrosBindSeoMetaListenersOnce() {
        if (nrosSeoMetaCache.bound) {
            return;
        }
        nrosSeoMetaCache.bound = true;
        jQuery(document).on('input change', '#excerpt, #yoast_wpseo_metadesc, textarea[name="_yoast_wpseo_metadesc"], #rank_math_description, textarea[name="rank_math_description"]', nrosTriggerUpdate);
    }

    function nrosScheduleDiscoverFetch(focusScore, focusActions) {
        if (!nrosResolveEditorPostId()) {
            return;
        }
        nrosLastFocusForDiscover = { score: focusScore, actions: focusActions ? focusActions.slice() : [] };
        const title = String(nrosGetTitle() || '');
        const content = String(nrosGetContent() || '');
        if (nrosDiscoverTimer) {
            clearTimeout(nrosDiscoverTimer);
        }
        nrosDiscoverTimer = setTimeout(function () {
            nrosDiscoverTimer = null;
            nrosExecuteDiscoverFetch(title, content, focusScore, focusActions);
        }, 1200);
    }
    function nrosEvaluateArticle() {
        try {
        let title = String(nrosGetTitle() || '');
        let content = String(nrosGetContent() || '');

        nrosRefreshSeoMetaCache();
        let seoTextForHash = (nrosSeoMetaCache.excerpt + nrosSeoMetaCache.yoast + nrosSeoMetaCache.rankmath).length;

        let evalHash = title + content + seoTextForHash;
        if (evalHash === nrosLastEvalHash && evalHash !== '') return;
        nrosLastEvalHash = evalHash;

        let score = 0;
        let actions = [];

        let hasMeta = nrosSeoMetaHasContent();
        if (hasMeta) { 
            score += 25; 
            $('#check-meta').html('<span class="nros-icon-wrapper">📝</span> <span style="color:#00a32a;">' + (isGr ? 'Meta Description OK' : 'Meta Description OK') + '</span>'); 
        } else { 
            actions.push({ prio: 'HIGH', impact: 1, text: isGr ? 'Πρόσθεσε Meta Description ή Σύνοψη (Excerpt)' : 'Add a Meta Description or Excerpt' });
            $('#check-meta').html('<span class="nros-icon-wrapper">📝</span> <span style="color:#d63638;">' + (isGr ? 'Λείπει Meta Description' : 'Meta Description Missing') + '</span>'); 
        }

        let wordCount = String(content).replace(/<\/?[^>]+(>|$)/g, "").split(/\s+/).filter(word => word.length > 0).length;
        if (wordCount >= 300) { 
            score += 20; 
            $('#check-words').html('<span class="nros-icon-wrapper">✍️</span> <span style="color:#00a32a;">' + (isGr ? 'Λέξεις OK' : 'Word Count OK') + ' (' + wordCount + ')</span>'); 
        } else { 
            actions.push({ prio: 'HIGH', impact: 2, text: isGr ? 'Γράψε περισσότερο κείμενο (τουλάχιστον 300 λέξεις)' : 'Write more content (min 300 words)' });
            $('#check-words').html('<span class="nros-icon-wrapper">✍️</span> <span style="color:#d63638;">' + (isGr ? 'Πολύ μικρό κείμενο' : 'Content too short') + ' (' + wordCount + '/300)</span>'); 
        }

        let len = title.length;
        if (len >= 40 && len <= 70) { 
            score += 20; 
            $('#hc-length').html('<span class="nros-icon-wrapper">⏳</span> <span style="color:#00a32a;">' + (isGr ? 'Μήκος Τίτλου OK' : 'Title Length OK') + '</span>'); 
        } else { 
            actions.push({ prio: 'HIGH', impact: 3, text: isGr ? 'Διόρθωσε το μήκος του τίτλου (40-70 γράμματα)' : 'Fix title length (40-70 chars)' });
            $('#hc-length').html('<span class="nros-icon-wrapper">⏳</span> <span style="color:#d63638;">' + (isGr ? 'Λάθος μήκος τίτλου' : 'Bad title length') + '</span>'); 
        }

        let linkCount = (String(content).match(/<a href=/g) || []).length;
        const storytellingAuto = !!nrosFeatures.storytelling_auto;
        const timelineDisabled = $('input[name="newsai_disable_auto_timeline"]').is(':checked');
        const hasTimelineShortcode = /\[(newsroom_timeline|nros_timeline)\b/i.test(String(content));
        const hasTimelineHtml = /(newsai-story-cluster|newsroom-os-story-cluster|nros-timeline|newsroom-timeline|timeline-item|timeline-wrap)/i.test(String(content));
        const storytellingCoversLinks = hasTimelineShortcode || hasTimelineHtml || nrosIsAutoTimelineOnForCurrentEdit();
        if (linkCount >= 2 || storytellingCoversLinks) { 
            score += 15; 
            const linksLabel = storytellingCoversLinks && linkCount < 2
                ? (isGr ? 'Καλύπτεται από Storytelling Timeline' : 'Covered by Storytelling Timeline')
                : ((isGr ? 'Εσωτερικά Links OK' : 'Internal Links OK') + ' (' + linkCount + ')');
            $('#check-links').html('<span class="nros-icon-wrapper">🔗</span> <span style="color:#00a32a;">' + linksLabel + '</span>'); 
        } else { 
            actions.push({ prio: 'MEDIUM', impact: 4, text: isGr ? 'Πρόσθεσε τουλάχιστον 2 σχετικά άρθρα (Links)' : 'Add at least 2 internal links' });
            $('#check-links').html('<span class="nros-icon-wrapper">🔗</span> <span style="color:#d63638;">' + (isGr ? 'Λείπουν Εσωτερικά Links' : 'Internal Links Missing') + ' (' + linkCount + '/2)</span>'); 
        }

        if (/\d/.test(title)) { 
            score += 10; 
            $('#hc-number').html('<span class="nros-icon-wrapper">🔢</span> <span style="color:#00a32a;">' + (isGr ? 'Περιέχει Αριθμό' : 'Contains Number') + '</span>'); 
        } else { 
            actions.push({ prio: 'LOW', impact: 5, text: isGr ? 'Βάλε έναν αριθμό στον τίτλο για +30% CTR' : 'Add a number to title for +30% CTR' });
            $('#hc-number').html('<span class="nros-icon-wrapper">🔢</span> <span style="color:#646970;">' + (isGr ? 'Χωρίς Αριθμό' : 'No number in title') + '</span>'); 
        }

        if (/[!?]/.test(title)) { 
            score += 10; 
            $('#hc-power').html('<span class="nros-icon-wrapper">⚡</span> <span style="color:#00a32a;">' + (isGr ? 'Power Character OK' : 'Power Character OK') + '</span>'); 
        } else { 
            actions.push({ prio: 'LOW', impact: 6, text: isGr ? 'Βάλε ένα Power Symbol (! ή ?) στον τίτλο' : 'Add a Power Symbol (! or ?) to title' });
            $('#hc-power').html('<span class="nros-icon-wrapper">⚡</span> <span style="color:#646970;">' + (isGr ? 'Χωρίς Power Character' : 'No Power Character') + '</span>'); 
        }

        let color = score >= 85 ? '#10b981' : (score >= 60 ? '#f59e0b' : '#dc2626');
        if ($('#nros-pub-score').length) {
            $('#nros-pub-score').text(score + '%').css('color', color);
        }
        if ($('#nros-pub-bar').length) {
            $('#nros-pub-bar').css({'width': score + '%', 'background': color});
        }
        $('#nros-focus-score').text(score + '%').css('color', color);
        const ring = document.getElementById('nros-focus-ring');
        if (ring && nrosFeatures.circular_gauge !== false) {
            const pct = Math.max(0, Math.min(100, score));
            ring.style.background = 'conic-gradient(' + color + ' 0% ' + pct + '%, #e5e7eb ' + pct + '% 100%)';
        }
        if ($('#nros-focus-bar').length) {
            $('#nros-focus-bar').css({'width': score + '%', 'background': color});
        }

        let actionBox = $('#nros-next-action-box');
        let actionBadge = $('#nros-action-priority');
        let actionText = $('#nros-next-action-text');

        if (score === 100 || actions.length === 0) {
            if (actionBox.length) actionBox.css({'background':'#ecfdf5', 'border-color':'#a7f3d0', 'border-left-color':'#10b981'});
            if (actionBadge.length) actionBadge.text(nrosDiscoverUi('badge_ready', 'READY')).css('background', '#10b981');
            if (actionText.length) actionText.text(nrosDiscoverUi('all_perfect', 'Everything looks perfect! Ready to publish.')).css('color', '#065f46');
            $('#nros-focus-action').text(nrosDiscoverUi('great_state_title', 'Great state: ready to publish.'));
        } else {
            actions.sort((a, b) => a.impact - b.impact); 
            let bestAction = actions[0];
            
            if (actionText.length) actionText.text(bestAction.text);
            $('#nros-focus-action').text(bestAction.text);
            
            if (bestAction.prio === 'HIGH') {
                if (actionBox.length) actionBox.css({'background':'#fef2f2', 'border-color':'#fecaca', 'border-left-color':'#dc2626'});
                if (actionBadge.length) actionBadge.text(nrosDiscoverUi('badge_high', 'HIGH PRIORITY')).css('background', '#dc2626');
                if (actionText.length) actionText.css('color', '#991b1b');
            } else if (bestAction.prio === 'MEDIUM') {
                if (actionBox.length) actionBox.css({'background':'#fffbeb', 'border-color':'#fde68a', 'border-left-color':'#f59e0b'});
                if (actionBadge.length) actionBadge.text(nrosDiscoverUi('badge_medium', 'MEDIUM')).css('background', '#d97706');
                if (actionText.length) actionText.css('color', '#92400e');
            } else {
                if (actionBox.length) actionBox.css({'background':'#f8f9fa', 'border-color':'#e2e4e7', 'border-left-color':'#646970'});
                if (actionBadge.length) actionBadge.text(nrosDiscoverUi('badge_low', 'LOW')).css('background', '#646970');
                if (actionText.length) actionText.css('color', '#50575e');
            }
        }
        // Persist the Focus Score to postmeta so the chief dashboard can average it
        // across the writer's recent posts. Throttled to one write every 10s and only
        // when the integer score has actually changed since the last successful save.
        try {
            nrosPersistFocusScore(score);
            const structureQuick = nrosClientStructureQuickPack(content);
            nrosLastReadinessState.search = score;
            nrosLastReadinessState.structure = structureQuick.pct;
            nrosLastReadinessState.structureActions = structureQuick.actions || [];
            nrosUpdateStructureChecklist(structureQuick);
            nrosPaintReadinessEngine(nrosLastReadinessState, actions, nrosLastDiscoverActions);
            nrosScheduleDiscoverFetch(score, actions);
        } catch (persistErr) {
            // never let persistence break the sidebar UI
        }

        } catch (e) {
            // Keep UI alive even if editor APIs return unexpected values.
        }
    }

    let nrosLastSavedScore = -1;
    let nrosScoreSaveTimer = null;
    let nrosScoreSaveBusy = false;
    function nrosPersistFocusScore(score) {
        score = parseInt(score, 10);
        if (isNaN(score) || score < 0 || score > 100) return;
        if (score === nrosLastSavedScore) return;
        if (typeof newsai_vars === 'undefined' || !newsai_vars || !newsai_vars.ajax_url || !newsai_vars.nonce) return;
        let postId = parseInt(newsai_vars.post_id, 10) || 0;
        if (!postId && typeof wp !== 'undefined' && wp.data && typeof wp.data.select === 'function') {
            try {
                let editor = wp.data.select('core/editor');
                if (editor && typeof editor.getCurrentPostId === 'function') {
                    postId = parseInt(editor.getCurrentPostId(), 10) || 0;
                }
            } catch (eGet) {}
        }
        if (!postId) {
            let pidField = document.getElementById('post_ID');
            if (pidField && pidField.value) {
                postId = parseInt(pidField.value, 10) || 0;
            }
        }
        if (!postId) return;
        if (nrosScoreSaveBusy) return;
        if (nrosScoreSaveTimer) clearTimeout(nrosScoreSaveTimer);
        nrosScoreSaveTimer = setTimeout(function() {
            nrosScoreSaveBusy = true;
            $.post(newsai_vars.ajax_url, {
                action: 'newsai_save_focus_score',
                nonce:  newsai_vars.nonce,
                post_id: postId,
                score:  score
            }).done(function(resp) {
                if (resp && resp.success) {
                    nrosLastSavedScore = score;
                }
            }).always(function() {
                nrosScoreSaveBusy = false;
            });
        }, 10000); // 10s debounce — avoid hammering DB on every keystroke
    }

    // --- 🧠 LOCAL AI: SMART TAG SUGGESTER (Context-aware ranking) ---
    let nrosLastText = '';
    function nrosSuggestTags() {
        if(typeof nros_site_tags === 'undefined') return;

        let rawTitle = nrosGetTitle() || '';
        // Parse full plain text but keep weighted zones for speed/quality.
        let rawContent = nrosGetContent().replace(/<[^>]*>?/gm, ' ');
        let leadContent = rawContent.substring(0, 650);
        let bodyContent = rawContent.substring(0, 2800);

        if (rawContent.length < 100) {
            let placeholder = isGr ? 'Γράψτε κείμενο για προτάσεις...' : 'Write text for suggestions...';
            $('#nros-tag-suggestions').html('<span style="font-size:11px; color:#a7aaad; font-style:italic;">'+placeholder+'</span>');
            return;
        }

        function nrosNormalize(text) {
            if (!text) return '';
            let out = String(text).toLowerCase();
            if (out.normalize) {
                out = out.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
            }
            out = out.replace(/[^\p{L}\p{N}\s]/gu, ' ');
            out = out.replace(/\s+/g, ' ').trim();
            return out;
        }
        function escapeRegExp(string) {
            return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        }
        const stopWords = isGr
            ? new Set(['και','με','το','τα','της','του','των','στο','στα','στη','στην','στον','για','απο','από','σε','ειναι','ειναι','μια','ενα','πως','που','μην','οτι','ότι','τις','τους'])
            : new Set(['the','and','is','in','at','of','on','for','with','from','this','that','to','a','an']);
        const denyList = new Set(['news','breaking','article','story','ειδηση','ειδήσεις','newsroom','portal']);

        const titleNorm = nrosNormalize(rawTitle);
        const leadNorm = nrosNormalize(leadContent);
        const bodyNorm = nrosNormalize(bodyContent);
        const textToAnalyze = titleNorm + ' ' + leadNorm + ' ' + bodyNorm;
        if (textToAnalyze === nrosLastText) return;
        nrosLastText = textToAnalyze;

        let matches = [];

        nros_site_tags.forEach(function(tag) {
            const tagName = (tag.name || '').trim();
            if (tagName.length < 2) return;
            const tagNorm = nrosNormalize(tagName);
            if (!tagNorm || stopWords.has(tagNorm) || denyList.has(tagNorm)) return;

            const words = tagNorm.split(' ').filter(Boolean);
            const isAcronym = /^[a-z0-9]{2,4}$/i.test(tagNorm);
            if (!isAcronym && words.length === 1 && words[0].length <= 2) return;

            const regex = new RegExp('(^|\\s)' + escapeRegExp(tagNorm) + '(?=\\s|$)', 'g');
            const titleHits = (titleNorm.match(regex) || []).length;
            const leadHits = (leadNorm.match(regex) || []).length;
            const bodyHits = (bodyNorm.match(regex) || []).length;
            const totalHits = titleHits + leadHits + bodyHits;
            if (totalHits <= 0) return;

            // Weighted relevance by editorial position + popularity.
            let score = 0;
            score += titleHits * 16;
            score += leadHits * 6;
            score += bodyHits * 2;
            if (words.length > 1) score += 4; // favor entities/phrases
            if (Number(tag.count || 0) > 0) score += Math.min(5, Math.log10(Number(tag.count) + 1) * 2);

            // Penalize overly generic one-word tags with low evidence.
            if (words.length === 1 && totalHits === 1 && titleHits === 0) score -= 3;
            if (score > 0) {
                matches.push({ data: tag, score: score, hits: totalHits, phrase: words.length > 1 });
            }
        });

        matches.sort((a, b) => b.score - a.score || b.hits - a.hits);

        if(matches.length > 0) {
            let html = '';
            const selected = [];
            matches.forEach(function(m) {
                if (selected.length >= 6) return;
                const norm = nrosNormalize(m.data.name);
                const duplicate = selected.some(s => {
                    const sNorm = nrosNormalize(s.data.name);
                    return norm === sNorm || norm.includes(sNorm) || sNorm.includes(norm);
                });
                if (!duplicate) selected.push(m);
            });
            selected.forEach(function(m) {
                const tag = m.data;
                let confLevel = 'low';
                if (m.score >= 18) confLevel = 'high';
                else if (m.score >= 10) confLevel = 'medium';
                const confLabel = confLevel === 'high'
                    ? __('HIGH')
                    : (confLevel === 'medium' ? __('MED') : __('LOW'));
                html += '<span class="nros-tag-pill-wrap">' +
                    '<span class="nros-tag-confidence '+confLevel+'">'+confLabel+'</span>' +
                    '<span class="nros-pill-btn nros-add-tag-btn" data-id="'+tag.id+'" data-name="'+tag.name+'" title="'+__('Add to article')+'">+ '+tag.name+'</span>' +
                    '</span>';
            });
            $('#nros-tag-suggestions').html(html);
        } else {
            let placeholder = isGr ? 'Γράψτε κείμενο για προτάσεις...' : 'Write text for suggestions...';
            $('#nros-tag-suggestions').html('<span style="font-size:11px; color:#a7aaad; font-style:italic;">'+placeholder+'</span>');
        }
    }


    // ========================================================
    // 🚀 THE MASTER EVENT LISTENER (Hybrid Gutenberg & Classic)
    // ========================================================
    const NROS_IDLE_MS = 1200;
    let nrosEvalIdleTimer = null;

    function nrosGetActiveSidebarPane() {
        var $active = jQuery('.nros-sb-tab.nros-sb-tab--active');
        return $active.length ? String($active.data('sb-pane') || 'readiness') : 'readiness';
    }

    function nrosShouldRunEditorScoring() {
        if (document.hidden) {
            return false;
        }
        return !!document.getElementById('nros-focus-score') || !!document.getElementById('nros-discover-score');
    }

    function nrosShouldRunTagSuggestions() {
        if (document.hidden) {
            return false;
        }
        var pane = nrosGetActiveSidebarPane();
        return pane === 'readiness';
    }

    function nrosScheduleIdleCallback(fn) {
        if (typeof window.requestIdleCallback === 'function') {
            window.requestIdleCallback(function () {
                fn();
            }, { timeout: 2000 });
        } else {
            setTimeout(fn, 32);
        }
    }

    function nrosRunUpdate(forceTags) {
        try {
            if (nrosShouldRunEditorScoring()) {
                nrosEvaluateArticle();
                nrosUpdateBreakingHeadingWarn();
            }
            if (forceTags === true || nrosShouldRunTagSuggestions()) {
                nrosSuggestTags();
            }
        } catch (e) {
            // Prevent total failure if one checker throws.
        }
    }

    function nrosTriggerUpdate(forceRun) {
        if (forceRun === true) {
            nrosScheduleIdleCallback(function () {
                nrosRunUpdate(true);
            });
            return;
        }
        clearTimeout(nrosEvalIdleTimer);
        nrosEvalIdleTimer = setTimeout(function () {
            nrosEvalIdleTimer = null;
            if (!nrosShouldRunEditorScoring()) {
                return;
            }
            nrosScheduleIdleCallback(function () {
                nrosRunUpdate(false);
            });
        }, NROS_IDLE_MS);
    }

    // Targeted listeners — no global textarea/contenteditable scan.
    nrosBindSeoMetaListenersOnce();
    jQuery(document).on('input change', '#title, #content, .editor-post-title__input', nrosTriggerUpdate);

    // 2. Gutenberg only — never subscribe on Classic (wp.blocks + getEditedPostContent can stack-overflow).
    if (nrosIsBlockEditor() && typeof wp !== 'undefined' && wp.data && wp.data.subscribe) {
        let nrosWpStateHash = '';
        wp.data.subscribe(function() {
            try {
                const editor = wp.data.select('core/editor');
                if (!editor) {
                    return;
                }
                const t = editor.getEditedPostAttribute('title') || '';
                const c = editor.getEditedPostContent ? (editor.getEditedPostContent() || '') : '';
                var metaPack = nrosReadSeoMetaFromEditorStore();
                var metaLen = metaPack ? (String(metaPack.excerpt).length + String(metaPack.yoast).length + String(metaPack.rankmath).length) : 0;
                const nextHash = String(t).length + '|' + String(c).length + '|' + metaLen;
                if (nextHash !== nrosWpStateHash) {
                    nrosWpStateHash = nextHash;
                    nrosTriggerUpdate();
                }
            } catch (e) {
                /* ignore — avoid re-entrant trigger on broken store */
            }
        });
    }

    // 3. Αρχική φόρτωση
    setTimeout(function() { nrosTriggerUpdate(true); }, 900);
    // Final safety net: low-cost periodic hash check (avoids idle CPU burn).
    let nrosPeriodicHash = '';
    setInterval(function() {
        try {
            if (!document.getElementById('nros-focus-score') && !document.getElementById('nros-discover-score')) return;
            if (document.hidden) return;
            const next = (nrosGetTitle() || '') + '|' + (nrosGetContent() || '').length;
            if (next !== nrosPeriodicHash) {
                nrosPeriodicHash = next;
                nrosTriggerUpdate();
            }
        } catch (e) {}
    }, 6000);

    jQuery(document).on('change', '#newsai-claim-review-enabled', function () {
        jQuery('#nros-claim-review-fields').toggle(this.checked);
    });

    // First-use onboarding in editor
    const onboardingSeenKey = 'nros_onboarding_seen_v2';
    if (nrosFeatures.onboarding_modal !== false && !localStorage.getItem(onboardingSeenKey) && $('#nros-onboarding-modal').length) {
        setTimeout(() => { $('#nros-onboarding-modal').fadeIn(160); }, 500);
    }
    $(document).on('click', '#nros-onboarding-close, .nros-onboarding-backdrop', function() {
        localStorage.setItem(onboardingSeenKey, '1');
        $('#nros-onboarding-modal').fadeOut(150);
    });

    // Remember each sidebar section's open/closed state per editor so writers are not
    // re-flooded with every panel on each new article. Persisted in localStorage.
    (function nrosPersistAccordions() {
        var keyPrefix = 'nros_acc_v1_';
        var nodes = document.querySelectorAll('details.nros-accordion[data-nros-persist]');
        if (!nodes.length) {
            return;
        }
        nodes.forEach(function (el) {
            var storeKey = keyPrefix + el.getAttribute('data-nros-persist');
            try {
                var stored = localStorage.getItem(storeKey);
                if (stored === 'open') {
                    el.open = true;
                } else if (stored === 'closed') {
                    el.open = false;
                }
            } catch (e) {}
            el.addEventListener('toggle', function () {
                try {
                    localStorage.setItem(storeKey, el.open ? 'open' : 'closed');
                } catch (e) {}
            });
        });
    })();

    $(document).on('click', '.nros-readiness-tab', function (e) {
        e.preventDefault();
        const t = jQuery(this).data('readiness');
        jQuery('.nros-readiness-tab').removeClass('nros-readiness-tab--active');
        jQuery(this).addClass('nros-readiness-tab--active');
        jQuery('#nros-readiness-pane-editorial, #nros-readiness-pane-discover, #nros-readiness-pane-structure').hide();
        if (t === 'discover') {
            jQuery('#nros-readiness-pane-discover').show();
        } else if (t === 'structure') {
            jQuery('#nros-readiness-pane-structure').show();
        } else {
            jQuery('#nros-readiness-pane-editorial').show();
        }
    });

    function nrosBreakingPaint(state) {
        if (!state) {
            return;
        }
        const on = !!(state.active || state.legacy);
        const panel = jQuery('#nros-breaking-panel');
        if (!panel.length) {
            return;
        }
        panel.toggleClass('is-idle', !on);
        jQuery('#nros-breaking-active-ui').toggle(on);
        jQuery('#nros-breaking-idle-ui').toggle(!on);
        const expiresEl = jQuery('#nros-breaking-expires-text');
        if (state.active && state.hours_left > 0 && expiresEl.length) {
            const tpl = panel.data('expires-template') || 'Auto-expires in ~%s hours';
            expiresEl.text(String(tpl).replace('%s', state.hours_left));
        }
        nrosUpdateBreakingHeadingWarn();
    }

    function nrosBreakingRequest(action, data, onDone) {
        if (typeof newsai_vars === 'undefined' || !newsai_vars.ajax_url) {
            return;
        }
        const postId = nrosResolveEditorPostId();
        if (!postId) {
            nrosToast(isGr ? 'Αποθήκευσε πρώτα το άρθρο (draft).' : 'Save the post as a draft first.');
            return;
        }
        const payload = jQuery.extend({
            action: action,
            nonce: newsai_vars.nonce,
            post_id: postId
        }, data || {});
        jQuery.post(newsai_vars.ajax_url, payload).done(function (resp) {
            if (resp && resp.success && resp.data && resp.data.state) {
                nrosBreakingPaint(resp.data.state);
            }
            if (typeof onDone === 'function') {
                onDone(resp);
            }
        }).fail(function () {
            nrosToast(isGr ? 'Σφάλμα Breaking mode.' : 'Breaking mode request failed.');
        });
    }

    jQuery(document).on('change', '#newsai-enable-breaking', function () {
        if (!this.checked) {
            return;
        }
        nrosBreakingRequest('newsai_breaking_set', { enable: '1' });
    });

    jQuery(document).on('click', '#newsai-breaking-resolve', function (e) {
        e.preventDefault();
        jQuery('#newsai-breaking-resolve-field').val('1');
        nrosBreakingRequest('newsai_breaking_resolve', {});
    });

    jQuery(document).on('click', '#newsai-insert-live-update', function (e) {
        e.preventDefault();
        nrosInsertLiveUpdateBlock();
        nrosTriggerUpdate(true);
    });

    if (jQuery('#nros-breaking-panel').length) {
        nrosUpdateBreakingHeadingWarn();
    }
    
    $(document).on('click', '#nros-open-details-btn', function(e) {
        e.preventDefault();
        const detailsPanel = $('#nros-score-details-panel');
        if (detailsPanel.length) {
            detailsPanel.prop('open', true);
            detailsPanel[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
    });

    $(document).on('click', '#nros-fix-now-btn', function(e) {
        e.preventDefault();
        const txt = ($('#nros-next-action-text').text() || '').toLowerCase();
        if (txt.includes('meta')) {
            $('#excerpt').focus();
            nrosToast(nrosI18n.focused_meta || (isGr ? 'Άνοιξε το Excerpt/Meta πεδίο.' : 'Focused Excerpt/Meta field.'));
            return;
        }
        if (txt.includes('internal') || txt.includes('links') || txt.includes('links')) {
            $('#newsai-keyword').focus();
            nrosToast(nrosI18n.start_links || (isGr ? 'Ξεκίνα με αναζήτηση σχετικών links.' : 'Start with related links search.'));
            return;
        }
        const titleField = $('#title');
        if (titleField.length) {
            titleField.focus();
            nrosToast(nrosI18n.start_title || (isGr ? 'Ξεκίνα διορθώνοντας τον τίτλο.' : 'Start by refining the title.'));
            return;
        }
        nrosToast(nrosI18n.open_detail_first || (isGr ? 'Άνοιξε τον αναλυτικό πίνακα για το πρώτο fix.' : 'Open detailed panel for the first fix.'));
    });
    // ========================================================


    // --- 🚀 QUICK BLOCKS (HYBRID NLP & INCEPTION FIX) ---
    $(document).on('click', '.nros-quick-block', function(e) {
        e.preventDefault();
        var type = $(this).data('type');
        var contentText = nrosGetContent().replace(/<\/?[^>]+(>|$)/g, " ").replace(/\s+/g, ' ').trim();
        var html = '';

        if (type === 'faq') {
            if (typeof newsai_vars !== 'undefined' && newsai_vars.features && newsai_vars.features.faq_block === false) {
                alert(isGr ? 'Το FAQ block είναι απενεργοποιημένο. Ενεργοποίησέ το από Ρυθμίσεις → UX & AI.' : 'FAQ block is disabled. Enable it under Settings → UX & AI.');
                return;
            }
            var sentences = contentText.match(/[^.?!;\u037E\n]+[.?!;\u037E]+/g) || [];
            var questionsMatch = [];
            
            var qWordsGr = ['τι', 'πώς', 'πως', 'ποιος', 'ποια', 'ποιο', 'ποιες', 'ποιους', 'πόσο', 'ποσο', 'πόσα', 'ποσα', 'γιατί', 'γιατι', 'πότε', 'ποτε', 'πού', 'που', 'μήπως', 'μηπως', 'άραγε'];
            var qWordsEn = ['what', 'how', 'why', 'who', 'when', 'where', 'is', 'are', 'do', 'does', 'can', 'will', 'should', 'could', 'would'];
            var activeQWords = isGr ? qWordsGr : qWordsEn;

            sentences.forEach(function(s) {
                var cleanS = s.trim();
                if (cleanS.length < 10 || cleanS.length > 200) return; 
                
                var hasQuestionMark = /[?;¿\u037E]/.test(cleanS);
                
                var firstWord = cleanS.split(' ')[0].toLowerCase().replace(/[^a-zα-ωάέήίόύώ]/g, '');
                var hasQuestionWord = activeQWords.includes(firstWord);

                if (hasQuestionMark || hasQuestionWord) {
                    if (!/[?;¿\u037E]['"”)]*$/.test(cleanS)) { 
                        cleanS = cleanS.replace(/[.!,]+$/, '') + (isGr ? ';' : '?'); 
                    }
                    questionsMatch.push(cleanS);
                }
            });
            
            var ansPlaceholder = isGr ? 'Απάντηση εδώ...' : 'Answer here...';
            var title = isGr ? 'Συχνές Ερωτήσεις (FAQ)' : 'Frequently Asked Questions (FAQ)';
            var faqPairs = [];
            var fi;
            for (fi = 0; fi < questionsMatch.length && faqPairs.length < 2; fi++) {
                faqPairs.push({ q: questionsMatch[fi], a: ansPlaceholder });
            }
            if (faqPairs.length === 0) {
                alert(isGr ? 'Δεν βρέθηκαν ερωτήσεις στο κείμενο. Γράψε ρητορικές ερωτήσεις ή ενεργοποίησε FAQ μόνο όταν έχεις πραγματικές Q&A.' : 'No questions found in the article text. Add real Q&A sentences first — empty FAQ placeholders hurt SEO.');
                return;
            }
            html = nrosBuildFaqHtml(faqPairs, title);

        } else if (type === 'keypoints') {
            var $kpBtn = $(this);
            var kpOrigHtml = $kpBtn.html();
            var kpTitle = isGr ? 'Βασικά Σημεία:' : 'Key Takeaways:';
            var kpUseAi = typeof newsai_vars !== 'undefined' && newsai_vars.ai_active && contentText.length >= 80;

            function kpInsertLocal() {
                var block = nrosBuildKeypointsHtmlLocal(contentText, isGr);
                if (block) {
                    nrosInsertIntoEditor(block);
                } else {
                    alert(isGr ? 'Γράψτε λίγο περισσότερο κείμενο πριν τα Βασικά Σημεία.' : 'Write a bit more content before adding key takeaways.');
                }
            }

            if (!kpUseAi) {
                kpInsertLocal();
                return;
            }

            $kpBtn.prop('disabled', true).html('⏳...');
            $.post(newsai_vars.ajax_url, {
                action: 'newsai_ai_key_points',
                nonce: newsai_vars.nonce,
                post_id: newsai_vars.post_id || 0,
                title: nrosGetTitle(),
                content: nrosGetContent()
            })
            .done(function (resp) {
                if (resp && resp.success) {
                    var data = (resp.data && resp.data.data) || {};
                    var points = data.points;
                    if (Array.isArray(points) && points.length >= 2) {
                        var block = nrosBuildKeypointsHtml(points, kpTitle, true);
                        if (block) {
                            nrosInsertIntoEditor(block);
                            return;
                        }
                    }
                }
                kpInsertLocal();
            })
            .fail(function () {
                kpInsertLocal();
            })
            .always(function () {
                $kpBtn.prop('disabled', false).html(kpOrigHtml);
            });
            return;
        }
        if (html) {
            nrosInsertIntoEditor(html);
        } else if (type === 'faq') {
            alert(isGr ? 'Δεν βρέθηκαν ερωτήσεις στο κείμενο. Προσθέστε ερωτηματικά προτάσεις και δοκιμάστε ξανά.' : 'No questions found in the content. Add question sentences and try again.');
        }
    });

    // --- 1-CLICK TAG ADDER (Hybrid: Gutenberg & Classic Editor - No Scroll!) ---
    $(document).on('click', '.nros-add-tag-btn', function(e) {
        e.preventDefault();
        let btn = $(this);
        let name = btn.data('name');
        let tagId = parseInt(btn.data('id'), 10);
        let originalText = btn.html();
        
        // Συνάρτηση για Οπτική Επιβεβαίωση (Πράσινο χρώμα - Χωρίς Scroll)
        function showSuccess() {
            btn.text(__('✅ Added'));
            btn.css({'background':'#10b981', 'color':'#fff', 'border-color':'#10b981'});
            setTimeout(() => {
                btn.html(originalText);
                btn.css({'background':'', 'color':'', 'border-color':''});
            }, 2000);
        }

        // 1. Gutenberg (Block Editor) Logic - Native React (No Scroll)
        if (nrosIsBlockEditor()) {
            let currentTags = wp.data.select("core/editor").getEditedPostAttribute('tags') || [];
            if (!currentTags.includes(tagId)) {
                let newTags = [...currentTags, tagId];
                wp.data.dispatch("core/editor").editPost({ tags: newTags });
            }
            showSuccess();
            if (typeof newsai_vars !== 'undefined' && newsai_vars.ajax_url) {
                $.post(newsai_vars.ajax_url, { action: 'newsai_enrich_tag_wikidata', term_id: tagId, nonce: newsai_vars.nonce });
            }
        } 
        // 2. Classic Editor Logic - Silent AJAX (No Scroll)
        else if (jQuery('#tax-input-post_tag').length || jQuery('#new-tag-post_tag').length) {
            // Βρίσκουμε το κρυφό πεδίο που κρατάει τα Tags του Classic Editor
            let tagField = jQuery('#tax-input-post_tag');
            let currentTagsStr = tagField.val() || '';
            
            // Φτιάχνουμε Array από το String (π.χ. "Tag1, Tag2")
            let currentTagsArray = currentTagsStr.split(',').map(t => t.trim()).filter(t => t.length > 0);
            
            if (!currentTagsArray.includes(name)) {
                currentTagsArray.push(name);
                let newTagsStr = currentTagsArray.join(', ');
                
                // Ενημερώνουμε το κρυφό πεδίο (έτσι ώστε να σωθούν τα tags όταν πατηθεί "Ενημέρωση Άρθρου")
                tagField.val(newTagsStr);
                
                // Ενημερώνουμε το οπτικό UI του Classic Editor (ώστε να βλέπει ο χρήστης το Tag)
                if (typeof window.tagBox !== 'undefined') {
                    // Safe DOM build: never inject raw tag names as HTML.
                    var $li = jQuery('<li>');
                    var btnId = 'post_tag-check-num-' + Date.now();
                    var $btn = jQuery('<button>', { type: 'button', id: btnId, 'class': 'ntdelbutton' });
                    $btn.append(jQuery('<span>', { 'class': 'remove-tag-icon', 'aria-hidden': 'true' }));
                    $btn.append(jQuery('<span>', { 'class': 'screen-reader-text' }).text('Remove term: ' + String(name || '')));
                    $li.append($btn).append(document.createTextNode(' ' + String(name || '')));
                    jQuery('.tagchecklist').append($li);
                    tagBox.quickClicks(jQuery('#post_tag')); // Επανασυνδέει τα κουμπιά διαγραφής
                }
            }
            showSuccess();
        } 
        // 3. Fallback
        else {
            nrosCopyToClipboard(name, btn, '+ ' + name);
        }
    });

    // --- INTERNAL LINKS UI ---
    $(document).on('click', '#newsai-search-links', function(e) {
        e.preventDefault();
        var keyword = $('#newsai-keyword').val().trim();
        if (!keyword) return;
        $.post(newsai_vars.ajax_url, { action: 'newsai_get_related_posts', keyword: keyword, post_id: newsai_vars.post_id, nonce: newsai_vars.nonce }, function(response) {
            if (response.success) {
                var html = '';
                $.each(response.data, function(i, post) { html += '<label style="display:block; margin-bottom:5px;"><input type="checkbox" class="newsai-link-cb" value="' + post.url + '" data-title="' + post.title + '"> ' + post.title + '</label>'; });
                $('#newsai-links-results').html(html).slideDown(); $('#newsai-insert-links').show();
            }
        });
    });

    function nrosSemLinksEmptyMessage(meta) {
        var reason = meta && meta.reason ? meta.reason : 'no_matches';
        var minChars = (meta && meta.min_chars) ? meta.min_chars : 60;
        if (reason === 'content_too_short') {
            return __('Write at least %d characters in the title and body, then try again.').replace('%d', String(minChars));
        }
        if (reason === 'no_keywords') {
            return __('Could not extract enough keywords from this draft. Add a clearer title or more body text.');
        }
        return __('No matching archive posts yet. Try “Wide coverage” under Settings → UX, or write more specific names/places in the article.');
    }

    $(document).on('click', '#newsai-smart-links', function(e) {
        e.preventDefault();
        var btn = $(this);
        var original = btn.html();
        btn.html('⏳...').prop('disabled', true);
        $.post(newsai_vars.ajax_url, {
            action: 'newsai_get_semantic_links',
            post_id: nrosResolveEditorPostId(),
            title: nrosGetTitle(),
            content: nrosGetContent(),
            nonce: newsai_vars.nonce
        }, function(response) {
            btn.html(original).prop('disabled', false);
            var data = response && response.success ? response.data : null;
            if (data && data._meta) {
                $('#newsai-links-results').html('<div style="color:#646970;line-height:1.45;">' + nrosEscHtml(nrosSemLinksEmptyMessage(data._meta)) + '</div>').slideDown();
                $('#newsai-insert-links').hide();
                return;
            }
            var links = Array.isArray(data) ? data.filter(function (p) { return p && p.url && p.title; }) : [];
            if (links.length === 0) {
                $('#newsai-links-results').html('<div style="color:#646970;line-height:1.45;">' + nrosEscHtml(nrosSemLinksEmptyMessage({ reason: 'no_matches' })) + '</div>').slideDown();
                $('#newsai-insert-links').hide();
                return;
            }
            var html = '';
            $.each(links, function(i, post) {
                var badge = '<span style="font-size:10px; background:#ecfdf5; color:#166534; border:1px solid #bbf7d0; border-radius:999px; padding:1px 6px; margin-left:6px;">' + nrosEscHtml(post.reason || 'Relevant') + ' · ' + (post.score || 0) + '</span>';
                html += '<label style="display:block; margin-bottom:6px;"><input type="checkbox" class="newsai-link-cb" value="' + nrosEscHtml(post.url) + '" data-title="' + nrosEscHtml(post.title) + '"> ' + nrosEscHtml(post.title) + badge + '</label>';
            });
            $('#newsai-links-results').html(html).slideDown();
            $('#newsai-insert-links').show();
        }).fail(function() {
            btn.html(original).prop('disabled', false);
            $('#newsai-links-results').html('<div style="color:#b91c1c;">' + nrosEscHtml(__('Network error. Try again.')) + '</div>').slideDown();
        });
    });

    $(document).on('click', '#newsai-insert-links', function(e) {
        e.preventDefault();
        var selected = $('.newsai-link-cb:checked');
        var clusterLabel = __('Related coverage');
        var linksHeading = isGr ? 'Σχετικά άρθρα' : 'Related articles';
        var html = '<aside class="newsai-story-cluster newsai-story-cluster--links" role="complementary" aria-label="' + nrosEscHtml(clusterLabel) + '">';
        html += '<h3 class="newsai-story-cluster__heading">' + nrosEscHtml(linksHeading) + '</h3>';
        html += '<ul class="newsai-story-cluster__list">';
        selected.each(function() {
            var url = String($(this).val() || '').trim();
            var linkTitle = String($(this).data('title') || '').trim();
            if (!url || !linkTitle) { return; }
            html += '<li><a href="' + nrosEscHtml(url) + '">' + nrosEscHtml(linkTitle) + '</a></li>';
        });
        html += '</ul></aside>';
        if (html.indexOf('<li>') === -1) { return; }
        nrosInsertIntoEditor(html);
    });

    // --- MANUAL TIMELINE INSERT ---
    $(document).on('click', '#newsai-insert-timeline', function(e) {
        e.preventDefault();
        var btn = $(this); var originalText = btn.html();
        var postId = nrosResolveEditorPostId();
        if (!postId) {
            alert(nrosI18n.timeline_no_tags || nrosI18n.timeline_not_enough || __('Save the post first, then try again.'));
            return;
        }
        btn.html('⏳...').prop('disabled', true);
        $.post(newsai_vars.ajax_url, { action: 'newsai_build_timeline', post_id: postId, tag_id: 0, keyword: '', nonce: newsai_vars.nonce }, function(response) {
            btn.html(originalText).prop('disabled', false);
            if (response.success) { nrosInsertIntoEditor(response.data); return; }
            var msg = (response.data && response.data.message) ? response.data.message : '';
            if (!msg && response.data && response.data.code === 'no_tags') {
                msg = nrosI18n.timeline_no_tags || '';
            }
            if (!msg) {
                msg = nrosI18n.timeline_not_enough || __('Not enough related published posts found for a timeline.');
            }
            alert(msg);
        }).fail(function() { btn.html(originalText).prop('disabled', false); });
    });

    function nrosNewsaiVarsFromBtn(btn) {
        var $btn = btn ? $(btn) : $('#newsai-ai-tag-match');
        var vars = (typeof window.newsai_vars !== 'undefined') ? window.newsai_vars
            : ((typeof newsai_vars !== 'undefined') ? newsai_vars : null);
        if (vars && vars.ajax_url) {
            return vars;
        }
        if (!$btn.length) {
            return null;
        }
        var ajaxUrl = $btn.attr('data-ajax-url') || $btn.data('ajaxUrl');
        var nonce = $btn.attr('data-nonce') || $btn.data('nonce');
        if (!ajaxUrl || !nonce) {
            return null;
        }
        return {
            ajax_url: ajaxUrl,
            nonce: nonce,
            post_id: parseInt($btn.attr('data-post-id') || '0', 10) || 0,
            ai_active: ($btn.attr('data-ai-active') === '1' || $btn.data('aiActive') === 1 || $btn.data('ai-active') === 1)
        };
    }

    function nrosAiTagMatchErrorMessage(resp, fallback) {
        var code = (resp && resp.data && resp.data.message) ? String(resp.data.message) : '';
        if (code === 'no_valid_tags') {
            return isGr
                ? 'Το AI δεν βρήκε tags από το pool του site που ταιριάζουν. Δοκίμασε μεγαλύτερο κείμενο ή πρόσθεσε tags στο site.'
                : 'AI found no matching tags from your site pool. Try more article text or add tags on the site.';
        }
        if (code === 'empty_content') {
            return isGr ? 'Γράψε περισσότερο κείμενο στο άρθρο.' : 'Add more article text first.';
        }
        if (code === 'ai_not_configured') {
            return isGr ? 'Ρύθμισε API key στο Newsroom OS → AI.' : 'Configure an API key in Newsroom OS → AI.';
        }
        if (code === 'pro_required') {
            return isGr ? 'Απαιτείται ενεργό Pro license.' : 'Active Pro license required.';
        }
        return fallback || (isGr ? 'AI Tag Match απέτυχε.' : 'AI Tag Match failed.');
    }

    // --- AI TAG MATCH (Pro BYOK) ---
    $(document).on('click', '#newsai-ai-tag-match', function(e) {
        e.preventDefault();
        var btn = this;
        var cfg = nrosNewsaiVarsFromBtn(btn);
        if (!cfg || !cfg.ajax_url) {
            alert(isGr
                ? 'Δεν φορτώθηκε το script του Newsroom OS (theme conflict). Κάνε hard refresh ή απενεργοποίησε optimize στο admin.'
                : 'Newsroom OS scripts did not load (theme conflict). Hard refresh or disable admin JS optimization.');
            return;
        }
        if (!cfg.ai_active && (typeof newsai_vars === 'undefined' || !newsai_vars.ai_active)) {
            alert(isGr ? 'Ενεργοποίησε Pro + API key στις ρυθμίσεις AI.' : 'Enable Pro and an API key in AI settings.');
            return;
        }
        var postId = nrosResolveEditorPostId() || parseInt(cfg.post_id, 10) || 0;
        if (!postId) {
            alert(__('Save the post first, then run AI Tag Match.'));
            return;
        }
        var $btn = $(btn);
        var orig = $btn.html();
        $btn.prop('disabled', true).html('⏳ ' + __('Matching…'));
        $.post(cfg.ajax_url, {
            action: 'newsai_ai_tag_match',
            post_id: postId,
            title: nrosGetTitle(),
            content: nrosGetContent().replace(/<[^>]*>?/gm, ' ').substring(0, 8000),
            nonce: cfg.nonce
        }).done(function(resp) {
            var payload = (resp && resp.data && resp.data.data) ? resp.data.data : {};
            var tags = payload.tags || [];
            var suggested = payload.suggested_new_tags || [];
            if (!tags.length && !suggested.length) {
                alert(nrosAiTagMatchErrorMessage(resp, __('AI Tag Match could not find suitable tags.')));
                return;
            }
            var html = '';
            tags.forEach(function(row) {
                html += '<span class="nros-tag-pill-wrap">' +
                    '<span class="nros-tag-confidence high">AI</span>' +
                    '<span class="nros-pill-btn nros-add-tag-btn" data-id="' + row.id + '" data-name="' + row.name.replace(/"/g, '&quot;') + '" title="' + (row.reason || '') + '">+ ' + row.name + '</span>' +
                    '</span>';
            });
            if (suggested.length) {
                html += '<div style="width:100%;margin-top:8px;font-size:11px;color:#646970;">' + __('Suggested new tags (create manually):') + '</div>';
                suggested.forEach(function(row) {
                    html += '<span class="nros-tag-pill-wrap">' +
                        '<span class="nros-tag-confidence" style="background:#fef3c7;color:#92400e;">NEW</span>' +
                        '<span class="nros-pill-btn" style="cursor:default;opacity:.95;" title="' + (row.reason || '') + '">' + row.name + '</span>' +
                        '</span>';
                });
            }
            $('#nros-tag-suggestions').html(html);
        }).fail(function(xhr) {
            var resp = xhr && xhr.responseJSON ? xhr.responseJSON : null;
            alert(nrosAiTagMatchErrorMessage(resp, __('AI request failed. Check your API key and daily limit.')));
        }).always(function() {
            $btn.prop('disabled', false).html(orig);
        });
    });
    
    $(document).on('click', '.nros-copy-task-btn, .nros-radar-copy-btn', function(e) {
        e.preventDefault();
        var btn = $(this);
        var inSidebar = btn.closest('#newsai_sidebar').length > 0;
        var text = $.trim(String(btn.data('title') || btn.attr('data-title') || ''));
        var originalText = btn.html();

        function nrosCopyBtnFlash(ok) {
            btn.html(ok ? '✅' : '❌');
            setTimeout(function () { btn.html(originalText); }, 2000);
        }

        function nrosCopyText(value, done) {
            if (!value) {
                done(false);
                return;
            }
            if (navigator.clipboard && window.isSecureContext) {
                navigator.clipboard.writeText(value).then(function () { done(true); }).catch(function () { done(false); });
                return;
            }
            var textArea = document.createElement('textarea');
            textArea.value = value;
            textArea.style.position = 'fixed';
            textArea.style.top = '0';
            textArea.style.left = '0';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            try {
                document.execCommand('copy');
                done(true);
            } catch (err) {
                done(false);
            }
            document.body.removeChild(textArea);
        }

        if (inSidebar) {
            nrosCopyText(text, function (ok) {
                nrosCopyBtnFlash(ok);
                if (!ok) {
                    return;
                }
                var msg = (nrosI18n.radar_headline_copied) || 'Headline copied.';
                if (typeof newsai_vars !== 'undefined' && newsai_vars.can_plan_brief && nrosI18n.radar_headline_copied_desk) {
                    msg = nrosI18n.radar_headline_copied_desk;
                }
                nrosToast(msg);
            });
            return;
        }

        var taskInput = document.getElementById('nros-task-input');
        if (taskInput && text) {
            taskInput.value = text;
            taskInput.focus();
            taskInput.style.boxShadow = '0 0 0 3px rgba(34, 113, 177, 0.4)';
            setTimeout(function () { taskInput.style.boxShadow = 'none'; }, 1200);
            nrosCopyBtnFlash(true);
            return;
        }

        if (!text) {
            nrosCopyBtnFlash(false);
            return;
        }
        nrosCopyText(text, function (ok) { nrosCopyBtnFlash(ok); });
    });

    // --- 🚀 PROMPTS (Extended Limit 25.000 Chars) ---
    $(document).on('click', '.newsai-prompt-btn', function(e) {
        e.preventDefault(); e.stopPropagation();
        var btn = $(this); var type = btn.data('type'); var originalText = btn.html();
        var title = nrosGetTitle(); 
        
        var content = nrosGetContent().replace(/<\/?[^>]+(>|$)/g, " ").replace(/\s+/g, ' ').trim().substring(0, 25000); 
        
        btn.html('⏳...');
        $.post(newsai_vars.ajax_url, { action: 'newsai_get_prompt', type: type, post_id: newsai_vars.post_id, title: title, content: content, nonce: newsai_vars.nonce }, function(response) {
            if (response.success) nrosCopyToClipboard(response.data, btn, originalText); else btn.html(originalText);
        });
    });

    // --- FETCH DATA (Trends & News) ---
    var nrosRadarFetchLock = false;

    function fetchNews() {
        if (nrosFeatures.skip_radar) { return; }
        if (nrosRadarFetchLock) { return; }
        nrosRadarFetchLock = true;
        var geo = nrosResolveEditorGeo();
        var postId = nrosResolveEditorPostId();
        var targets = $('#nros-pane-news, #newsai-news-list, #sidebar-news-list');
        
        nrosRenderRadarSkeleton(targets);
        $.post(newsai_vars.ajax_url, { action: 'newsai_get_news', geo: geo, post_id: postId, nonce: newsai_vars.nonce }, function(response) {
            if(response.success) {
                targets.html(response.data);
                targets.attr('data-nros-radar-loaded', '1');
            }
            else {
                var msg = (response.data && response.data.message) ? response.data.message : '⚠️ Error.';
                targets.html('<div style="color:#9a3412; text-align:center; padding:10px; font-size:12px;">' + $('<div/>').text(msg).html() + '</div>');
            }
        }).fail(function() {
            targets.html('<div style="color:#d63638; text-align:center; padding:10px;">⚠️ Network error.</div>');
        }).always(function() {
            nrosRadarFetchLock = false;
        });
    }

    function fetchTrends() {
        if (nrosFeatures.skip_radar) { return; }
        if (nrosRadarFetchLock) { return; }
        nrosRadarFetchLock = true;
        var geo = nrosResolveEditorGeo();
        var postId = nrosResolveEditorPostId();
        var targets = $('#nros-pane-trends, #newsai-trends-list, #sidebar-trends-list');
        
        nrosRenderRadarSkeleton(targets);
        $.post(newsai_vars.ajax_url, { action: 'newsai_get_trends', geo: geo, post_id: postId, nonce: newsai_vars.nonce }, function(response) {
            if(response.success) {
                targets.html(response.data);
                targets.attr('data-nros-radar-loaded', '1');
            }
            else {
                var msg = (response.data && response.data.message) ? response.data.message : '⚠️ Error.';
                targets.html('<div style="color:#9a3412; text-align:center; padding:10px; font-size:12px;">' + $('<div/>').text(msg).html() + '</div>');
            }
        }).fail(function() {
            targets.html('<div style="color:#d63638; text-align:center; padding:10px;">⚠️ Network error.</div>');
        }).always(function() {
            nrosRadarFetchLock = false;
        });
    }

    function nrosInitMobileBottomSheet() {
        var mobileSheetEnabled = !!nrosFeatures.mobile_bottom_sheet;
        if (!mobileSheetEnabled || window.innerWidth > 782) return;

        var box = $('#newsai_sidebar.postbox');
        if (!box.length || box.find('.nros-mobile-sheet-handle').length) return;

        box.addClass('nros-mobile-sheet');
        var inside = box.find('.inside').first();
        if (!inside.length) return;

        var handleLabel = isGr ? 'Newsroom OS εργαλεία' : 'Newsroom OS tools';
        var handle = $('<button type="button" class="nros-mobile-sheet-handle" aria-expanded="false">⬆️ ' + handleLabel + '</button>');
        box.prepend(handle);

        handle.on('click', function() {
            var open = box.hasClass('nros-mobile-open');
            box.toggleClass('nros-mobile-open', !open);
            handle.attr('aria-expanded', !open ? 'true' : 'false');
            handle.html((!open ? '⬇️ ' : '⬆️ ') + handleLabel);
        });
    }

    nrosInitMobileBottomSheet();
    // Lazy radar: editor sidebar loads on accordion/tab open; dashboard widget loads when visible.
    if (!nrosFeatures.lite_mode) {
        nrosMaybeFetchRadarTrends();
    }

    // ============================================================
    // AI Assist (Pro) — title suggestions, content optimization,
    // trend-aware keywords. BYOK; results go to #newsai-ai-output.
    // ============================================================
    (function initAiAssist() {
        var $root = $('#newsai-ai-assist');
        if (!$root.length) { return; }
        var $out = $('#newsai-ai-output');

        function isGutenberg() {
            return !!(window.wp && wp.data && wp.data.select && wp.data.select('core/editor'));
        }

        function getEditorContext() {
            var title = '';
            var content = '';
            if (isGutenberg()) {
                try {
                    var ed = wp.data.select('core/editor');
                    title = (ed.getEditedPostAttribute('title') || '') + '';
                    content = (ed.getEditedPostAttribute('content') || '') + '';
                } catch (e) { /* fall through */ }
            }
            if (!title) {
                var $t = $('#title');
                if ($t.length) { title = $t.val() || ''; }
            }
            if (!content) {
                if (window.tinymce && tinymce.get('content')) {
                    content = tinymce.get('content').getContent();
                } else {
                    var $c = $('#content');
                    if ($c.length) { content = $c.val() || ''; }
                }
            }
            return { title: title, content: content };
        }

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

        function setTitleEverywhere(newTitle) {
            if (isGutenberg()) {
                try { wp.data.dispatch('core/editor').editPost({ title: newTitle }); return true; } catch (e) {}
            }
            var $t = $('#title');
            if ($t.length) { $t.val(newTitle).trigger('input'); return true; }
            return false;
        }

        function renderAnalysisPanel(data) {
            var a = data && data.analysis;
            if (!a || (!a.primary_keyword && !a.primary_entity)) { return ''; }
            var html = '<div style="margin-bottom:10px;padding:10px;border:1px dashed #c7d2fe;border-radius:6px;background:#eef2ff;font-size:12px;color:#3730a3;">';
            html += '<div style="font-weight:700;margin-bottom:4px;">' + __('SEO analysis') + '</div>';
            html += '<div><strong>' + __('Primary keyword') + ':</strong> ' + escapeHtml(a.primary_keyword) + '</div>';
            if (a.primary_entity) {
                html += '<div><strong>' + __('Primary entity') + ':</strong> ' + escapeHtml(a.primary_entity) + '</div>';
            }
            if (a.article_type) {
                html += '<div><strong>' + __('Type') + ':</strong> ' + escapeHtml(a.article_type) + '</div>';
            }
            if (a.search_intent) {
                html += '<div><strong>' + __('Intent') + ':</strong> ' + escapeHtml(a.search_intent) + '</div>';
            }
            html += '</div>';
            return html;
        }

        function renderTitleSuggestions(data) {
            var rows = (data && data.suggestions) || [];
            if (!rows.length) {
                $out.html('<em>' + __('No suggestions returned.') + '</em>');
                return;
            }
            var angleLabels = {
                facts: __('Facts'),
                impact: __('Human impact'),
                aftermath: __('Aftermath'),
                authority: __('Authority'),
                curiosity: __('Discover hook')
            };
            var angleColors = { facts: '#0ea5e9', impact: '#a855f7', aftermath: '#f59e0b', authority: '#10b981', curiosity: '#ec4899' };
            var html = renderAnalysisPanel(data);
            html += '<div style="display:flex;flex-direction:column;gap:8px;">';
            html += '<div style="font-size:11px;color:#6b7280;margin-bottom:2px;">'
                 + __('🎯 Target: 55–70 characters for Google Discover & News.')
                 + '</div>';
            rows.forEach(function (r) {
                var chars = parseInt(r.chars, 10) || (typeof r.title === 'string' ? r.title.length : 0);
                var lenColor, lenLabel;
                if (chars >= 55 && chars <= 70) { lenColor = '#10b981'; lenLabel = __('Ideal'); }
                else if (chars >= 50 && chars <= 75) { lenColor = '#f59e0b'; lenLabel = __('OK'); }
                else { lenColor = '#dc2626'; lenLabel = __('Edge'); }

                html += '<div style="padding:10px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;">';
                html += '<div style="display:flex;justify-content:space-between;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:6px;">';
                if (r.angle && angleLabels[r.angle]) {
                    html += '<span style="font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:#fff;background:' + (angleColors[r.angle] || '#6b7280') + ';padding:2px 7px;border-radius:9px;font-weight:700;">' + escapeHtml(angleLabels[r.angle]) + '</span>';
                } else {
                    html += '<span></span>';
                }
                var scoreTxt = (typeof r.score === 'number' && r.score > 0) ? (' · SEO ' + r.score + '/10') : '';
                html += '<span title="' + escapeHtml(__('Character count')) + '" style="font-size:11px;font-weight:700;color:' + lenColor + ';">' + chars + ' ' + __('chars') + ' · ' + escapeHtml(lenLabel) + escapeHtml(scoreTxt) + '</span>';
                html += '</div>';
                html += '<div style="font-weight:600;color:#1f2937;line-height:1.35;font-size:14px;">' + escapeHtml(r.title) + '</div>';
                if (r.why) {
                    html += '<div style="color:#6b7280;font-size:12px;margin-top:4px;">' + escapeHtml(r.why) + '</div>';
                }
                html += '<div style="margin-top:8px;display:flex;gap:6px;">';
                html += '<button type="button" class="button button-primary newsai-ai-use-title" data-title="' + escapeHtml(r.title) + '">'
                     + __('Use') + '</button>';
                html += '</div></div>';
            });
            html += '</div>';
            $out.html(html);
            $out.off('click', '.newsai-ai-use-title').on('click', '.newsai-ai-use-title', function () {
                var t = $(this).data('title');
                if (t) { setTitleEverywhere(String(t)); }
            });
        }

        function renderOptimizeSuggestions(data) {
            var rows = (data && data.suggestions) || [];
            if (!rows.length) {
                $out.html('<em>' + __('No suggestions returned.') + '</em>');
                return;
            }
            var catColor = {
                readability: '#0ea5e9',
                seo: '#16a34a',
                eeat: '#7c3aed',
                structure: '#f59e0b',
                factcheck: '#dc2626'
            };
            var html = renderAnalysisPanel(data);
            html += '<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:8px;">';
            rows.forEach(function (r) {
                var color = catColor[r.category] || '#6b7280';
                html += '<li style="padding:10px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;">';
                html += '<div style="display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin-bottom:4px;">';
                html += '<span style="font-size:10px;text-transform:uppercase;letter-spacing:.04em;font-weight:700;color:#fff;background:' + color + ';padding:2px 6px;border-radius:3px;">' + escapeHtml(r.category) + '</span>';
                if (r.paragraph > 0) {
                    html += '<span style="font-size:11px;color:#6b7280;">' + __('Paragraph') + ' #' + (r.paragraph | 0) + '</span>';
                }
                html += '</div>';
                html += '<div style="color:#1f2937;line-height:1.4;">' + escapeHtml(r.suggestion) + '</div>';
                if (r.why) {
                    html += '<div style="color:#6b7280;font-size:12px;margin-top:4px;">' + escapeHtml(r.why) + '</div>';
                }
                html += '</li>';
            });
            html += '</ul>';
            $out.html(html);
        }

        function renderTrendKeywords(data) {
            var rows = (data && data.keywords) || [];
            if (!rows.length) {
                $out.html('<em>' + __('No trending keywords returned.') + '</em>');
                return;
            }
            var fitColor = { high: '#dc2626', medium: '#ea580c', low: '#9ca3af' };
            var html = renderAnalysisPanel(data);
            html += '<div style="display:flex;flex-direction:column;gap:8px;">';
            rows.forEach(function (r) {
                var fc = fitColor[r.fit] || '#6b7280';
                html += '<div style="padding:10px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;">';
                html += '<div style="display:flex;justify-content:space-between;gap:8px;align-items:center;flex-wrap:wrap;">';
                html += '<strong style="color:#1f2937;">' + escapeHtml(r.term) + '</strong>';
                html += '<span style="font-size:10px;text-transform:uppercase;letter-spacing:.04em;color:#fff;background:' + fc + ';padding:2px 6px;border-radius:3px;">' + escapeHtml(r.fit) + '</span>';
                if (r.intent_relation) {
                    html += '<span style="font-size:10px;color:#4b5563;">' + escapeHtml(r.intent_relation) + '</span>';
                }
                html += '</div>';
                html += '<div style="font-size:12px;color:#4b5563;margin-top:4px;"><strong>' + __('Placement') + ':</strong> ' + escapeHtml(r.placement) + '</div>';
                if (r.tip) {
                    html += '<div style="color:#6b7280;font-size:12px;margin-top:4px;">' + escapeHtml(r.tip) + '</div>';
                }
                html += '</div>';
            });
            html += '</div>';
            $out.html(html);
        }

        function nrosApplyMetaDescriptionToEditor(text) {
            var t = String(text || '').trim();
            if (!t) { return false; }
            var applied = false;
            if (isGutenberg() && typeof wp !== 'undefined' && wp.data && wp.data.dispatch) {
                try {
                    var meta = Object.assign({}, wp.data.select('core/editor').getEditedPostAttribute('meta') || {});
                    var hasYoast = typeof meta._yoast_wpseo_metadesc !== 'undefined' || document.querySelector('[class*="yoast"], [id*="yoast"]');
                    var hasRm = typeof meta.rank_math_description !== 'undefined' || document.querySelector('[class*="rank-math"], [id*="rank-math"]');
                    if (hasYoast) {
                        meta._yoast_wpseo_metadesc = t;
                        applied = true;
                    }
                    if (hasRm) {
                        meta.rank_math_description = t;
                        applied = true;
                    }
                    if (applied) {
                        wp.data.dispatch('core/editor').editPost({ meta: meta });
                    }
                    var ex = wp.data.select('core/editor').getEditedPostAttribute('excerpt');
                    if (!ex || String(ex).trim().length < 10) {
                        wp.data.dispatch('core/editor').editPost({ excerpt: t });
                        applied = true;
                    }
                } catch (e) {}
            }
            jQuery('textarea').each(function () {
                if (this.id === 'content') { return; }
                var $el = jQuery(this);
                if ($el.closest('[class*="rank-math"], [id*="rank-math"], [class*="yoast"], [id*="yoast"]').length) {
                    $el.val(t).trigger('input').trigger('change');
                    applied = true;
                }
            });
            var $excerpt = jQuery('#excerpt');
            if ($excerpt.length) {
                $excerpt.val(t).trigger('input');
                applied = true;
            }
            if (typeof nrosEvaluateArticle === 'function') {
                nrosEvaluateArticle();
            }
            return applied;
        }

        function renderMetaDescription(data) {
            var desc = data && data.meta_description ? String(data.meta_description) : '';
            if (!desc) {
                $out.html('<em>' + __('No meta description returned.') + '</em>');
                return;
            }
            var chars = parseInt(data.chars, 10) || desc.length;
            var lenColor = (chars >= 140 && chars <= 160) ? '#10b981' : ((chars >= 130 && chars <= 165) ? '#f59e0b' : '#dc2626');
            var html = renderAnalysisPanel(data);
            html += '<div style="padding:12px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;">';
            html += '<div style="font-size:11px;font-weight:700;color:' + lenColor + ';margin-bottom:8px;">' + chars + ' ' + __('characters') + ' · ' + __('Target: 140–160') + '</div>';
            html += '<p style="margin:0;color:#1f2937;line-height:1.45;font-size:14px;" id="newsai-ai-meta-desc-text">' + escapeHtml(desc) + '</p>';
            html += '<div style="margin-top:10px;display:flex;flex-wrap:wrap;gap:6px;">';
            html += '<button type="button" class="button newsai-ai-copy-meta">' + __('Copy') + '</button>';
            html += '<button type="button" class="button button-primary newsai-ai-apply-meta">' + __('Apply to SEO fields') + '</button>';
            html += '</div>';
            if (data.seo_targets && data.seo_targets.length) {
                html += '<div style="margin-top:6px;font-size:11px;color:#6b7280;">' + __('Writes to: ') + escapeHtml(data.seo_targets.join(', ')) + '</div>';
            }
            html += '</div>';
            $out.html(html);
            $out.off('click', '.newsai-ai-copy-meta').on('click', '.newsai-ai-copy-meta', function () {
                if (navigator.clipboard && navigator.clipboard.writeText) {
                    navigator.clipboard.writeText(desc);
                }
            });
            $out.off('click', '.newsai-ai-apply-meta').on('click', '.newsai-ai-apply-meta', function () {
                var m = desc;
                var postId = (typeof nrosResolveEditorPostId === 'function' ? nrosResolveEditorPostId() : 0) || (newsai_vars && newsai_vars.post_id) || 0;
                if (!postId) {
                    alert(__('Save the post first, then apply the meta description.'));
                    return;
                }
                var $applyBtn = $(this);
                $applyBtn.prop('disabled', true);
                $.post(newsai_vars.ajax_url, {
                    action: 'newsai_ai_apply_meta_description',
                    nonce: newsai_vars.nonce,
                    post_id: postId,
                    meta_description: m
                }).done(function (resp) {
                    if (!resp || !resp.success) {
                        alert(__('Could not save meta description.'));
                        return;
                    }
                    nrosApplyMetaDescriptionToEditor(m);
                    $out.append('<div style="margin-top:8px;font-size:12px;color:#059669;">' + __('Saved to SEO fields.') + '</div>');
                }).fail(function () {
                    alert(__('Could not save meta description.'));
                }).always(function () {
                    $applyBtn.prop('disabled', false);
                });
            });
        }

        function renderGeoSummary(data) {
            var summaryData = {
                heading: data && data.heading ? String(data.heading) : '',
                summary: data && data.summary ? String(data.summary) : '',
                qa: data && data.qa ? data.qa : []
            };
            var headingLabel = String(summaryData.heading || '').trim() || __('Quick answers');
            var block = typeof nrosBuildGeoSummaryHtml === 'function'
                ? nrosBuildGeoSummaryHtml(summaryData, headingLabel, true)
                : '';
            if (!block) {
                $out.html('<em>' + __('Could not build GEO summary.') + '</em>');
                return;
            }
            var html = renderAnalysisPanel(data);
            html += '<div style="padding:12px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;">';
            html += '<p style="margin:0 0 10px 0;font-size:12px;color:#6b7280;">' + __('Structured summary + Q&amp;A for AI Overviews. Inserts at the top of the article.') + '</p>';
            html += '<div style="max-height:220px;overflow:auto;font-size:13px;color:#1f2937;border:1px dashed #e5e7eb;padding:10px;border-radius:6px;background:#f9fafb;">' + block + '</div>';
            html += '<div style="margin-top:10px;display:flex;flex-wrap:wrap;gap:6px;">';
            html += '<button type="button" class="button button-primary newsai-ai-insert-geo-summary">' + __('Insert at top') + '</button>';
            html += '</div></div>';
            $out.html(html);
            $out.off('click', '.newsai-ai-insert-geo-summary').on('click', '.newsai-ai-insert-geo-summary', function () {
                if (typeof nrosInsertIntoEditor === 'function') {
                    nrosInsertIntoEditor(block, true);
                    nrosToast(__('GEO summary inserted.'));
                }
            });
        }

        $root.on('click', '.newsai-ai-action', function () {
            var task = String($(this).data('task') || '');
            if (!task) { return; }
            var ctx = getEditorContext();
            if (!ctx.content || ctx.content.replace(/<[^>]*>/g, '').trim().length < 50) {
                $out.html('<em style="color:#b91c1c;">' + __('Write a bit more content (≥50 characters) before asking the AI.') + '</em>');
                return;
            }
            var $btn = $(this);
            var origHtml = $btn.html();
            $btn.prop('disabled', true).html(__('⏳ Thinking…'));
            $out.html('<em style="color:#6b7280;">' + __('Waiting for AI response…') + '</em>');

            var actionMap = {
                title_suggest:    'newsai_ai_title_suggest',
                optimize_content: 'newsai_ai_optimize_content',
                trend_keywords:   'newsai_ai_trend_keywords',
                meta_description: 'newsai_ai_meta_description',
                geo_summary:      'newsai_ai_geo_summary'
            };
            var action = actionMap[task];
            if (!action) { $btn.prop('disabled', false).html(origHtml); return; }

            $.ajax({
                url: newsai_vars.ajax_url,
                type: 'POST',
                timeout: 90000,
                data: {
                    action: action,
                    nonce: newsai_vars.nonce,
                    post_id: newsai_vars.post_id,
                    title: ctx.title,
                    content: ctx.content
                }
            })
            .done(function (resp) {
                if (!resp || !resp.success) {
                    var msg = (resp && resp.data && resp.data.message) || __('AI error.');
                    $out.html('<em style="color:#b91c1c;">' + escapeHtml(String(msg)) + '</em>');
                    return;
                }
                var payload = resp.data || {};
                var data = payload.data || {};
                if (task === 'title_suggest') { renderTitleSuggestions(data); }
                else if (task === 'optimize_content') { renderOptimizeSuggestions(data); }
                else if (task === 'trend_keywords') { renderTrendKeywords(data); }
                else if (task === 'meta_description') { renderMetaDescription(data); }
                else if (task === 'geo_summary') { renderGeoSummary(data); }
                if (payload.cached) {
                    $out.append('<div style="margin-top:6px;font-size:11px;color:#9ca3af;">' + __('From cache') + '</div>');
                }
                if (typeof payload.remaining === 'number') {
                    $out.append('<div style="margin-top:2px;font-size:11px;color:#9ca3af;">' + __('Remaining today: ') + payload.remaining + '</div>');
                }
            })
            .fail(function (xhr, textStatus) {
                var msg = (xhr && xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) || '';
                if (textStatus === 'timeout') {
                    msg = __('AI request timed out. Check hosting outbound HTTPS to Google, API key, and Gemini model (gemini-2.5-flash).');
                }
                if (!msg) {
                    msg = __('Network error.');
                }
                $out.html('<em style="color:#b91c1c;">' + escapeHtml(String(msg)) + '</em>');
            })
            .always(function () {
                $btn.prop('disabled', false).html(origHtml);
            });
        });
    })();

    /* Author Performance: see assets/author-performance.js */
});