(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
    const upgradeUrl = (window.vmo_ajax && vmo_ajax.upgradeUrl) || 
                       (window.vmoAjax && vmoAjax.upgradeUrl) || 
                       'https://jerremejosephson.com/vmo-upgrade/';
    const topupUrl = (window.vmo_ajax && vmo_ajax.topupUrl) || 
                     (window.vmoAjax && vmoAjax.topupUrl) || 
                     'https://jerremejosephson.com/vmo-topup/';
    
    // Persuasive, encouraging messages (rotated)
    const messages = [
        "You're building something amazing! Your subscription credit has run out. Keep the momentum going—",
        "So close to your vision! Your credit is used up. Don't let anything slow you down—",
        "Your business empire awaits! Subscription credit depleted. Power up and keep building—",
        "You're on your way to greatness! Credit used up. Fuel your dreams—"
    ];
    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="_blank" class="vmo-credit-btn vmo-credit-btn-topup">
                        💳 Top Up Now
                    </a>
                    <a href="${upgradeUrl}" target="_blank" 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 subscription credit has run out. Please top up or upgrade to continue building.', 'warning');
    }
    
    console.log('[VMO] Credit enforcement toast shown');
};

/**
 * 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.data && response.data.status === 'insufficient_tokens') ||
                     response.success === false && response.data && response.data.code === 'insufficient_tokens')) {
        window.showInsufficientCreditsToast();
        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);
        }
    }

    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 restores the original demo website.</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.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 = !!snapshot.vmoPreviewIsLive;
    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) {
        if (snapshot.vmoPreviewIsLive && snapshot.previewUrl) {
            iframe.removeAttribute('srcdoc');
            iframe.setAttribute('src', snapshot.previewUrl);
        } else {
            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;
    }

    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.srcdoc = '';
    delete iframe.dataset.vmoPreviewMode;

    if (typeof window.showIframePlaceholder === 'function') {
        setTimeout(function() {
            window.showIframePlaceholder();
        }, 40);
        return true;
    }

    return false;
};

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

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

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

    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();
            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;
};

/**
 * 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();
    let progressValue = 10;
    let progressTimer = null;
    let reloadScheduled = false;

    const finalizeReload = function(delayMs) {
        if (reloadScheduled) {
            return;
        }
        reloadScheduled = true;

        window.setTimeout(function() {
            try {
                window.location.reload();
            } catch (reloadError) {
                console.warn('[VMO] Reset reload failed, trying replace().', reloadError);
                try {
                    window.location.replace(window.location.href);
                } catch (_) {}
            }

            window.setTimeout(function() {
                try {
                    window.location.replace(window.location.href);
                } catch (_) {}
            }, 900);
        }, Math.max(0, delayMs || 0));
    };

    const restoreConfirmationState = function(message) {
        window.clearInterval(progressTimer);
        window.vmoResetProgressUi.reset();
        window.vmoRestoreBuilderResetSnapshot(resetSnapshot);
        $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, 'Refreshing the demo website...', 'Returning the iframe to the official demo 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 sessionId = window.vmoConsultationSessionId || 
                      window.vmoCurrentConsultationSessionId || 
                      localStorage.getItem('vmoConsultationSessionId') || 
                      '';

    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',
        data: {
            action: 'vmo_reset_builder',
            security: nonce,
            session_id: sessionId,
            current_project_post_id: window.currentProjectId || 0,
            current_project_title: window.currentProjectTitle || '',
            current_live_page_id: window.currentLivePageId || 0,
            confirmation: 'RESET_BUILDER'
        },
        success: function(response) {
            if (response.success) {
                window.clearInterval(progressTimer);
                window.vmoResetProgressUi.update(84, 'Clearing local builder state...', 'Switching back to the demo experience');
                window.vmoClearBuilderStorage();

                try {
                    sessionStorage.setItem('builder_reset_demo_pending', '1');
                } catch (_) {}

                if (response.data.new_session_id) {
                    localStorage.setItem('vmoConsultationSessionId', response.data.new_session_id);
                    window.vmoConsultationSessionId = response.data.new_session_id;
                    window.vmoCurrentConsultationSessionId = response.data.new_session_id;
                }

                const previewUpdated = window.vmoResetBuilderPreviewToDemo();
                window.vmoResetProgressUi.update(100, 'Builder reset complete.', 'Restoring the demo website and refreshing the builder');
                finalizeReload(previewUpdated ? 650 : 320);
            } else {
                restoreConfirmationState((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);
            restoreConfirmationState('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,
        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 (typeof window.showToast === 'function') {
            window.showToast('Backup restored into the builder. Reloading the unpublished draft...', 'success', false, false);
        }

        setTimeout(function() {
            window.location.reload();
        }, 1500);
    }).fail(function() {
        $buttons.prop('disabled', false);
        if (typeof window.showToast === 'function') {
            window.showToast('Backup restore failed.', 'error', false, false);
        }
    });
};

window.vmoResetConsultation = window.vmoResetBuilder;

/**
 * 🤖 Show reset modal from AI detection.
 */
window.vmoShowResetConfirmation = function(aiMessage = null) {
    const $ = jQuery;

    window.vmoResetProgressUi.reset();
    window.vmoSetResetModalVisibility(true);
    window.vmoLoadBuilderBackups(false);

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

    console.log('[VMO] Reset confirmation shown (AI-triggered)');
};

/**
 * ═══════════════════════════════════════════════════════════════════════════════
 * 🚀 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';
    
    // 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.success === false && data.data) {
            if (data.data.status === 'insufficient_tokens') return true;
            if (data.data.code === 'insufficient_tokens') return true;
            if (data.data.message && data.data.message.toLowerCase().includes('insufficient')) return true;
        }
        if (data.error && data.error.code === 'insufficient_tokens') return true;
        
        return 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 response = xhr.responseJSON || (xhr.responseText ? JSON.parse(xhr.responseText) : null);
                if (response && isInsufficientCredits(response)) {
                    if (typeof window.showInsufficientCreditsToast === 'function') {
                        window.showInsufficientCreditsToast();
                    }
                }
            } 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();
                    }
                }
            } catch (e) {
                // Ignore - response might not be JSON
            }
        }
        
        return response;
    };
    
    console.log('[VMO] Global credit enforcement system initialized');
})();