/**
 * Contentosapp Studio Dashboard Interactions
 *
 * Handles AJAX loading of dashboard data and skeleton unmasking.
 *
 * @package Contentosapp_Studio
 * @since   3.0.0
 */
/* global CostudioData */
(function ($) {
    'use strict';

    const data = window.CostudioData || {};
    const i18n = data.i18n || {};
    const licenseUrl = data.license_url || data.upgrade_url || 'admin.php?page=costudio-license';

    function t(key, fallback) {
        return (typeof i18n[key] === 'string' && i18n[key].length) ? i18n[key] : fallback;
    }

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

    const safeUrl = (url, fallback = '#') => {
        const value = String(url == null ? '' : url);
        return /^(https?:\/\/|admin\.php|\/(?!\/))/i.test(value) ? escapeHtml(value) : fallback;
    };

    const priorityLabel = (p) => {
        if (p === 'high')   return t('priority_high', 'High');
        if (p === 'medium') return t('priority_medium', 'Medium');
        if (p === 'low')    return t('priority_low', 'Low');
        return '';
    };

    let currentPeriod = 'this_month';
    let recentAllData = [];
    let currentStatusFilter = 'all';

    const artStatusPillClass = (status, published) => {
        if (status === 'completed' && published) return 'fos-status-pill--published';
        if (status === 'completed') return 'fos-status-pill--completed';
        if (status === 'running')   return 'fos-status-pill--running';
        if (status === 'pending')   return 'fos-status-pill--pending';
        if (status === 'paused')    return 'fos-status-pill--paused';
        if (status === 'error')          return 'fos-status-pill--error';
        if (status === 'pending_upgrade') return 'fos-status-pill--error';
        if (status === 'planned')        return 'fos-status-pill--planned';
        return 'fos-status-pill--draft';
    };

    const artStatusLabel = (status, published) => {
        if (status === 'completed' && published) return t('status_published', 'Published');
        if (status === 'completed') return t('status_completed_short', 'Done');
        if (status === 'running')   return t('status_running', 'Running');
        if (status === 'pending')   return t('status_pending', 'Pending');
        if (status === 'paused')    return t('status_paused', 'Paused');
        if (status === 'error')     return t('status_error', 'Error');
        if (status === 'pending_upgrade') return t('status_upgrade_required', 'Managed service quota needs attention');
        if (status === 'planned')   return t('status_planned', 'Planned');
        return t('status_draft', 'Draft');
    };

    const renderRecentTable = (items) => {
        const theadHtml = `<thead><tr>
            <th class="fos-dash-recent-table__col-title">${escapeHtml(t('col_article', 'Article'))}</th>
            <th class="fos-dash-recent-table__col-site">${escapeHtml(t('col_site', 'Site'))}</th>
            <th class="fos-dash-recent-table__col-priority">${escapeHtml(t('col_priority', 'Priority'))}</th>
            <th class="fos-dash-recent-table__col-date">${escapeHtml(t('col_date', 'Date'))}</th>
            <th class="fos-dash-recent-table__col-status">${escapeHtml(t('col_status', 'Status'))}</th>
        </tr></thead>`;

        let tbodyHtml = '';
        if (!items.length) {
            tbodyHtml = `<tr><td colspan="5" class="fos-dash-recent-empty">${t('dash_no_articles_yet', 'No articles generated yet.')}</td></tr>`;
        } else {
            items.forEach(art => {
                const priorityCell = art.priority
                    ? `<span class="fos-priority-badge fos-priority-badge--${escapeHtml(art.priority)}">${escapeHtml(priorityLabel(art.priority))}</span>`
                    : '<span class="fos-dash-recent-table__muted">—</span>';
                const artStatus = art.status || 'completed';
                tbodyHtml += `
                    <tr>
                        <td class="fos-dash-recent-table__title"><a href="${safeUrl(art.url)}" class="fos-dash-recent-table__link" title="${escapeHtml(art.title)}">${escapeHtml(art.title)}</a></td>
                        <td class="fos-dash-recent-table__site">${escapeHtml(art.site)}</td>
                        <td class="fos-dash-recent-table__priority">${priorityCell}</td>
                        <td class="fos-dash-recent-table__date">${escapeHtml(art.date)}</td>
                        <td class="fos-dash-recent-table__status"><span class="fos-status-pill ${artStatusPillClass(artStatus, art.published)}">${escapeHtml(artStatusLabel(artStatus, art.published))}</span></td>
                    </tr>`;
            });
        }
        return `<table class="fos-dash-recent-table">${theadHtml}<tbody>${tbodyHtml}</tbody></table>`;
    };

    const renderRecentFilters = (allItems) => {
        const counts = { all: allItems.length };
        allItems.forEach(art => {
            const s = art.status || 'completed';
            counts[s] = (counts[s] || 0) + 1;
        });

        const uniqueStatuses = Object.keys(counts).filter(k => k !== 'all').length;
        if (uniqueStatuses <= 1) return '';

        const filterDefs = [
            { key: 'all',       label: t('filter_all', 'All') },
            { key: 'running',   label: t('status_running', 'Running') },
            { key: 'pending',   label: t('status_pending', 'Pending') },
            { key: 'error',     label: t('status_error', 'Error') },
            { key: 'paused',    label: t('status_paused', 'Paused') },
            { key: 'planned',   label: t('status_planned', 'Planned') },
            { key: 'completed', label: t('status_completed_short', 'Done') },
        ];

        const pills = filterDefs
            .filter(f => f.key === 'all' || (counts[f.key] || 0) > 0)
            .map(f => {
                const count = counts[f.key] || 0;
                const isActive = f.key === currentStatusFilter;
                return `<button type="button" class="fos-dash-recent-filter-pill${isActive ? ' is-active' : ''}" data-filter="${escapeHtml(f.key)}">${escapeHtml(f.label)} <span class="fos-dash-recent-filter-pill__count">${count}</span></button>`;
            }).join('');

        return `<div class="fos-dash-recent-filters">${pills}</div>`;
    };

    const renderRecent = (allItems, filterKey) => {
        filterKey = filterKey || 'all';
        const filtered = filterKey === 'all' ? allItems : allItems.filter(a => (a.status || 'completed') === filterKey);
        $('#fos-recent-filters-root').html(renderRecentFilters(allItems));
        $('#fos-recent-root').html(renderRecentTable(filtered));
    };

    const ajaxErrorMessage = (res, fallback) => {
        const payload = res && res.data ? res.data : res;
        if (typeof payload === 'string' && payload.length) return payload;
        if (payload && typeof payload.message === 'string' && payload.message.length) return payload.message;
        return fallback;
    };

    const renderDashboardError = (message) => {
        const safeMessage = escapeHtml(message || t('dash_load_failed', 'Could not load dashboard data right now.'));
        const retryText = t('dash_try_refresh', 'Refresh the page or try again shortly.');
        const retryHtml = escapeHtml(retryText);

        $('.fos-skeleton-loading').removeClass('fos-skeleton-loading');

        $('#fos-plan-badge')
            .removeClass('cts-badge--success cts-badge--neutral fos-skeleton-loading')
            .addClass('cts-badge--warning')
            .text('!');

        $('#fos-dash-banner-root').html(
            '<div class="fos-dash-empty">' +
                '<div class="fos-dash-empty__icon">!</div>' +
                '<p>' + safeMessage + '</p>' +
            '</div>'
        );

        $('.fos-dash-metrics .fos-dash-metric__val').text('-');
        $('.fos-dash-metrics .fos-dash-metric__sub').text(retryText);
        $('#fos-dash-quota-root').html(
            '<div class="fos-dash-metric__capacity">' +
                '<div class="fos-dash-metric__capacity-row">' +
                    '<div class="fos-dash-metric__val">-</div>' +
                '</div>' +
                '<div class="fos-dash-metric__sub fos-dash-metric__breakdown">' + retryHtml + '</div>' +
            '</div>'
        );

        const $hItems = $('#fos-health-root .fos-dash-health-item');
        $hItems.find('.fos-dash-health-item__val').text('-');
        $hItems.find('.fos-dash-health-item__sub').text(message || t('dash_load_failed', 'Could not load dashboard data right now.'));

        $('#fos-queue-root').html('<div class="fos-dash-empty"><div class="fos-dash-empty__icon">!</div><p>' + safeMessage + '</p></div>');
        $('#fos-recent-root').html('<div class="fos-dash-empty"><div class="fos-dash-empty__icon">!</div><p>' + safeMessage + '</p></div>');
    };

    const loadDashboard = (period) => {
        const $app = $('#fos-dashboard-app');
        if (!$app.length) return;

        const ajax_url = data.ajax_url || '';
        const nonce = data.nonce || '';

        $.ajax({
            url: ajax_url,
            type: 'POST',
            data: {
                action: 'costudio_get_dashboard_data',
                nonce: nonce,
                period: period || 'this_month'
            },
            success: (res) => {
                if (!res || !res.success) {
                    renderDashboardError(ajaxErrorMessage(res, t('dash_load_failed', 'Could not load dashboard data right now.')));
                    return;
                }
                const d = res.data;

                // 1. Plan Badge
                $('#fos-plan-badge')
                    .removeClass('cts-badge--success cts-badge--warning cts-badge--neutral fos-skeleton-loading')
                    .addClass(d.plan.service_plan_active ? 'cts-badge--success' : 'cts-badge--neutral')
                    .text(d.plan.service_plan_name || d.plan.plan_name || 'AUTO');

                // 2. Banner
                let bannerHtml = '';
                if (d.live) {
                    const liveAgentQty = d.live.agent_qty || 6;
                    const liveCurrentAgent = Math.min(d.live.current_agent || 1, liveAgentQty);
                    const isPublishing = d.live.phase === 'publishing' || (d.live.current_agent || 1) > liveAgentQty;
                    const progress = Math.min(100, Math.round((liveCurrentAgent / liveAgentQty) * 100));
                    const liveStage = isPublishing
                        ? escapeHtml(d.live.agent_name || t('finalizing_publication', 'Finalizando publicação'))
                        : `${escapeHtml(t('agent_label', 'Agent'))} 0${liveCurrentAgent} - ${escapeHtml(d.live.agent_name)} ${escapeHtml(t('is_running', 'is running'))}`;
                    bannerHtml = `
                        <div class="fos-dash-live">
                            <div class="fos-dash-live__left">
                                <div class="fos-dash-live__dot"></div>
                                <div>
                                    <div class="fos-dash-live__label">${escapeHtml(t('dash_live_label', 'LIVE - PRODUCTION RUNNING'))}</div>
                                    <div class="fos-dash-live__title">${escapeHtml(d.live.title)} · ${escapeHtml(d.live.site)}</div>
                                </div>
                            </div>
                            <div class="fos-dash-live__right">
                                <div class="fos-dash-live__progress">
                                    <div class="fos-dash-live__pct">${progress}%</div>
                                    <div class="fos-dash-live__agent">${liveStage}</div>
                                    <div class="fos-dash-live__bar-wrap">
                                        <div class="fos-dash-live__bar-fill" style="width:${progress}%"></div>
                                    </div>
                                </div>
                                <a href="${safeUrl(d.live.url)}" class="fos-dash-live__btn">${escapeHtml(t('view', 'View'))} →</a>
                            </div>
                        </div>`;
                } else if (d.next_up) {
                    const pClass = d.next_up.priority === 'high' ? 'high' : (d.next_up.priority === 'low' ? 'low' : 'med');
                    bannerHtml = `
                        <div class="fos-dash-nextup">
                            <div class="fos-dash-nextup__priority fos-dash-nextup__priority--${pClass}"></div>
                            <span class="fos-dash-nextup__label">NEXT UP</span>
                            <span class="fos-dash-nextup__kw">${escapeHtml(d.next_up.keyword)}</span>
                            <div class="fos-dash-nextup__meta">
                                <span class="fos-dash-nextup__site">${escapeHtml(d.next_up.site)}</span>
                                ${d.next_up.category ? `<span class="fos-dash-nextup__cat">${escapeHtml(d.next_up.category)}</span>` : ''}
                            </div>
                            <a href="${safeUrl(d.next_up.url)}" class="fos-dash-nextup__btn fos-btn-pulse">🚀 ${escapeHtml(t('dash_produce_now', 'Produce now'))}</a>
                        </div>`;
                }
                $('#fos-dash-banner-root').html(bannerHtml);

                // Show welcome banner if user just exited the wizard.
                if (sessionStorage.getItem('costudio_from_wizard')) {
                    sessionStorage.removeItem('costudio_from_wizard');
                    $('#fos-welcome-banner').fadeIn(250);
                }

                // 3. Metrics
                const $metrics = $('.fos-dash-metrics .fos-dash-metric');
                $metrics.find('.fos-skeleton-loading').removeClass('fos-skeleton-loading');
                
                $metrics.eq(0).find('.fos-dash-metric__val').text(d.metrics.total);
                $metrics.eq(1).find('.fos-dash-metric__val').text(d.metrics.published);
                
                // Update the card label (e.g. "Published this month" vs "Last 90 days")
                if (d.metrics.main_label) {
                    $metrics.eq(1).find('.fos-dash-metric__label').text(d.metrics.main_label);
                }

                const deltaClass = d.metrics.diff > 0 ? 'fos-dash-delta-up' : (d.metrics.diff < 0 ? 'fos-dash-delta-down' : '');
                const deltaSymbol = d.metrics.diff > 0 ? '▲' : (d.metrics.diff < 0 ? '▼' : '→');
                const compareLabel = d.metrics.period_compare || t('dash_vs_last_month', 'vs last month');
                if (d.metrics.period === 'all' || !compareLabel) {
                    $metrics.eq(1).find('.fos-dash-metric__sub').text(t('dash_all_time', 'All time'));
                } else {
                    $metrics.eq(1).find('.fos-dash-metric__sub').html(`<span class="${deltaClass}">${deltaSymbol} ${Math.abs(d.metrics.diff)}</span> ${escapeHtml(compareLabel)}`);
                }
                $metrics.eq(2).find('.fos-dash-metric__val').text(d.metrics.hours + 'h');
                
                const articlesInPeriod = d.metrics.period_articles || 0;
                $metrics.eq(2).find('.fos-dash-metric__sub').text(`${articlesInPeriod} ${t('dash_articles', 'articles')} × 3.7h`);
                
                // 3.4 Quota Card — Headline (consumed) + Contextual Breakdown (Sprint B.2 v4)
                //
                // Headline = single number, what was produced this month
                //   (matches the card label "PRODUÇÕES / MÊS" literally).
                //
                // Breakdown explains the headline's composition + reveals
                //   the cap (since the headline itself is just one number):
                //     ⚡ X/Y plan    → ALWAYS shown (carries the cap context)
                //     ✨ N extras    → only when balance > 0 OR used_this_month > 0
                //                      (skipped on novato states to avoid "0 extras" noise)
                //     🔑 BYOK        → unlimited or remaining/cap
                //
                // Buy button — only when planning extras becomes relevant:
                //   - monthly_count >= 70% of service quota (warning zone), OR
                //   - already used some extras this month (engaged with feature)
                //   Otherwise hidden — avoids upsell pressure on relaxed states.
                //
                // Math sources (server-driven, fallbacks computed locally
                // for older API responses that may lack the new fields):
                //   monthly_count        — ContentOS Auto productions debited from service quota
                //   addon.used_this_month — Auto productions debited from extras this month
                //   addon.balance        — current extras saldo (persistent)
                //   byok_count           — productions using the user's own AI key
                const planLimit       = parseInt(d.plan.limit || 0, 10);
                const monthlyCount    = parseInt(d.plan.monthly_count || 0, 10);
                const byokCount       = parseInt(d.plan.byok_count || 0, 10);
                const addonEnabled    = !!(d.plan.addon && d.plan.addon.enabled);
                const addonBalance    = addonEnabled ? parseInt(d.plan.addon.balance || 0, 10) : 0;
                const addonUsedMonth  = addonEnabled && d.plan.addon.used_this_month
                    ? parseInt(d.plan.addon.used_this_month, 10)
                    : 0;
                const monthlyTotal    = parseInt(d.plan.monthly_total || (monthlyCount + addonUsedMonth + byokCount), 10);
                const planConsumed    = Math.min(monthlyCount, planLimit);

                const breakdownParts = [];
                breakdownParts.push(`⚡ ${planConsumed}/${planLimit} ${escapeHtml(t('dash_auto_short', 'plan'))}`);
                // Extras fragment only when meaningful — skip on "0 saldo, 0 usado"
                // so novato states don't carry a demoralizing "0 extras" line.
                if (addonEnabled && (addonBalance > 0 || addonUsedMonth > 0)) {
                    breakdownParts.push(`✨ ${addonBalance} ${escapeHtml(t('dash_extras_short', 'extras'))}`);
                }
                if (d.plan.byok_limit === 'unlimited') {
                    breakdownParts.push(`🔑 ${byokCount} ${escapeHtml(t('dash_byok_short', 'BYOK'))}`);
                } else {
                    breakdownParts.push(`🔑 ${byokCount}/${d.plan.byok_limit} ${escapeHtml(t('dash_byok_short', 'BYOK'))}`);
                }
                const breakdown = breakdownParts.join(' · ');

                // Buy button visibility: only when planning extras is relevant.
                // 70% threshold gives the user a real "I should think about
                // extras" window without firing off too early.
                const planUsageRatio  = planLimit > 0 ? (monthlyCount / planLimit) : 0;
                const showBuyBtn      = addonEnabled && (planUsageRatio >= 0.7 || addonUsedMonth > 0);
                const buyBtn          = showBuyBtn
                    ? `<button type="button" class="fos-dash-addon-buy" id="fos-dash-addon-buy" title="${escapeHtml(t('dash_addon_buy_title', 'Buy more credits'))}">+ ${escapeHtml(t('dash_addon_buy', 'Buy'))}</button>`
                    : '';

                const headlineHtml = `
                    <div class="fos-dash-metric__capacity">
                        <div class="fos-dash-metric__capacity-row">
                            <div class="fos-dash-metric__val">${monthlyTotal}</div>
                            ${buyBtn}
                        </div>
                        <div class="fos-dash-metric__sub fos-dash-metric__breakdown">${breakdown}</div>
                    </div>`;

                $('#fos-dash-quota-root').html(headlineHtml);

                // 4. System Health
                const h = d.health;
                const settings_url = data.settings_url || '';
                const license_url = licenseUrl;
                const $hItems = $('#fos-health-root .fos-dash-health-item');
                $hItems.find('.fos-skeleton-loading').removeClass('fos-skeleton-loading');

                $hItems.eq(0).find('.fos-dash-health-item__val').html(`<div class="fos-dash-dot ${h.ai.ok ? 'fos-dash-dot--ok' : 'fos-dash-dot--err'}"></div>${escapeHtml(h.ai.label)} ${h.ai.model ? `<span style="opacity:0.6; font-weight:400; margin-left:4px">${escapeHtml(h.ai.model)}</span>` : ''}`);
                $hItems.eq(0).find('.fos-dash-health-item__sub').html(h.ai.ok ? escapeHtml(t('api_key_saved', 'API key saved')) : `<a href="${safeUrl(settings_url)}" class="fos-dash-health-item__link">${escapeHtml(t('dash_configure_api', 'Configure API'))} →</a>`);

                const imgDotClass = h.img.ok ? 'fos-dash-dot--ok' : 'fos-dash-dot--err';
                let imgSub = h.img.sub || '';
                if (!imgSub) {
                    imgSub = h.img.ok ? escapeHtml(t('api_key_saved', 'API key saved')) : `<a href="${safeUrl(settings_url)}" class="fos-dash-health-item__link">${escapeHtml(t('dash_configure_api', 'Configure API'))} →</a>`;
                } else {
                    imgSub = escapeHtml(imgSub);
                }
                $hItems.eq(1).find('.fos-dash-health-item__val').html(`<div class="fos-dash-dot ${imgDotClass}"></div>${escapeHtml(h.img.label)} ${h.img.model ? `<span style="opacity:0.6; font-weight:400; margin-left:4px">${escapeHtml(h.img.model)}</span>` : ''}`);
                $hItems.eq(1).find('.fos-dash-health-item__sub').html(imgSub);

                $hItems.eq(2).find('.fos-dash-health-item__val').html(`<div class="fos-dash-dot ${h.sites.count > 0 ? 'fos-dash-dot--ok' : 'fos-dash-dot--warn'}"></div>${h.sites.count} / ${h.sites.limit}`);
                $hItems.eq(2).find('.fos-dash-health-item__sub').html(h.sites.count > 0 ? `${h.sites.count} ${escapeHtml(h.sites.count > 1 ? t('dash_sites_active', 'sites active') : t('dash_site_active', 'site active'))}` : `<a href="${safeUrl(settings_url)}" class="fos-dash-health-item__link">${escapeHtml(t('dash_connect_site', 'Connect a site'))} →</a>`);

                $hItems.eq(3).find('.fos-dash-health-item__val').html(`<div class="fos-dash-dot ${h.service_plan_active ? 'fos-dash-dot--ok' : 'fos-dash-dot--warn'}"></div>${escapeHtml(h.service_plan_active ? t('dash_pro_active', 'Service plan active') : t('dash_free_basic', 'Free plan'))}`);
                $hItems.eq(3).find('.fos-dash-health-item__sub').html(h.service_plan_active ? escapeHtml(t('dash_unlimited_access', 'BYOK remains unlimited')) : `<a href="${safeUrl(license_url)}" class="fos-dash-health-item__link">${escapeHtml(t('dash_upgrade_pro', 'Manage service plan'))} →</a>`);

                // 5. Production Queue
                const queueData = d.queue || {};
                const queueItems = Array.isArray(queueData.items)
                    ? queueData.items
                    : (Array.isArray(d.queue) ? d.queue : []);
                const pendingTotal = parseInt(queueData.pending_total != null ? queueData.pending_total : queueItems.length, 10) || 0;
                const runningTotal = parseInt(queueData.running_total != null ? queueData.running_total : (d.live ? 1 : 0), 10) || 0;
                const slotBusy = runningTotal > 0;
                const slotText = slotBusy ? t('dash_queue_slot_busy', 'Slot busy') : t('dash_queue_slot_free', 'Slot free');

                let qHtml = `
                    <div class="fos-dash-queue-summary fos-dash-queue-summary--${slotBusy ? 'busy' : 'free'}">
                        <div>
                            <div class="fos-dash-queue-summary__label">${escapeHtml(t('dash_production_queue', 'Production queue'))}</div>
                            <div class="fos-dash-queue-summary__value">${pendingTotal} ${escapeHtml(t('dash_queue_waiting', 'waiting'))}</div>
                        </div>
                        <div class="fos-dash-queue-summary__slot">${escapeHtml(slotText)}</div>
                    </div>`;

                if (queueItems.length) {
                    queueItems.forEach(item => {
                        const pClass = item.priority === 'high' ? 'high' : (item.priority === 'low' ? 'low' : (item.priority === 'medium' ? 'med' : 'neutral'));
                        const title = item.title || item.keyword || '';
                        const position = parseInt(item.position || 0, 10) || '';
                        const agentName = item.agent_name || (t('agent_label', 'Agent') + ' ' + (item.current_agent || ''));
                        qHtml += `
                            <a href="${safeUrl(item.url)}" class="fos-dash-queue-item">
                                <div class="fos-dash-queue-item__pos">${position ? '#' + escapeHtml(position) : '-'}</div>
                                <div class="fos-dash-priority fos-dash-priority--${pClass}"></div>
                                <div class="fos-dash-queue-item__info">
                                    <div class="fos-dash-queue-item__kw">${escapeHtml(title)}</div>
                                    <div class="fos-dash-queue-item__meta">
                                        <span class="fos-dash-queue-item__site">${escapeHtml(item.site || '')}</span>
                                        <span class="fos-dash-queue-item__cat">${escapeHtml(agentName)}</span>
                                        ${item.created_at ? `<span class="fos-dash-queue-item__cat">${escapeHtml(item.created_at)}</span>` : ''}
                                    </div>
                                </div>
                                <div class="fos-dash-queue-item__rocket">→</div>
                            </a>`;
                    });
                } else {
                    const emptyText = slotBusy
                        ? t('dash_queue_none_waiting_busy', 'No productions waiting. The local slot is currently busy.')
                        : t('dash_queue_none_waiting_free', 'No productions waiting. The local slot is free.');
                    qHtml += '<div class="fos-dash-empty"><div class="fos-dash-empty__icon">✓</div><p>' + escapeHtml(emptyText) + '</p></div>';
                }

                $('#fos-queue-root').html(qHtml);

                // 6. Recent
                recentAllData = d.recent || [];
                currentStatusFilter = 'all';
                if (recentAllData.length) {
                    renderRecent(recentAllData, 'all');
                } else {
                    $('#fos-recent-root').html('<div class="fos-dash-empty"><div class="fos-dash-empty__icon">📝</div><p>' + t('dash_no_articles_yet', 'No articles generated yet.') + '</p></div>');
                }

                // 7. Unmask static elements (Quick Actions and Footers)
                $('.fos-skeleton-loading').removeClass('fos-skeleton-loading');
                
                // 8. Update dynamic license sub text in Quick Actions
                $('#fos-actions-root .fos-dash-action-item').last().find('.fos-dash-action-item__sub').text(d.plan.service_plan_active ? t('dash_pro_active', 'Service plan active') : t('dash_free_upgrade', 'Choose a service plan'));
            },
            error: (xhr) => {
                renderDashboardError(ajaxErrorMessage(xhr && xhr.responseJSON ? xhr.responseJSON : null, t('dash_load_failed', 'Could not load dashboard data right now.')));
            }
        });
    };

    const bindRecentFilters = () => {
        $(document).on('click', '.fos-dash-recent-filter-pill', function () {
            const filterKey = $(this).data('filter') || 'all';
            if (filterKey === currentStatusFilter) return;
            currentStatusFilter = filterKey;
            $('.fos-dash-recent-filter-pill')
                .removeClass('is-active')
                .filter(`[data-filter="${filterKey}"]`)
                .addClass('is-active');
            const filtered = filterKey === 'all' ? recentAllData : recentAllData.filter(a => (a.status || 'completed') === filterKey);
            $('#fos-recent-root').html(renderRecentTable(filtered));
        });
    };

    const bindPeriodPills = () => {
        $(document).on('click', '#fos-dash-period .fos-dash-period__pill', function () {
            const $pill = $(this);
            const period = $pill.data('period');
            if (!period || period === currentPeriod) return;

            currentPeriod = period;
            currentStatusFilter = 'all';

            $('#fos-dash-period .fos-dash-period__pill')
                .removeClass('is-active')
                .attr('aria-selected', 'false');
            $pill.addClass('is-active').attr('aria-selected', 'true');

            // Skeleton flash for metrics + recent while reloading.
            $('.fos-dash-metrics .fos-dash-metric__val, .fos-dash-metrics .fos-dash-metric__sub')
                .find('span').addClass('fos-skeleton-loading');
            $('#fos-recent-root').html('<div class="fos-dash-recent-loading"><span class="fos-skeleton-loading">' + t('loading', 'Loading…') + '</span></div>');

            loadDashboard(period);
        });
    };

    const bindSyncQuota = () => {
        $(document).on('click', '#fos-dash-sync-quota', function (e) {
            e.preventDefault();
            const $btn = $(this);
            if ($btn.hasClass('is-spinning')) return;

            const ajax_url = data.ajax_url || '';
            const nonce = data.nonce || '';

            $btn.addClass('is-spinning');
            
            // Fade out current values to show something is happening.
            $('#fos-dash-quota-root .fos-dash-metric__val').css('opacity', 0.5);

            $.ajax({
                url: ajax_url,
                type: 'POST',
                data: {
                    action: 'costudio_sync_license_quota',
                    nonce: nonce
                },
                success: (res) => {
                    $btn.removeClass('is-spinning');
                    if (!res.success) {
                        alert(res.data || t('sync_failed', 'Sync failed.'));
                        $('#fos-dash-quota-root .fos-dash-metric__val').css('opacity', 1);
                        return;
                    }
                    
                    // Success! Refresh the whole dashboard data to update everything.
                    loadDashboard(currentPeriod);
                },
                error: () => {
                    $btn.removeClass('is-spinning');
                    $('#fos-dash-quota-root .fos-dash-metric__val').css('opacity', 1);
                }
            });
        });
    };

    /**
     * Sprint B.2 — "+ Buy" button on the Extra Quotas dashboard row.
     *
     * Delegates to window.costudioAddonModal() if Sprint B.3's modal is
     * loaded; otherwise links straight to the License page where the same
     * placeholder lives. Either way the user reaches a working surface.
     */
    const bindAddonBuy = () => {
        $(document).on('click', '#fos-dash-addon-buy', function (e) {
            e.preventDefault();
            if (typeof window.costudioAddonModal === 'function') {
                window.costudioAddonModal();
                return;
            }
            window.location.href = licenseUrl;
        });
    };

    $(document).ready(function () {
        bindPeriodPills();
        bindSyncQuota();
        bindAddonBuy();
        bindRecentFilters();
        loadDashboard(currentPeriod);
    });

})(jQuery);
