(function($){
        // Toast, overlays, and loader UI
// Toast notification system - COMPATIBLE WITH ALL VMO CALLS
window.showToast = function(message, type = 'info', loading = false, sticky = false, callback = null) {
    // Remove existing toast
    $('.vmo-toast').remove();
    
    // Handle different parameter combinations for backward compatibility
    let isGenerating = loading;
    let persistent = sticky;
    
    // Create toast element
    const toast = $(`
        <div class="vmo-toast vmo-toast-${type}">
            <div class="vmo-toast-content">
                <span class="vmo-toast-message">${message}</span>
                ${!persistent && !isGenerating ? '<button class="vmo-toast-close" style="position: absolute; top: 5px; right: 8px; border: none; background: none; font-size: 16px; cursor: pointer; color: #999;">&times;</button>' : ''}
            </div>
            ${isGenerating ? '<div class="vmo-loading-spinner"></div>' : ''}
        </div>
    `);
    
    $('body').append(toast);
    
    // Add click handlers
    toast.find('.vmo-toast-close').on('click', function() {
        hideToast();
        if (callback && typeof callback === 'function') {
            callback();
        }
    });
    
    // Auto-hide non-persistent toasts
    if (!persistent && !isGenerating) {
        setTimeout(() => {
            hideToast();
            if (callback && typeof callback === 'function') {
                callback();
            }
        }, 3000);
    }
    
    // Voice feedback integration
    if (window.vmoVoiceToastHandler) {
        window.vmoVoiceToastHandler(message, type);
    }
};

window.hideToast = function(force = false) {
    $('.vmo-toast').remove();
};

/**
 * 🚀 CREDIT ENFORCEMENT: Persuasive insufficient credits toast
 * Shows when user runs out of subscription credit with upgrade/topup buttons
 * User-facing: "subscription credit" (never "tokens")
 */
window.showInsufficientCreditsToast = function(customMessage = null) {
    // Remove any existing toasts first
    $('.vmo-toast').remove();
    $('.vmo-credit-toast').remove();
    
    // Get URLs from localized data. Prefer the in-plugin "My Plan" page, deep
    // linked to the relevant section so the option the user picks is shown first.
    const ajaxData = window.vmo_ajax || window.vmoAjax || {};
    const upgradeUrl = ajaxData.myPlanPlansUrl ||
                       ajaxData.upgradeUrl ||
                       'https://jerremejosephson.com/vmo-upgrade/';
    const topupUrl = ajaxData.myPlanBoostersUrl ||
                     ajaxData.topupUrl ||
                     'https://jerremejosephson.com/vmo-topup/';
    // In-plugin deep links should open in the same tab so the anchor scroll +
    // highlight runs; external fallbacks open in a new tab.
    const upgradeTarget = ajaxData.myPlanPlansUrl ? '_self' : '_blank';
    const topupTarget = ajaxData.myPlanBoostersUrl ? '_self' : '_blank';
    
    // Persuasive, encouraging messages (rotated)
    const messages = [
        "Your VMO Credit balance is empty. Add a one-time booster or upgrade to a higher-credit plan to continue metered actions.",
        "This task needs more VMO Credit before it can continue. Add credit to keep working.",
        "Metered plugin actions need available VMO Credit. Add a booster or upgrade your plan.",
        "Your available VMO Credit has been used up. Add a booster or choose a higher-credit plan."
    ];
    const message = customMessage || messages[Math.floor(Math.random() * messages.length)];
    
    // Create styled toast with CTA buttons
    const toast = $(`
        <div class="vmo-credit-toast vmo-toast-warning">
            <div class="vmo-credit-toast-content">
                <div class="vmo-credit-toast-icon">⚡</div>
                <div class="vmo-credit-toast-message">
                    <p>${message}</p>
                </div>
                <div class="vmo-credit-toast-actions">
                    <a href="${topupUrl}" target="${topupTarget}" class="vmo-credit-btn vmo-credit-btn-topup">
                        Buy One-Time Booster
                    </a>
                    <a href="${upgradeUrl}" target="${upgradeTarget}" class="vmo-credit-btn vmo-credit-btn-upgrade">
                        Upgrade Plan
                    </a>
                </div>
                <button class="vmo-credit-toast-close">&times;</button>
            </div>
        </div>
    `);
    
    $('body').append(toast);
    
    // Close button handler
    toast.find('.vmo-credit-toast-close').on('click', function() {
        toast.fadeOut(300, function() { $(this).remove(); });
    });
    
    // Auto-hide after 12 seconds (long enough to read and click)
    setTimeout(() => {
        toast.fadeOut(300, function() { $(this).remove(); });
    }, 12000);
    
    // Optional voice feedback
    if (window.vmoVoiceToastHandler) {
        window.vmoVoiceToastHandler('Your available VMO Credit has been used up. Please add a booster or upgrade to continue metered actions.', 'warning');
    }
    
    console.log('[VMO] Credit enforcement toast shown');
};

window.showLowCreditsToast = function(status = {}, customMessage = null) {
    $('.vmo-toast').remove();
    $('.vmo-credit-toast').remove();

    const ajax = window.vmo_ajax || window.vmoAjax || {};
    const upgradeUrl = ajax.myPlanPlansUrl || ajax.upgradeUrl || 'https://jerremejosephson.com/vmo-upgrade/';
    const topupUrl = ajax.myPlanBoostersUrl || ajax.topupUrl || 'https://jerremejosephson.com/vmo-topup/';
    const upgradeTarget = ajax.myPlanPlansUrl ? '_self' : '_blank';
    const topupTarget = ajax.myPlanBoostersUrl ? '_self' : '_blank';
    const balance = Number(status.balance ?? ajax.token_balance ?? 0);
    const percent = Number(status.remaining_percent ?? ajax.credit_remaining_percent ?? 0);
    const nextPlan = status.next_plan || ajax.next_plan || 'the next plan';
    const percentText = Number.isFinite(percent) ? Math.max(0, Math.min(100, percent)).toFixed(percent % 1 === 0 ? 0 : 1) : '40';
    const balanceText = Number.isFinite(balance) ? Math.max(0, balance).toLocaleString() : 'low';
    const warningLevel = status.credit_warning_level || ajax.credit_warning_level || (status.critical_credit || ajax.critical_credit ? 'critical' : 'low');
    const isCritical = warningLevel === 'critical' || status.critical_credit === true || ajax.critical_credit === true;
    const messages = isCritical ? [
        `Critical VMO Credit warning: ${percentText}% remains (${balanceText} credits). Temporary pauses can hit AI, phone, SMS, email, media, and automation if credit reaches zero. Recurring provider services may be suspended or cancelled after the grace period.`,
        `Only ${percentText}% of VMO Credit remains. Add credit now to avoid losing plugin services temporarily and provider-backed services after the grace period.`,
        `VMO Credit is critically low at ${percentText}%. Refill before the balance reaches zero so AI, phone, SMS, email, and recurring provider services keep running.`
    ] : [
        `Your VMO Credit balance is down to ${percentText}% (${balanceText} credits). Upgrade to ${nextPlan} or buy a one-time booster before larger tasks pause.`,
        `Credit is getting low: ${percentText}% remains. Add a booster or move to ${nextPlan} so the task you are working on can finish cleanly.`,
        `Heads up: only ${percentText}% of your VMO Credit remains. Refill now to avoid a hard stop in the plugin.`
    ];
    const message = customMessage || messages[Math.floor(Math.random() * messages.length)];

    const toast = $(`
        <div class="vmo-credit-toast vmo-toast-warning vmo-credit-toast-low ${isCritical ? 'vmo-credit-toast-critical' : ''}">
            <div class="vmo-credit-toast-content">
                <div class="vmo-credit-toast-icon">!</div>
                <div class="vmo-credit-toast-message">
                    <p>${message}</p>
                </div>
                <div class="vmo-credit-toast-actions">
                    <a href="${topupUrl}" target="${topupTarget}" class="vmo-credit-btn vmo-credit-btn-topup">
                        Buy One-Time Booster
                    </a>
                    <a href="${upgradeUrl}" target="${upgradeTarget}" class="vmo-credit-btn vmo-credit-btn-upgrade">
                        Upgrade Plan
                    </a>
                </div>
                <button class="vmo-credit-toast-close">&times;</button>
            </div>
        </div>
    `);

    $('body').append(toast);
    toast.find('.vmo-credit-toast-close').on('click', function() {
        toast.fadeOut(300, function() { $(this).remove(); });
    });
    setTimeout(() => {
        toast.fadeOut(300, function() { $(this).remove(); });
    }, 12000);

    if (window.vmoVoiceToastHandler) {
        window.vmoVoiceToastHandler(isCritical ? 'Your VMO Credit balance is critically low. Please add credit now to avoid service interruptions.' : 'Your VMO Credit balance is running low. Please add a booster or upgrade soon.', 'warning');
    }
};

/**
 * Global AJAX response interceptor for credit enforcement
 * Catches 'insufficient_tokens' status and shows persuasive toast
 */
window.vmoHandleAjaxResponse = function(response) {
    if (response && (response.status === 'insufficient_tokens' || response.status === 'service_locked' ||
                     (response.data && response.data.status === 'insufficient_tokens') ||
                     (response.data && response.data.status === 'service_locked') ||
                     response.success === false && response.data && (response.data.code === 'insufficient_tokens' || response.data.code === 'service_locked'))) {
        const status = response.data && response.data.credit_status ? response.data.credit_status : {};
        window.showInsufficientCreditsToast((response.data && response.data.message) || response.message || null, status);
        return false; // Indicates insufficient credits
    }
    return true; // Normal response
};
    
    // === Preset Toggle Buttons Functionality ===
    
    // Handle menu button click (special case)
    $(document).on('click', '.vmo-preset-btn[data-action="menu"]', function() {
        $('#vmo-menu-modal').show();
        $('#vmo-preview-iframe').css('visibility', 'hidden');
    });

    // Handle category toggle buttons
    $(document).on('click', '.vmo-preset-btn[data-category]', function() {
        const category = $(this).data('category');
        const $content = $(`.vmo-preset-content[data-category="${category}"]`);
        
        // Hide all other preset contents
        $('.vmo-preset-content').not($content).slideUp(200);
        
        // Toggle current content
        $content.slideToggle(300);
        
        // Update button states
        $('.vmo-preset-btn[data-category]').removeClass('vmo-preset-btn-active');
        if ($content.is(':visible') || $content.is(':animated')) {
            $(this).addClass('vmo-preset-btn-active');
        }
    });

    // Handle individual preset prompt clicks
    $(document).on('click', '.vmo-preset-content li[data-prompt]', function() {
        const prompt = $(this).data('prompt');
        $('#vmo-prompt-input').val(prompt).focus();
        
        // Hide all preset contents after selection
        $('.vmo-preset-content').slideUp(200);
        $('.vmo-preset-btn[data-category]').removeClass('vmo-preset-btn-active');
        
        // Show success message
        if (typeof window.showToast === 'function') {
            window.showToast('Prompt loaded! Click SEND to generate.', 'success');
        }
    });

    // Initialize: Hide all preset contents on load
    $(document).ready(function() {
        $('.vmo-preset-content').hide();
    });
    
    // ═══════════════════════════════════════════════════════════════════════════════
    // 🔄 RESET BUILDER MODAL, BACKUPS, AND RESTORE HANDLERS
    // ═══════════════════════════════════════════════════════════════════════════════

    $(document).on('click', '#vmo-open-reset-builder', function(e) {
        e.preventDefault();
        window.vmoResetProgressUi.reset();
        window.vmoSetResetModalVisibility(true);
        window.vmoLoadBuilderBackups(false);
    });

    $(document).on('click', '#vmo-refresh-reset-backups', function(e) {
        e.preventDefault();
        window.vmoLoadBuilderBackups(true);
    });

    $(document).on('click', '#vmo-reset-close, #vmo-reset-cancel, .vmo-reset-modal-overlay', function(e) {
        e.preventDefault();
        if (window.vmoResetInProgress) {
            return;
        }
        window.vmoResetProgressUi.reset();
        window.vmoSetResetModalVisibility(false);
    });

    $(document).on('click', '#vmo-reset-confirm', function(e) {
        e.preventDefault();
        window.vmoResetBuilder();
    });

    $(document).on('click', '.vmo-reset-restore-btn', function(e) {
        e.preventDefault();
        const backupId = $(this).data('backupId');
        if (backupId) {
            window.vmoRestoreBuilderBackup(String(backupId));
        }
    });

})(jQuery);

/**
 * Shared helper to clear browser-side builder state before reload.
 */
window.vmoClearBuilderStorage = function() {
    const keysToRemove = [];

    for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        if (key && (key.includes('vmo') || key.includes('consultation') || key.includes('VMO'))) {
            keysToRemove.push(key);
        }
    }

    if (typeof window.vmoClearStoredCheckpoint === 'function') {
        window.vmoClearStoredCheckpoint();
    }

    keysToRemove.forEach((key) => localStorage.removeItem(key));

    for (let i = sessionStorage.length - 1; i >= 0; i--) {
        const key = sessionStorage.key(i);
        if (key && (key.includes('vmo') || key.includes('consultation') || key.includes('VMO'))) {
            sessionStorage.removeItem(key);
        }
    }

    try {
        sessionStorage.removeItem('builder_reset_blank_pending');
        sessionStorage.removeItem('builder_reset_demo_pending');
    } catch (_) {}

    window.vmoConsultationSessionId = '';
    window.vmoCurrentConsultationSessionId = '';
    window._vmoIntelligentConsultationActive = false;
    window.currentProjectId = null;
    window.currentProjectTitle = null;
    window.currentLivePageId = null;
    window.vmoLivePermalink = '';
    window.lastContent = '';
    window.vmoHasContent = false;
    window.vmoPreviewIsLive = false;
    window.isUnsaved = false;
    window.isGenerating = false;
    window.vmoShowcasePreviewHtml = '';
    window.vmoShowcaseMediaPromise = null;

    if (window.vmoState && typeof window.vmoState === 'object') {
        window.vmoState = { blocks: [] };
    }

    const promptInput = document.getElementById('vmo-prompt-input');
    if (promptInput) {
        promptInput.value = '';
    }

    const chatHistory = document.getElementById('vmo-chat-history');
    if (chatHistory) {
        chatHistory.innerHTML = '';
    }

    const voiceHistory = document.getElementById('vmo-voice-chat-history');
    if (voiceHistory) {
        voiceHistory.innerHTML = '';
    }

    const voiceStatus = document.getElementById('vmo-voice-status');
    if (voiceStatus) {
        voiceStatus.textContent = 'Voice Consultation Stopped';
    }

    const codeView = document.getElementById('vmo-code-view');
    if (codeView) {
        codeView.value = '';
        codeView.style.display = 'none';
    }
};

window.vmoResetInProgress = false;

window.vmoSetResetModalVisibility = function(isVisible) {
    const modal = document.getElementById('vmo-reset-modal');
    if (!modal) {
        return;
    }

    if (isVisible) {
        modal.style.display = 'flex';
        modal.removeAttribute('hidden');
        modal.setAttribute('aria-hidden', 'false');
        return;
    }

    modal.style.display = 'none';
    modal.setAttribute('aria-hidden', 'true');
};

window.vmoResetToastUi = {
    ensure: function() {
        const $ = jQuery;
        if ($('#vmo-reset-progress-toast').length) {
            return $('#vmo-reset-progress-toast');
        }

        const toast = $(
            '<div id="vmo-reset-progress-toast" style="display:none;position:fixed;inset:0;z-index:1000001;align-items:center;justify-content:center;padding:20px;background:rgba(2,6,16,0.62);backdrop-filter:blur(10px);">'
                + '<div style="width:min(460px,calc(100vw - 32px));padding:22px 22px 18px;border-radius:26px;background:rgba(6,13,24,0.96);border:1px solid rgba(96,165,250,0.26);box-shadow:0 32px 100px rgba(0,0,0,0.42);color:#f8fafc;">'
                + '<div style="display:flex;align-items:flex-start;justify-content:space-between;gap:14px;">'
                + '<div style="display:flex;gap:14px;align-items:flex-start;">'
                + '<div style="width:22px;height:22px;border:2px solid rgba(148,163,184,0.28);border-top-color:#67e8f9;border-radius:999px;animation:vmoResetToastSpin 0.9s linear infinite;flex:0 0 auto;margin-top:2px;"></div>'
                + '<div>'
                + '<div style="font-size:12px;letter-spacing:0.18em;text-transform:uppercase;font-weight:800;color:#67e8f9;">Reset Builder</div>'
                + '<div id="vmo-reset-toast-status" style="margin-top:8px;font-size:18px;line-height:1.4;font-weight:800;color:#f8fafc;">Creating a protected backup...</div>'
                + '<div id="vmo-reset-toast-stage" style="margin-top:6px;font-size:13px;line-height:1.55;color:#cbd5e1;">Preparing Reset Builder</div>'
                + '</div>'
                + '</div>'
                + '<div id="vmo-reset-toast-value" style="font-size:16px;font-weight:800;color:#e2e8f0;white-space:nowrap;">0%</div>'
                + '</div>'
                + '<div style="margin-top:16px;height:10px;border-radius:999px;background:rgba(148,163,184,0.18);overflow:hidden;">'
                + '<div id="vmo-reset-toast-fill" style="height:100%;width:0%;border-radius:999px;background:linear-gradient(90deg,#22d3ee,#60a5fa,#a78bfa);"></div>'
                + '</div>'
                + '<div style="margin-top:12px;font-size:12px;line-height:1.5;color:#94a3b8;">Please wait while VMO secures a backup, clears the current builder state, and leaves the preview blank.</div>'
                + '</div>'
                + '<style>@keyframes vmoResetToastSpin{to{transform:rotate(360deg);}}</style>'
                + '</div>'
        );

        $('body').append(toast);
        return toast;
    },

    show: function() {
        this.ensure().css('display', 'flex').hide().stop(true, true).fadeIn(120);
    },

    update: function(percent, status, stage) {
        const safePercent = Math.max(0, Math.min(100, Math.round(percent || 0)));
        const toast = this.ensure();
        toast.find('#vmo-reset-toast-status').text(status || 'Resetting Builder...');
        toast.find('#vmo-reset-toast-stage').text(stage || 'Working');
        toast.find('#vmo-reset-toast-value').text(safePercent + '%');
        toast.find('#vmo-reset-toast-fill').css('width', safePercent + '%');
    },

    hide: function() {
        const $ = jQuery;
        $('#vmo-reset-progress-toast').stop(true, true).fadeOut(160, function() {
            $(this).remove();
        });
    }
};

window.vmoResetProgressUi = {
    reset: function() {
        const $ = jQuery;
        $('#vmo-reset-modal').removeClass('is-resetting');
        $('#vmo-reset-progress').prop('hidden', true);
        $('#vmo-reset-progress-status').text('Creating a protected backup...');
        $('#vmo-reset-progress-stage').text('Preparing Reset Builder');
        $('#vmo-reset-progress-value').text('0%');
        $('#vmo-reset-progress-fill').css('width', '0%');
        $('.vmo-reset-progress-bar').attr('aria-valuenow', '0');
        $('#vmo-reset-confirm').prop('disabled', false).text('🗑️ Yes, Reset Builder');
        $('#vmo-reset-cancel, #vmo-reset-close').prop('disabled', false);
        window.vmoResetInProgress = false;
        if (window.vmoResetToastUi) {
            window.vmoResetToastUi.hide();
        }
    },

    begin: function() {
        const $ = jQuery;
        $('#vmo-reset-modal').addClass('is-resetting');
        $('#vmo-reset-progress').prop('hidden', false);
        $('#vmo-reset-confirm').prop('disabled', true).text('Resetting Builder...');
        $('#vmo-reset-cancel, #vmo-reset-close').prop('disabled', true);
        window.vmoResetInProgress = true;
        if (window.vmoResetToastUi) {
            window.vmoResetToastUi.show();
        }
    },

    update: function(percent, status, stage) {
        const safePercent = Math.max(0, Math.min(100, Math.round(percent || 0)));
        const statusNode = document.getElementById('vmo-reset-progress-status');
        const stageNode = document.getElementById('vmo-reset-progress-stage');
        const valueNode = document.getElementById('vmo-reset-progress-value');
        const fillNode = document.getElementById('vmo-reset-progress-fill');
        if (status && statusNode) {
            statusNode.textContent = status;
        }
        if (stage && stageNode) {
            stageNode.textContent = stage;
        }
        if (valueNode) {
            valueNode.textContent = safePercent + '%';
        }
        if (fillNode) {
            fillNode.style.width = safePercent + '%';
        }
        const progressBar = document.querySelector('.vmo-reset-progress-bar');
        if (progressBar) {
            progressBar.setAttribute('aria-valuenow', String(safePercent));
        }
        if (window.vmoResetToastUi) {
            window.vmoResetToastUi.update(safePercent, status, stage);
        }
    }
};

window.vmoShowBuilderResetCompleteDialog = function(details = {}) {
    const $ = jQuery;
    const backupId = details.backup_id ? String(details.backup_id) : '';
    const message = details.message || 'The active website instance has been archived, the builder preview has been returned to its shipped starting state, and your three newest Reset Builder backups remain available from Builder Safety Tools.';

    let $modal = $('#vmo-builder-reset-complete-modal');
    if (!$modal.length) {
        $modal = $(
            '<div id="vmo-builder-reset-complete-modal" style="display:none;position:fixed;inset:0;z-index:1000002;align-items:center;justify-content:center;padding:20px;background:rgba(2,6,16,0.58);backdrop-filter:blur(8px);">'
                + '<div role="dialog" aria-modal="true" aria-labelledby="vmo-builder-reset-complete-title" style="width:min(520px,calc(100vw - 32px));border-radius:22px;background:#ffffff;color:#0f172a;border:1px solid rgba(15,23,42,0.12);box-shadow:0 32px 100px rgba(0,0,0,0.32);overflow:hidden;">'
                + '<div style="display:flex;align-items:center;justify-content:space-between;gap:16px;padding:18px 20px;border-bottom:1px solid rgba(15,23,42,0.08);">'
                + '<h2 id="vmo-builder-reset-complete-title" style="margin:0;font-size:20px;line-height:1.25;color:#0f172a;">Reset complete</h2>'
                + '<button type="button" class="vmo-builder-reset-complete-close" aria-label="Close" style="width:34px;height:34px;border-radius:999px;border:1px solid rgba(15,23,42,0.16);background:#f8fafc;color:#0f172a;font-size:20px;line-height:1;cursor:pointer;">&times;</button>'
                + '</div>'
                + '<div style="padding:20px;">'
                + '<p id="vmo-builder-reset-complete-message" style="margin:0;color:#334155;font-size:14px;line-height:1.65;"></p>'
                + '<p id="vmo-builder-reset-complete-backup" style="display:none;margin:14px 0 0;color:#64748b;font-size:12px;line-height:1.5;"></p>'
                + '</div>'
                + '<div style="display:flex;justify-content:flex-end;padding:0 20px 20px;">'
                + '<button type="button" class="vmo-builder-reset-complete-close" style="border:0;border-radius:10px;background:#0f172a;color:#fff;padding:10px 18px;font-weight:800;cursor:pointer;">OK</button>'
                + '</div>'
                + '</div>'
                + '</div>'
        );
        $('body').append($modal);
        $modal.on('click', function(event) {
            if (event.target === $modal[0]) {
                $modal.fadeOut(120);
            }
        });
        $modal.on('click', '.vmo-builder-reset-complete-close', function() {
            $modal.fadeOut(120);
        });
    }

    $modal.find('#vmo-builder-reset-complete-message').text(message);
    if (backupId) {
        $modal.find('#vmo-builder-reset-complete-backup').text('Protected backup: ' + backupId).show();
    } else {
        $modal.find('#vmo-builder-reset-complete-backup').hide().text('');
    }
    $modal.css('display', 'flex').hide().fadeIn(120);
};

window.vmoCreateBuilderResetSnapshot = function() {
    const iframe = document.getElementById('vmo-preview-iframe');
    let previewHtml = '';

    try {
        if (typeof window.vmoSerializePreviewDocument === 'function') {
            previewHtml = window.vmoSerializePreviewDocument();
        } else if (iframe) {
            previewHtml = String(iframe.getAttribute('srcdoc') || iframe.srcdoc || '');
        }
    } catch (_) {}

    return {
        vmoState: JSON.parse(JSON.stringify(window.vmoState || { blocks: [] })),
        lastContent: window.lastContent || '',
        vmoHasContent: !!window.vmoHasContent,
        vmoPreviewIsLive: !!window.vmoPreviewIsLive,
        currentProjectId: window.currentProjectId || null,
        currentProjectTitle: window.currentProjectTitle || null,
        currentLivePageId: window.currentLivePageId || null,
        vmoLivePermalink: window.vmoLivePermalink || '',
        previewHtml: previewHtml,
        previewUrl: iframe ? String(iframe.getAttribute('src') || '') : '',
        previewMode: iframe && iframe.dataset ? (iframe.dataset.vmoPreviewMode || '') : ''
    };
};

window.vmoRestoreBuilderResetSnapshot = function(snapshot) {
    const iframe = document.getElementById('vmo-preview-iframe');
    const codeView = document.getElementById('vmo-code-view');

    if (!snapshot) {
        return;
    }

    window.vmoState = snapshot.vmoState || { blocks: [] };
    window.lastContent = snapshot.lastContent || '';
    window.vmoHasContent = !!snapshot.vmoHasContent;
    window.vmoPreviewIsLive = false;
    window.currentProjectId = snapshot.currentProjectId || null;
    window.currentProjectTitle = snapshot.currentProjectTitle || null;
    window.currentLivePageId = snapshot.currentLivePageId || null;
    window.vmoLivePermalink = snapshot.vmoLivePermalink || '';

    if (codeView) {
        codeView.value = snapshot.lastContent || '';
        codeView.textContent = snapshot.lastContent || '';
    }

    if (iframe) {
        iframe.removeAttribute('src');
        iframe.srcdoc = snapshot.previewHtml || snapshot.lastContent || '';
        if (snapshot.previewMode) {
            iframe.dataset.vmoPreviewMode = snapshot.previewMode;
        } else {
            delete iframe.dataset.vmoPreviewMode;
        }
    }

    if (typeof window.renderBlocks === 'function') {
        window.renderBlocks();
    }
};

window.vmoEnsureResetConfirmBinding = function() {
    const confirmButton = document.getElementById('vmo-reset-confirm');
    if (!confirmButton || confirmButton.dataset.vmoDirectResetBound === '1') {
        return;
    }

    confirmButton.dataset.vmoDirectResetBound = '1';
    confirmButton.addEventListener('click', function(event) {
        event.preventDefault();
        event.stopPropagation();
        if (typeof event.stopImmediatePropagation === 'function') {
            event.stopImmediatePropagation();
        }
        window.vmoResetBuilder();
    }, true);
};

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', window.vmoEnsureResetConfirmBinding);
} else {
    window.vmoEnsureResetConfirmBinding();
}

window.vmoApplyBuilderResetState = function() {
    const iframe = document.getElementById('vmo-preview-iframe');
    if (!iframe) {
        return false;
    }

    window.autoLoadLatestProject = false;
    window.currentProjectId = null;
    window.currentProjectTitle = null;
    window.currentLivePageId = null;
    window.vmoLivePermalink = '';
    window.vmoLivePageTitle = '';
    window.vmoPreviewIsLive = false;
    window.vmoHasContent = false;
    window.lastContent = '';

    const consultationChip = document.querySelector('#vmo-consultation-status .vmo-chip');
    if (consultationChip) {
        consultationChip.dataset.ready = 'false';
        consultationChip.removeAttribute('title');
    }

    const previewTitle = document.getElementById('vmo-preview-title');
    if (previewTitle) {
        previewTitle.textContent = 'Live Preview';
    }

    iframe.style.display = '';
    iframe.style.visibility = 'visible';
    iframe.removeAttribute('src');
    iframe.removeAttribute('srcdoc');
    iframe.srcdoc = '';
    delete iframe.dataset.vmoPreviewMode;
    delete iframe.dataset.vmoShowcaseRecoveryCount;
    delete iframe.dataset.vmoShowcaseMediaState;

    const codeView = document.getElementById('vmo-code-view');
    if (codeView) {
        codeView.value = '';
        codeView.textContent = '';
    }

    if (typeof window.vmoSetPublishedState === 'function') {
        window.vmoSetPublishedState(false);
    } else {
        const updateLiveButton = document.getElementById('vmo-update-live-btn');
        const publishButton = document.getElementById('vmo-publish-btn');
        if (updateLiveButton) {
            updateLiveButton.style.display = 'none';
        }
        if (publishButton) {
            publishButton.setAttribute('data-published', 'false');
        }
    }

    if (typeof window.showIframePlaceholder === 'function') {
        setTimeout(function() {
            window.showIframePlaceholder({ force: true, rebuild: true, skipPersist: true, status: 'reset', message: 'Restoring the shipped preview...' });
        }, 40);
        return true;
    }

    return false;
};

window.vmoResetBuilderPreviewToBlank = function() {
    let placeholderShown = false;

    window.autoLoadLatestProject = false;
    window.currentProjectId = null;
    window.currentProjectTitle = null;
    window.currentLivePageId = null;
    window.vmoLivePermalink = '';
    window.vmoLivePageTitle = '';
    window.vmoPreviewIsLive = false;

    if (window.vmoState && typeof window.vmoState === 'object') {
        window.vmoState = { blocks: [] };
    }

    window.lastContent = '';
    window.vmoHasContent = false;

    if (typeof window.vmoClearStoredCheckpoint === 'function') {
        window.vmoClearStoredCheckpoint();
    }

    if (typeof window.renderBlocks === 'function') {
        try {
            window.renderBlocks();
        } catch (renderError) {
            console.warn('[VMO] Reset render fallback failed:', renderError);
        }
    }

    placeholderShown = window.vmoApplyBuilderResetState() || placeholderShown;

    if (!placeholderShown && typeof window.showIframePlaceholder === 'function') {
        try {
            window.showIframePlaceholder({ force: true, rebuild: true, skipPersist: true, status: 'reset', message: 'Restoring the shipped preview...' });
            placeholderShown = true;
        } catch (placeholderError) {
            console.warn('[VMO] Reset placeholder fallback failed:', placeholderError);
        }
    }

    const loadMenu = document.getElementById('vmo-load-menu');
    if (loadMenu) {
        loadMenu.innerHTML = '<div class="vmo-no-proj">No saved projects.</div>';
        loadMenu.classList.remove('open');
    }

    return placeholderShown;
};

window.vmoResetBuilderPreviewToDemo = function() {
    if (typeof window.vmoLoadDemoPreviewFrame === 'function') {
        window.vmoResetBuilderPreviewToBlank();
        return window.vmoLoadDemoPreviewFrame({ force: true, skipPersist: true, status: 'reset' });
    }
    return window.vmoResetBuilderPreviewToBlank();
};

window.vmoApplyRestoredBuilderProject = function(project) {
    const restoredProject = project && typeof project === 'object' ? project : {};
    const iframe = document.getElementById('vmo-preview-iframe');
    const codeView = document.getElementById('vmo-code-view');
    let restoredState = restoredProject.state || { blocks: [] };
    let restoredHtml = restoredProject.html || '';

    if (typeof restoredState === 'string') {
        try {
            restoredState = JSON.parse(restoredState);
        } catch (_) {
            restoredState = { blocks: [] };
        }
    }

    if (!restoredState || typeof restoredState !== 'object') {
        restoredState = { blocks: [] };
    }

    if (typeof window.vmoNormalizeBuilderHtml === 'function') {
        restoredHtml = window.vmoNormalizeBuilderHtml(restoredHtml);
    }

    if ((!Array.isArray(restoredState.blocks) || !restoredState.blocks.length) && restoredHtml) {
        restoredState.blocks = [{
            id: 'restored_backup_home_' + Date.now(),
            html: restoredHtml,
            type: 'restored_backup'
        }];
    }

    const hasRestoredContent = typeof window.vmoShouldTreatAsRealContent === 'function'
        ? window.vmoShouldTreatAsRealContent(restoredHtml, restoredState)
        : !!String(restoredHtml || '').trim();

    window.autoLoadLatestProject = true;
    window.vmoState = restoredState;
    window.lastContent = restoredHtml;
    window.vmoHasContent = hasRestoredContent;
    window.currentProjectId = restoredProject.project_id || restoredProject.id || null;
    window.currentProjectTitle = restoredProject.title || restoredProject.project_title || 'Restored Website';
    window.currentLivePageId = null;
    window.vmoLivePermalink = '';
    window.vmoLivePageTitle = '';
    window.vmoPreviewIsLive = false;
    window.isUnsaved = false;

    if (codeView) {
        codeView.value = restoredHtml;
        codeView.textContent = restoredHtml;
    }

    if (iframe) {
        iframe.removeAttribute('src');
        delete iframe.dataset.vmoPreviewMode;
        delete iframe.dataset.vmoShowcaseRecoveryCount;
        delete iframe.dataset.vmoShowcaseMediaState;
        if (hasRestoredContent) {
            iframe.srcdoc = restoredHtml;
        } else {
            iframe.removeAttribute('srcdoc');
            iframe.srcdoc = '';
        }
    }

    if (typeof window.vmoSetPublishedState === 'function') {
        window.vmoSetPublishedState(false);
    }

    if (hasRestoredContent && typeof window.renderBlocks === 'function') {
        window.renderBlocks();
    } else if (typeof window.showIframePlaceholder === 'function') {
        window.showIframePlaceholder({ force: true, rebuild: true, skipPersist: true });
    }

    try {
        if (hasRestoredContent) {
            localStorage.setItem('vmo_checkpoint_state', JSON.stringify(window.vmoState));
            localStorage.setItem('vmo_checkpoint_html', restoredHtml);
            localStorage.setItem('vmo_checkpoint_ts', Date.now().toString());
            if (window.currentProjectTitle) {
                localStorage.setItem('vmo_checkpoint_title', window.currentProjectTitle);
            }
        } else if (typeof window.vmoClearStoredCheckpoint === 'function') {
            window.vmoClearStoredCheckpoint();
        }
    } catch (_) {}

    if (window.currentProjectId && window.vmoMediaGenerator && typeof window.vmoMediaGenerator.startProjectQueuePolling === 'function') {
        window.vmoMediaGenerator.startProjectQueuePolling(window.currentProjectId, { source: 'builder_restore' });
    }

    return hasRestoredContent;
};

/**
 * Load the three newest Reset Builder backups for the current user.
 */
window.vmoLoadBuilderBackups = function(forceShow = false) {
    const $ = jQuery;
    const ajaxUrl = (window.vmo_ajax && vmo_ajax.ajaxurl) || (window.vmoAjax && vmoAjax.ajax_url) || '/wp-admin/admin-ajax.php';
    const nonce = (window.vmo_ajax && vmo_ajax.nonce) || (window.vmoAjax && vmoAjax.nonce) || '';
    const $panel = $('#vmo-reset-backups-panel');
    const $list = $('#vmo-reset-backups-list');
    const escapeHtml = (value) => String(value)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');

    if (!$list.length) {
        return;
    }

    if (forceShow) {
        $panel.prop('hidden', false);
    }

    $list.html('<div class="vmo-reset-backup-empty">Loading backups...</div>');

    $.post(ajaxUrl, {
        action: 'vmo_list_builder_backups',
        security: nonce,
    }).done(function(response) {
        if (!response || !response.success) {
            $list.html('<div class="vmo-reset-backup-empty">Could not load Reset Builder backups.</div>');
            return;
        }

        const backups = Array.isArray(response.data && response.data.backups) ? response.data.backups : [];
        if (!backups.length) {
            $list.html('<div class="vmo-reset-backup-empty">No Reset Builder backups yet.</div>');
            if (!forceShow) {
                $panel.prop('hidden', true);
            }
            return;
        }

        const items = backups.map((backup) => {
            const createdAt = backup.created_at ? new Date(String(backup.created_at).replace(' ', 'T')) : null;
            const createdLabel = createdAt && !Number.isNaN(createdAt.getTime())
                ? createdAt.toLocaleString()
                : (backup.created_at || 'Unknown time');
            const projectTitle = escapeHtml(backup.project_title || 'Archived business state');
            const createdLabelText = escapeHtml(createdLabel);

            return `
                <div class="vmo-reset-backup-item">
                    <div class="vmo-reset-backup-copy">
                        <strong>${projectTitle}</strong>
                        <span>Saved ${createdLabelText}</span>
                        <span>Restored ${backup.restore_count || 0} time(s)</span>
                    </div>
                    <button class="vmo-reset-btn vmo-reset-restore-btn" data-backup-id="${backup.backup_id}">Restore Backup</button>
                </div>
            `;
        }).join('');

        $list.html(items);
        $panel.prop('hidden', false);
    }).fail(function() {
        $list.html('<div class="vmo-reset-backup-empty">Could not load Reset Builder backups.</div>');
    });
};

/**
 * Reset Builder and archive the current business instance server-side.
 */
window.vmoResetBuilder = function() {
    const $ = jQuery;
    const resetSnapshot = window.vmoCreateBuilderResetSnapshot();
    if (window.vmoResetInProgress) {
        return;
    }

    const $btn = $('#vmo-reset-confirm');
    const originalText = $btn.text();
    const resetContext = {
        sessionId: window.vmoConsultationSessionId || 
                   window.vmoCurrentConsultationSessionId || 
                   localStorage.getItem('vmoConsultationSessionId') || 
                   '',
        currentProjectPostId: resetSnapshot.currentProjectId || window.currentProjectId || 0,
        currentProjectTitle: resetSnapshot.currentProjectTitle || window.currentProjectTitle || '',
        currentLivePageId: resetSnapshot.currentLivePageId || window.currentLivePageId || 0
    };
    let progressValue = 10;
    let progressTimer = null;

    const restoreConfirmationState = function(message) {
        window.clearInterval(progressTimer);
        try {
            window.vmoResetProgressUi.reset();
        } catch (_) {
            window.vmoResetInProgress = false;
        }
        try {
            window.vmoRestoreBuilderResetSnapshot(resetSnapshot);
        } catch (restoreError) {
            console.warn('[VMO] Could not restore reset snapshot after failed reset.', restoreError);
        }
        $btn.prop('disabled', false).text(originalText);
        window.vmoSetResetModalVisibility(true);
        if (message && typeof window.showToast === 'function') {
            window.showToast(message, 'error', false, false);
        }
    };

    window.vmoResetProgressUi.begin();
    window.vmoResetProgressUi.update(progressValue, 'Creating a protected backup...', 'Securing your current builder state');
    if (typeof window.hideToast === 'function') {
        window.hideToast(true);
    }
    window.vmoSetResetModalVisibility(false);
    window.vmoResetProgressUi.update(18, 'Resetting the live preview...', 'Restoring the shipped iframe state while backup runs in the background');
    window.vmoResetBuilderPreviewToDemo();

    progressTimer = window.setInterval(function() {
        if (progressValue >= 78) {
            return;
        }

        if (progressValue < 36) {
            progressValue += 7;
            window.vmoResetProgressUi.update(progressValue, 'Creating a protected backup...', 'Securing your current builder state');
            return;
        }

        progressValue += 4;
        window.vmoResetProgressUi.update(progressValue, 'Resetting builder and preview...', 'Disconnecting this builder instance safely');
    }, 260);

    const ajaxUrl = (window.vmo_ajax && vmo_ajax.ajaxurl) || 
                    (window.vmoAjax && vmoAjax.ajax_url) || 
                    '/wp-admin/admin-ajax.php';
    const nonce = (window.vmo_ajax && vmo_ajax.nonce) || 
                  (window.vmoAjax && vmoAjax.nonce) || '';

    $.ajax({
        url: ajaxUrl,
        type: 'POST',
        timeout: 120000,
        data: {
            action: 'vmo_reset_builder',
            security: nonce,
            session_id: resetContext.sessionId,
            current_project_post_id: resetContext.currentProjectPostId,
            current_project_title: resetContext.currentProjectTitle,
            current_live_page_id: resetContext.currentLivePageId,
            confirmation: 'RESET_BUILDER'
        },
        success: function(response) {
            if (response && response.success) {
                window.clearInterval(progressTimer);
                const responseData = response.data || {};
                window.vmoResetProgressUi.update(84, 'Clearing local builder state...', 'Restoring the shipped preview until a new website is generated');
                window.vmoClearBuilderStorage();

                if (window.vmo_ajax) {
                    window.vmo_ajax.builder_reset_mode = true;
                }
                if (window.vmoAjax) {
                    window.vmoAjax.builder_reset_mode = true;
                }

                if (responseData.new_session_id) {
                    localStorage.setItem('vmoConsultationSessionId', responseData.new_session_id);
                    window.vmoConsultationSessionId = responseData.new_session_id;
                    window.vmoCurrentConsultationSessionId = responseData.new_session_id;
                    if (window.vmoConsultation && typeof window.vmoConsultation.handleBuilderResetComplete === 'function') {
                        window.vmoConsultation.handleBuilderResetComplete(responseData.new_session_id);
                    }
                }

                const previewUpdated = window.vmoResetBuilderPreviewToDemo();
                window.vmoResetProgressUi.update(100, 'Builder reset complete.', 'Preview refreshed to the shipped starting state');
                window.setTimeout(function() {
                    window.vmoResetProgressUi.reset();
                    window.vmoSetResetModalVisibility(false);
                    window.vmoResetBuilderPreviewToDemo();
                    window.vmoLoadBuilderBackups(false);
                    if (typeof window.showToast === 'function') {
                        window.showToast('Builder reset complete. The preview has been refreshed.', 'success', false, false);
                    }
                    if (typeof window.vmoShowBuilderResetCompleteDialog === 'function') {
                        window.vmoShowBuilderResetCompleteDialog(responseData);
                    }
                }, previewUpdated ? 650 : 320);
            } else {
                restoreConfirmationState((response && response.data && response.data.message) || 'Reset Builder failed before the backup could be completed.');
            }
        },
        error: function(xhr, status, error) {
            console.error('Reset Builder error:', error);
            const timedOut = status === 'timeout';
            restoreConfirmationState(timedOut ? 'Reset Builder timed out before the backup step completed. Nothing was cleared.' : 'Reset Builder failed. Nothing was cleared because the backup step did not complete.');
        }
    });
};

/**
 * Restore a Reset Builder backup into the builder as an unpublished draft.
 */
window.vmoRestoreBuilderBackup = function(backupId) {
    const $ = jQuery;
    if (!backupId) {
        return;
    }

    const proceed = window.confirm('Restore this backup into the builder? Any current in-plugin business state will be replaced, and the restored website will remain unpublished until you publish again.');
    if (!proceed) {
        return;
    }

    const ajaxUrl = (window.vmo_ajax && vmo_ajax.ajaxurl) || (window.vmoAjax && vmoAjax.ajax_url) || '/wp-admin/admin-ajax.php';
    const nonce = (window.vmo_ajax && vmo_ajax.nonce) || (window.vmoAjax && vmoAjax.nonce) || '';
    const $buttons = $('.vmo-reset-restore-btn');

    $buttons.prop('disabled', true);

    $.post(ajaxUrl, {
        action: 'vmo_restore_builder_backup',
        security: nonce,
        backup_id: backupId,
        current_project_post_id: window.currentProjectId || 0,
        current_project_title: window.currentProjectTitle || '',
        current_live_page_id: window.currentLivePageId || 0,
        confirmation: 'RESTORE_BUILDER_BACKUP'
    }).done(function(response) {
        if (!response || !response.success) {
            $buttons.prop('disabled', false);
            if (typeof window.showToast === 'function') {
                window.showToast((response && response.data && response.data.message) || 'Backup restore failed.', 'error', false, false);
            }
            return;
        }

        window.vmoClearBuilderStorage();
        if (window.vmo_ajax) {
            window.vmo_ajax.builder_reset_mode = false;
        }
        if (window.vmoAjax) {
            window.vmoAjax.builder_reset_mode = false;
        }

        if (response.data && response.data.restored_session_id) {
            try {
                localStorage.setItem('vmoConsultationSessionId', response.data.restored_session_id);
            } catch (_) {}
            window.vmoConsultationSessionId = response.data.restored_session_id;
            window.vmoCurrentConsultationSessionId = response.data.restored_session_id;
        }

        if (response.data && response.data.project && typeof window.vmoApplyRestoredBuilderProject === 'function') {
            window.vmoApplyRestoredBuilderProject(response.data.project);
        }

        window.vmoLoadBuilderBackups(false);
        if (typeof window.showToast === 'function') {
            window.showToast('Backup restored into the builder as an unpublished draft.', 'success', false, false);
        }
    }).fail(function() {
        $buttons.prop('disabled', false);
        if (typeof window.showToast === 'function') {
            window.showToast('Backup restore failed.', 'error', false, false);
        }
    });
};

window.vmoClearConsultationStorage = function() {
    const storageKeys = [
        'vmoConsultationSessionId',
        'vmoCurrentConsultationSessionId',
        'vmo_consultation_checkpoint',
        'vmo_consultation_history',
        'vmo_consultation_state'
    ];

    storageKeys.forEach(function(key) {
        try { localStorage.removeItem(key); } catch (_) {}
        try { sessionStorage.removeItem(key); } catch (_) {}
    });
};

window.vmoResetConsultation = function() {
    const $ = jQuery;
    const consultation = window.vmoConsultation || null;
    const fallbackSessionId = consultation && typeof consultation.generateSessionId === 'function'
        ? consultation.generateSessionId()
        : ('consultation_' + Date.now() + '_' + Math.random().toString(36).slice(2, 10));
    const ajaxUrl = (window.vmo_ajax && window.vmo_ajax.ajaxurl) || (window.vmoAjax && window.vmoAjax.ajax_url) || '';
    const nonce = (window.vmo_ajax && window.vmo_ajax.nonce) || (window.vmoAjax && window.vmoAjax.nonce) || '';
    const currentSessionId = window.vmoConsultationSessionId || window.vmoCurrentConsultationSessionId || '';

    const applyConsultationReset = function(sessionId) {
        const newSessionId = String(sessionId || fallbackSessionId).trim() || fallbackSessionId;

        window.vmoClearConsultationStorage();
        window.vmoConsultationSessionId = newSessionId;
        window.vmoCurrentConsultationSessionId = newSessionId;
        try { localStorage.setItem('vmoConsultationSessionId', newSessionId); } catch (_) {}

        if (consultation && typeof consultation.handleConsultationResetComplete === 'function') {
            consultation.handleConsultationResetComplete(newSessionId, { source: 'consultation_reset', showReadyMessage: true });
        } else if (consultation && typeof consultation.handleBuilderResetComplete === 'function') {
            consultation.handleBuilderResetComplete(newSessionId);
        } else {
            const chatContainer = document.querySelector('#vmo-wizard-conversation') || document.querySelector('#vmo-chat-messages, .vmo-chat-messages, [data-vmo-chat-messages]');
            if (chatContainer) {
                chatContainer.innerHTML = '';
            }
        }

        if (typeof window.showToast === 'function') {
            window.showToast('Consultation restarted. Your website preview was not reset.', 'success', false, false);
        }
    };

    if (ajaxUrl && nonce && $ && typeof $.post === 'function') {
        $.post(ajaxUrl, {
            action: 'vmo_reset_consultation',
            security: nonce,
            session_id: currentSessionId
        }).done(function(response) {
            const responseData = response && response.success ? (response.data || {}) : {};
            applyConsultationReset(responseData.new_session_id || fallbackSessionId);
        }).fail(function() {
            applyConsultationReset(fallbackSessionId);
        });
        return;
    }

    applyConsultationReset(fallbackSessionId);
};

window.vmoShowConsultationResetConfirmation = function(aiMessage = null) {
    const $ = jQuery;
    let $modal = $('#vmo-consultation-reset-modal');

    if (!$modal.length) {
        $modal = $(
            '<div id="vmo-consultation-reset-modal" style="display:none;position:fixed;inset:0;z-index:1000002;align-items:center;justify-content:center;padding:20px;background:rgba(2,6,16,0.58);backdrop-filter:blur(8px);">'
                + '<div role="dialog" aria-modal="true" aria-labelledby="vmo-consultation-reset-title" style="width:min(520px,calc(100vw - 32px));border-radius:22px;background:#ffffff;color:#0f172a;border:1px solid rgba(15,23,42,0.12);box-shadow:0 32px 100px rgba(0,0,0,0.32);overflow:hidden;">'
                + '<div style="display:flex;align-items:center;justify-content:space-between;gap:16px;padding:18px 20px;border-bottom:1px solid rgba(15,23,42,0.08);">'
                + '<h2 id="vmo-consultation-reset-title" style="margin:0;font-size:20px;line-height:1.25;color:#0f172a;">Restart consultation?</h2>'
                + '<button type="button" class="vmo-consultation-reset-close" aria-label="Close" style="width:34px;height:34px;border-radius:999px;border:1px solid rgba(15,23,42,0.16);background:#f8fafc;color:#0f172a;font-size:20px;line-height:1;cursor:pointer;">&times;</button>'
                + '</div>'
                + '<div style="padding:20px;">'
                + '<p style="margin:0;color:#334155;font-size:14px;line-height:1.65;">This will clear only the current consultation conversation and start a fresh consultation session. It will not reset the builder, remove the live preview, unpublish the website, or touch Reset Builder backups.</p>'
                + '</div>'
                + '<div style="display:flex;justify-content:flex-end;gap:10px;padding:0 20px 20px;flex-wrap:wrap;">'
                + '<button type="button" class="vmo-consultation-reset-close" style="border:1px solid rgba(15,23,42,0.16);border-radius:10px;background:#f8fafc;color:#0f172a;padding:10px 16px;font-weight:800;cursor:pointer;">Cancel</button>'
                + '<button type="button" id="vmo-consultation-reset-confirm" style="border:0;border-radius:10px;background:#0f172a;color:#fff;padding:10px 18px;font-weight:800;cursor:pointer;">Restart Consultation</button>'
                + '</div>'
                + '</div>'
                + '</div>'
        );
        $('body').append($modal);
        $modal.on('click', function(event) {
            if (event.target === $modal[0]) {
                $modal.fadeOut(120);
            }
        });
        $modal.on('click', '.vmo-consultation-reset-close', function() {
            $modal.fadeOut(120);
        });
        $modal.on('click', '#vmo-consultation-reset-confirm', function() {
            $modal.fadeOut(120, function() {
                window.vmoResetConsultation();
            });
        });
    }

    if (aiMessage && typeof window.showToast === 'function') {
        window.showToast(aiMessage, 'info', false, false);
    }

    $modal.css('display', 'flex').hide().fadeIn(120);
    console.log('[VMO] Consultation restart confirmation shown');
};

window.vmoShowResetConfirmation = window.vmoShowConsultationResetConfirmation;

/**
 * ═══════════════════════════════════════════════════════════════════════════════
 * 🚀 GLOBAL CREDIT ENFORCEMENT SYSTEM
 * ═══════════════════════════════════════════════════════════════════════════════
 * Intercepts all AJAX responses to detect 'insufficient_tokens' and show
 * persuasive upgrade/topup toast. This ensures NO functionality works without credit.
 * ═══════════════════════════════════════════════════════════════════════════════
 */
(function() {
    'use strict';
    let creditRefreshInFlight = false;
    let lastCreditRefreshAt = 0;
    let lastLowCreditToastAt = 0;
    const LOW_CREDIT_TOAST_INTERVAL = 60000;
    
    // Helper to check if response indicates insufficient credits
    function isInsufficientCredits(data) {
        if (!data) return false;
        
        // Check various response formats
        if (data.status === 'insufficient_tokens') return true;
        if (data.code === 'insufficient_tokens') return true;
        if (data.status === 'service_locked') return true;
        if (data.code === 'service_locked') return true;
        if (data.service_locked === true) return true;
        if (data.no_credit === true) return true;
        if (data.success === false && data.data) {
            if (data.data.status === 'insufficient_tokens') return true;
            if (data.data.code === 'insufficient_tokens') return true;
            if (data.data.status === 'service_locked') return true;
            if (data.data.code === 'service_locked') return true;
            if (data.data.service_locked === true) return true;
            if (data.data.no_credit === true) return true;
            if (data.data.message && data.data.message.toLowerCase().includes('insufficient')) return true;
        }
        if (data.error && data.error.code === 'insufficient_tokens') return true;
        if (data.error && data.error.code === 'service_locked') return true;
        
        return false;
    }

    function getCreditStatus(data) {
        if (!data) return null;
        if (data.credit_status) return data.credit_status;
        if (data.data && data.data.credit_status) return data.data.credit_status;
        if (data.success === true && data.data) {
            if (typeof data.data.balance !== 'undefined' || typeof data.data.remaining_percent !== 'undefined') {
                return {
                    balance: data.data.balance,
                    remaining_percent: data.data.remaining_percent,
                    low_credit: data.data.low_credit,
                    critical_credit: data.data.critical_credit,
                    credit_warning_level: data.data.credit_warning_level,
                    no_credit: data.data.no_credit,
                    plan_tokens: data.data.plan_tokens
                };
            }
        }
        return null;
    }

    function updateLocalizedCreditStatus(status) {
        if (!status) return;
        const targets = [];
        if (window.vmo_ajax) targets.push(window.vmo_ajax);
        if (window.vmoAjax && window.vmoAjax !== window.vmo_ajax) targets.push(window.vmoAjax);
        targets.forEach(function(target) {
            if (typeof status.balance !== 'undefined') target.token_balance = parseInt(status.balance, 10) || 0;
            if (typeof status.effective_plan_tokens !== 'undefined') target.plan_tokens = parseInt(status.effective_plan_tokens, 10) || 0;
            else if (typeof status.plan_tokens !== 'undefined') target.plan_tokens = parseInt(status.plan_tokens, 10) || 0;
            if (typeof status.remaining_percent !== 'undefined') target.credit_remaining_percent = Number(status.remaining_percent) || 0;
            if (typeof status.usage_percent !== 'undefined') target.credit_usage_percent = Number(status.usage_percent) || 0;
            if (typeof status.low_credit_threshold_percent !== 'undefined') target.low_credit_remaining_percent = Number(status.low_credit_threshold_percent) || 40;
            if (typeof status.critical_credit_threshold_percent !== 'undefined') target.critical_credit_remaining_percent = Number(status.critical_credit_threshold_percent) || 20;
            if (typeof status.low_credit !== 'undefined') target.low_credit = Boolean(status.low_credit);
            if (typeof status.critical_credit !== 'undefined') target.critical_credit = Boolean(status.critical_credit);
            if (typeof status.credit_warning_level !== 'undefined') target.credit_warning_level = String(status.credit_warning_level || 'none');
            if (typeof status.no_credit !== 'undefined') target.no_credit = Boolean(status.no_credit);
            if (typeof status.service_locked !== 'undefined') target.service_locked = Boolean(status.service_locked);
            if (typeof status.service_lock_reason !== 'undefined') target.service_lock_reason = String(status.service_lock_reason || '');
            if (typeof status.cost_access_block_reason !== 'undefined') target.cost_access_block_reason = String(status.cost_access_block_reason || '');
            if (typeof status.subscription_payment_status !== 'undefined') target.subscription_payment_status = String(status.subscription_payment_status || '');
            if (typeof status.entitlement_active !== 'undefined') target.entitlement_active = Boolean(status.entitlement_active);
            if (typeof status.has_selected_plan !== 'undefined') target.has_selected_plan = Boolean(status.has_selected_plan);
            if (typeof status.free_access_active !== 'undefined') target.free_access_active = Boolean(status.free_access_active);
            if (typeof status.free_access_expired !== 'undefined') target.free_access_expired = Boolean(status.free_access_expired);
            if (typeof status.can_use_cost_bearing_services !== 'undefined') target.can_use_cost_bearing_services = Boolean(status.can_use_cost_bearing_services);
            if (status.next_plan) target.next_plan = status.next_plan;
        });
    }

    function isLowCreditStatus(status) {
        if (!status) return false;
        if (status.no_credit === true) return false;
        if (status.low_credit === true) return true;
        const balance = Number(status.balance ?? 0);
        const remaining = Number(status.remaining_percent ?? 101);
        const ajax = window.vmo_ajax || window.vmoAjax || {};
        const threshold = Number(status.low_credit_threshold_percent ?? ajax.low_credit_remaining_percent ?? 40);
        return balance > 0 && remaining <= threshold;
    }

    function showLowCreditSequence(status, source) {
        if (!isLowCreditStatus(status)) return;
        const now = Date.now();
        if (now - lastLowCreditToastAt < LOW_CREDIT_TOAST_INTERVAL) return;
        lastLowCreditToastAt = now;

        if (typeof window.showLowCreditsToast === 'function') {
            window.showLowCreditsToast(status);
            setTimeout(function() {
                const ajax = window.vmo_ajax || window.vmoAjax || {};
                const latestStatus = {
                    balance: ajax.token_balance,
                    remaining_percent: ajax.credit_remaining_percent,
                    low_credit: ajax.low_credit,
                    critical_credit: ajax.critical_credit,
                    credit_warning_level: ajax.credit_warning_level,
                    no_credit: ajax.no_credit,
                    next_plan: ajax.next_plan
                };
                if (isLowCreditStatus(latestStatus)) {
                    const repeatMessage = latestStatus.critical_credit ? 'You are still under the 20% critical credit line. Add credit now before provider-backed services are paused or enter cancellation grace.' : 'You are still under the 40% credit line. Upgrade or buy a booster before starting another plugin task.';
                    window.showLowCreditsToast(latestStatus, repeatMessage);
                }
            }, 7000);
        }

        console.log('[VMO] Low credit warning shown from', source || 'credit-check');
    }

    function actionFromAjaxSettings(settings) {
        if (!settings) return '';
        const data = settings.data;
        if (typeof data === 'string') {
            try {
                return new URLSearchParams(data).get('action') || '';
            } catch (e) {
                const match = data.match(/(?:^|&)action=([^&]+)/);
                return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : '';
            }
        }
        if (data && typeof data === 'object') {
            if (typeof FormData !== 'undefined' && data instanceof FormData) {
                return data.get('action') || '';
            }
            return data.action || '';
        }
        return '';
    }

    function refreshCreditStatus(source) {
        if (typeof jQuery === 'undefined') return;
        const ajax = window.vmo_ajax || window.vmoAjax || {};
        const ajaxurl = ajax.ajaxurl || ajax.ajax_url;
        const nonce = ajax.security || ajax.nonce;
        if (!ajaxurl || !nonce) return;

        const now = Date.now();
        if (creditRefreshInFlight || now - lastCreditRefreshAt < 10000) return;
        creditRefreshInFlight = true;
        lastCreditRefreshAt = now;

        jQuery.post(ajaxurl, {
            action: 'vmo_get_token_balance',
            security: nonce
        }).done(function(response) {
            const status = getCreditStatus(response);
            if (status) {
                updateLocalizedCreditStatus(status);
                if (isInsufficientCredits(response)) {
                    if (typeof window.showInsufficientCreditsToast === 'function') {
                        window.showInsufficientCreditsToast((response.data && response.data.message) || response.message || null);
                    }
                } else {
                    showLowCreditSequence(status, source || 'refresh');
                }
            }
        }).always(function() {
            creditRefreshInFlight = false;
        });
    }
    
    // Intercept jQuery AJAX (used by many VMO components)
    if (typeof jQuery !== 'undefined') {
        jQuery(document).ajaxComplete(function(event, xhr, settings) {
            try {
                // Skip if this is not a VMO AJAX call
                if (!settings.url || !settings.url.includes('admin-ajax.php')) return;
                const action = actionFromAjaxSettings(settings);
                
                const response = xhr.responseJSON || (xhr.responseText ? JSON.parse(xhr.responseText) : null);
                const status = getCreditStatus(response);
                if (status) {
                    updateLocalizedCreditStatus(status);
                }
                if (response && isInsufficientCredits(response)) {
                    if (typeof window.showInsufficientCreditsToast === 'function') {
                        window.showInsufficientCreditsToast(response.data && response.data.message ? response.data.message : null);
                    }
                    return;
                }
                if (status && isLowCreditStatus(status)) {
                    showLowCreditSequence(status, action || 'ajax-response');
                } else if (action && action.indexOf('vmo_') === 0 && action !== 'vmo_get_token_balance') {
                    refreshCreditStatus(action);
                }
            } catch (e) {
                // Ignore parse errors for non-JSON responses
            }
        });
    }
    
    // Wrap native fetch to intercept responses
    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        const response = await originalFetch.apply(this, args);
        
        // Only intercept VMO AJAX calls
        const url = typeof args[0] === 'string' ? args[0] : (args[0].url || '');
        if (url.includes('admin-ajax.php') || url.includes('wp-json/vmo')) {
            try {
                // Clone response to read body without consuming it
                const clone = response.clone();
                const data = await clone.json().catch(() => null);
                
                if (data && isInsufficientCredits(data)) {
                    if (typeof window.showInsufficientCreditsToast === 'function') {
                        window.showInsufficientCreditsToast((data.data && data.data.message) || data.message || null);
                    }
                } else {
                    const status = getCreditStatus(data);
                    if (status) {
                        updateLocalizedCreditStatus(status);
                        showLowCreditSequence(status, 'fetch-response');
                    } else {
                        refreshCreditStatus('fetch');
                    }
                }
            } catch (e) {
                // Ignore - response might not be JSON
            }
        }
        
        return response;
    };

    if (typeof jQuery !== 'undefined') {
        jQuery(function() {
            setTimeout(function() {
                const ajax = window.vmo_ajax || window.vmoAjax || {};
                const status = {
                    balance: ajax.token_balance,
                    remaining_percent: ajax.credit_remaining_percent,
                    low_credit: ajax.low_credit,
                    critical_credit: ajax.critical_credit,
                    credit_warning_level: ajax.credit_warning_level,
                    no_credit: ajax.no_credit,
                    low_credit_threshold_percent: ajax.low_credit_remaining_percent,
                    critical_credit_threshold_percent: ajax.critical_credit_remaining_percent,
                    next_plan: ajax.next_plan
                };

                if (ajax.service_locked && typeof window.showInsufficientCreditsToast === 'function') {
                    const reason = String(ajax.service_lock_reason || ajax.cost_access_block_reason || '');
                    const message = reason === 'subscription_required'
                        ? 'Choose a VMO subscription plan to power the plugin. AI, phone, SMS, email, media, and automation stay off until a paid plan or approved access window is active.'
                        : reason === 'free_access_expired'
                            ? 'Your free VMO access period has ended. Your generated website remains in place, but provider-backed services stay paused until billing is activated.'
                            : null;
                    if (message) {
                        window.showInsufficientCreditsToast(message);
                        return;
                    }
                }

                if (ajax.no_credit && typeof window.showInsufficientCreditsToast === 'function') {
                    window.showInsufficientCreditsToast();
                    return;
                }

                if (isLowCreditStatus(status)) {
                    showLowCreditSequence(status, 'page-load');
                } else {
                    refreshCreditStatus('page-load');
                }
            }, 1800);
        });
    }
    
    console.log('[VMO] Global credit enforcement system initialized');
})();