(function ($) {

    const PREVIEW_SNAPSHOT_KEY = 'vmo_preview_frame_state';
    const PREVIEW_SNAPSHOT_MAX_BYTES = 3500000;

    function getPreviewIframe() {
        return document.getElementById('vmo-preview-iframe');
    }

    function getPreviewIframeSrc() {
        const iframe = getPreviewIframe();
        if (!iframe) return '';
        return String(iframe.getAttribute('src') || iframe.src || '');
    }

    function getLivePreviewHtmlInternal() {
        const iframe = getPreviewIframe();

        if (typeof window.vmoSerializePreviewDocument === 'function') {
            const serialized = window.vmoSerializePreviewDocument();
            if (serialized && serialized.trim()) {
                return serialized;
            }
        }

        if (!iframe) {
            return '';
        }

        const srcdocHtml = String(iframe.getAttribute('srcdoc') || iframe.srcdoc || '');
        if (srcdocHtml && srcdocHtml.trim()) {
            return srcdocHtml;
        }

        try {
            if (iframe.contentDocument && iframe.contentDocument.documentElement) {
                return '<!DOCTYPE html>\n' + iframe.contentDocument.documentElement.outerHTML;
            }
        } catch (_) {}

        return '';
    }

    function readPersistedPreviewState() {
        try {
            const raw = sessionStorage.getItem(PREVIEW_SNAPSHOT_KEY);
            if (!raw) return null;
            return JSON.parse(raw);
        } catch (error) {
            console.warn('[VMO Theme] Could not read persisted preview state:', error);
            return null;
        }
    }

    function writePersistedPreviewState(snapshot) {
        if (!snapshot) return false;

        try {
            const raw = JSON.stringify(snapshot);
            if (raw.length > PREVIEW_SNAPSHOT_MAX_BYTES) {
                console.warn('[VMO Theme] Skipped preview snapshot: payload too large');
                return false;
            }
            sessionStorage.setItem(PREVIEW_SNAPSHOT_KEY, raw);
            return true;
        } catch (error) {
            console.warn('[VMO Theme] Could not persist preview state:', error);
            return false;
        }
    }

    function hasActiveIframePreview() {
        const iframe = getPreviewIframe();
        let html = '';
        if (!iframe) return false;

        html = getLivePreviewHtmlInternal();
        if (html && html.trim()) {
            if (typeof window.vmoHasMeaningfulPreviewHtml === 'function') {
                return window.vmoHasMeaningfulPreviewHtml(html);
            }
            return true;
        }
        if (getPreviewIframeSrc()) return true;

        try {
            const bodyHtml = iframe.contentDocument && iframe.contentDocument.body
                ? String(iframe.contentDocument.body.innerHTML || '').trim()
                : '';
            return !!bodyHtml;
        } catch (_) {
            return false;
        }
    }

    function buildPreviewSnapshot() {
        const iframe = getPreviewIframe();
        const showcasePreviewActive = isShowcasePlaceholderActive();
        const iframeSrc = getPreviewIframeSrc();
        let html = '';
        let mode = '';

        if (!iframe) {
            return null;
        }

        if (showcasePreviewActive) {
            html = getLivePreviewHtmlInternal();
            if (!html && typeof window.vmoGetShowcasePreviewHtml === 'function') {
                html = window.vmoGetShowcasePreviewHtml();
            }
            if (typeof window.vmoHasMeaningfulPreviewHtml === 'function' && !window.vmoHasMeaningfulPreviewHtml(html)) {
                html = '';
            }
            if (!html || !html.trim()) {
                return null;
            }
            mode = 'showcase';
        } else {
            html = getLivePreviewHtmlInternal();
            if (typeof window.vmoHasMeaningfulPreviewHtml === 'function' && !window.vmoHasMeaningfulPreviewHtml(html)) {
                html = '';
            }
            if ((!html || !html.trim()) && typeof window.vmoNormalizeBuilderHtml === 'function') {
                html = window.vmoNormalizeBuilderHtml(window.lastContent || '');
            }

            if (html && html.trim()) {
                if (typeof window.vmoShouldTreatAsRealContent === 'function'
                    && !window.vmoShouldTreatAsRealContent(html, window.vmoState)) {
                    html = '';
                }
            }

            if (html && html.trim()) {
                mode = 'html';
            } else if (window.vmoPreviewIsLive && iframeSrc) {
                mode = 'live-url';
            } else {
                return null;
            }
        }

        return {
            version: 1,
            ts: Date.now(),
            mode: mode,
            html: html || '',
            src: mode === 'live-url' ? iframeSrc : '',
            previewIsLive: !!window.vmoPreviewIsLive,
            showcasePreviewActive: showcasePreviewActive,
            currentProjectId: window.currentProjectId || null,
            currentProjectTitle: window.currentProjectTitle || null,
            currentLivePageId: window.currentLivePageId || null
        };
    }

    window.vmoPersistPreviewFrameState = function(reason) {
        const snapshot = buildPreviewSnapshot();

        if (!snapshot) {
            return false;
        }

        const persisted = writePersistedPreviewState(snapshot);
        if (persisted && window.vmoDebug) {
            console.log('[VMO Theme] Preview snapshot persisted:', reason || 'manual', snapshot.mode);
        }
        return persisted;
    };

    window.vmoRestorePersistedPreviewFrameState = function(options = {}) {
        const iframe = getPreviewIframe();
        const snapshot = readPersistedPreviewState();
        const force = !!options.force;
        const allowLiveUrl = options.allowLiveUrl !== false;

        if (!iframe || !snapshot) {
            return false;
        }

        if (!force && hasActiveIframePreview()) {
            return false;
        }

        if (snapshot.mode === 'showcase' && snapshot.html) {
            if (typeof window.vmoHasMeaningfulPreviewHtml === 'function' && !window.vmoHasMeaningfulPreviewHtml(snapshot.html)) {
                writePersistedPreviewState(null);
                try {
                    sessionStorage.removeItem(PREVIEW_SNAPSHOT_KEY);
                } catch (_) {}
                return false;
            }
            window.vmoPreviewIsLive = false;
            window.vmoHasContent = false;
            window.lastContent = '';
            window.vmoShowcasePreviewHtml = snapshot.html;
            iframe.removeAttribute('src');
            iframe.dataset.vmoPreviewMode = 'showcase-placeholder';
            iframe.dataset.vmoShowcaseMediaState = 'persisted';
            iframe.srcdoc = snapshot.html;
            if (typeof window.vmoGenerateShowcaseMedia === 'function') {
                setTimeout(function() {
                    window.vmoGenerateShowcaseMedia();
                }, 180);
            }
            return true;
        }

        if (snapshot.mode === 'html' && snapshot.html) {
            if (typeof window.vmoHasMeaningfulPreviewHtml === 'function' && !window.vmoHasMeaningfulPreviewHtml(snapshot.html)) {
                try {
                    sessionStorage.removeItem(PREVIEW_SNAPSHOT_KEY);
                } catch (_) {}
                return false;
            }
            if (typeof window.vmoShouldTreatAsRealContent === 'function'
                && !window.vmoShouldTreatAsRealContent(snapshot.html, window.vmoState)) {
                return false;
            }

            window.vmoPreviewIsLive = false;
            window.vmoHasContent = true;
            window.lastContent = snapshot.html;
            iframe.removeAttribute('src');
            delete iframe.dataset.vmoPreviewMode;
            iframe.srcdoc = snapshot.html;

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

        if (allowLiveUrl && snapshot.mode === 'live-url' && snapshot.src) {
            window.vmoPreviewIsLive = true;
            iframe.removeAttribute('srcdoc');
            delete iframe.dataset.vmoPreviewMode;
            iframe.setAttribute('src', snapshot.src);
            return true;
        }

        return false;
    };

    function bindPreviewPersistenceLifecycle() {
        const iframe = getPreviewIframe();

        if (!window.__vmoPreviewPersistenceBound) {
            window.__vmoPreviewPersistenceBound = true;

            window.addEventListener('pagehide', function() {
                window.vmoPersistPreviewFrameState('pagehide');
            });

            window.addEventListener('beforeunload', function() {
                window.vmoPersistPreviewFrameState('beforeunload');
            });

            window.addEventListener('pageshow', function() {
                setTimeout(function() {
                    if (!window.vmoRestorePersistedPreviewFrameState()) {
                        window.vmoPersistPreviewFrameState('pageshow');
                    }
                }, 140);
            });

            document.addEventListener('visibilitychange', function() {
                if (document.visibilityState === 'hidden') {
                    window.vmoPersistPreviewFrameState('visibilitychange-hidden');
                } else {
                    setTimeout(function() {
                        if (!window.vmoRestorePersistedPreviewFrameState()) {
                            window.vmoPersistPreviewFrameState('visibilitychange-visible');
                        }
                    }, 140);
                }
            });
        }

        if (iframe && iframe.dataset.vmoPreviewPersistenceBound !== '1') {
            iframe.dataset.vmoPreviewPersistenceBound = '1';
            iframe.addEventListener('load', function() {
                setTimeout(function() {
                    window.vmoPersistPreviewFrameState('iframe-load');
                }, 160);
            });
        }

        setTimeout(function() {
            if (!window.vmoRestorePersistedPreviewFrameState()) {
                window.vmoPersistPreviewFrameState('initial-pass');
            }
        }, 220);
    }

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

    function isShowcasePlaceholderActive() {
        if (typeof window.vmoIsShowcasePreviewActive === 'function') {
            return !!window.vmoIsShowcasePreviewActive();
        }

        const iframe = document.getElementById('vmo-preview-iframe');
        if (!iframe) return false;
        if (iframe.dataset && iframe.dataset.vmoPreviewMode === 'showcase-placeholder') return true;

        try {
            return !!iframe.contentDocument?.getElementById('vmo-demo-showcase');
        } catch (_) {
            return false;
        }
    }

    function getCurrentPreviewHtml() {
        const snapshot = readPersistedPreviewState();
        const liveHtml = getLivePreviewHtmlInternal();

        if (liveHtml && liveHtml.trim()) {
            return liveHtml;
        }

        if (!getPreviewIframe()) {
            return snapshot && snapshot.html ? String(snapshot.html) : '';
        }

        return snapshot && snapshot.html ? String(snapshot.html) : '';
    }

    function hasRenderableBackgroundMedia(el) {
        if (!el) return false;

        const inlineBackground = el.style && el.style.backgroundImage ? String(el.style.backgroundImage) : '';
        if (inlineBackground && inlineBackground !== 'none') {
            return true;
        }

        try {
            const computedBackground = window.getComputedStyle(el).backgroundImage;
            return !!computedBackground && computedBackground !== 'none' && computedBackground.indexOf('url(') !== -1;
        } catch (_) {
            return false;
        }
    }

    function hasNestedRenderableMedia(el) {
        if (!el || typeof el.querySelector !== 'function') return false;

        try {
            return !!el.querySelector('img, video, audio, canvas, svg, embed, object, iframe, .vmo-media-placeholder, [data-vmo-generate], [data-vmo-sora]');
        } catch (_) {
            return false;
        }
    }

    function isExplicitMediaSlot(el) {
        if (!el || !el.classList) return false;

        return el.classList.contains('vmo-media-placeholder')
            || el.classList.contains('vmo-media-placeholder-image')
            || el.classList.contains('vmo-media-placeholder-video')
            || el.hasAttribute('data-vmo-generate')
            || el.hasAttribute('data-vmo-sora')
            || el.getAttribute('data-bg') === '1';
    }

    function resolveReplaceTargetType(el) {
        if (!el || !el.tagName) return 'image';

        const tagName = el.tagName.toLowerCase();
        const dataType = String(el.getAttribute('data-type') || el.getAttribute('data-media-type') || '').toLowerCase();
        const source = String(el.getAttribute('src') || el.getAttribute('data-src') || el.getAttribute('data') || '').toLowerCase();

        if (dataType === 'video' || el.hasAttribute('data-vmo-sora') || el.classList.contains('vmo-media-placeholder-video')) {
            return 'video';
        }

        if (tagName === 'video') {
            return 'video';
        }

        if (tagName === 'iframe' && /(youtube|vimeo|dailymotion|twitch|facebook|instagram)/i.test(source)) {
            return 'video';
        }

        if (/\.(mp4|webm|ogg|mov|m4v)(\?|$)/i.test(source)) {
            return 'video';
        }

        return 'image';
    }
    
    // Helper function to validate if element is actually media
    function isValidMediaElement(el) {
        if (!el || !el.tagName) return false;
        
        const tagName = el.tagName.toLowerCase();
        const directMediaTags = ['img', 'video', 'canvas', 'svg', 'embed', 'object', 'iframe'];
        const hasNestedMedia = hasNestedRenderableMedia(el);
        const hasBackgroundMedia = hasRenderableBackgroundMedia(el);
        const explicitSlot = isExplicitMediaSlot(el);

        if (tagName === 'source') {
            return false;
        }

        // Skip wrapper nodes that merely contain media. We want buttons anchored to the actual media slot.
        if (hasNestedMedia && !directMediaTags.includes(tagName) && !hasBackgroundMedia && !explicitSlot) {
            return false;
        }

        // Skip if too small (likely decorative)
        const rect = el.getBoundingClientRect();
        if (rect.width < 20 || rect.height < 20) {
            return false;
        }
        
        // Direct media tags
        if (directMediaTags.includes(tagName)) {
            return true;
        }
        
        // Elements with background images
        if (hasBackgroundMedia) {
            if (!el.getAttribute('data-bg')) {
                el.setAttribute('data-bg', '1');
            }
            return true;
        }

        if (explicitSlot) {
            return true;
        }
        
        // Elements with media-related attributes
        if (el.hasAttribute('src') || el.hasAttribute('data-src') || el.hasAttribute('srcset')) {
            return true;
        }
        
        // Elements with media-related classes
        const mediaClasses = ['media', 'image', 'video', 'photo', 'picture', 'gallery', 'thumbnail'];
        for (const cls of mediaClasses) {
            if (String(el.className || '').toLowerCase().includes(cls) && !hasNestedMedia) {
                return true;
            }
        }
        
        return false;
    }
    
    /* ------------------------------------------------------------------
       1.  OVERLAY HELPER — adds ONE context‑aware button per media
       ------------------------------------------------------------------ */
    function vmoInjectReplaceButtonsInIframe() {
        console.log('🔧 vmoInjectReplaceButtonsInIframe called');
        const iframe = document.getElementById('vmo-preview-iframe');
        if (!iframe?.contentDocument) {
            console.log('❌ No iframe or contentDocument found');
            return;
        }

        const doc = iframe.contentDocument;
        console.log('✅ Iframe document found');

        // Remove existing overlay buttons
        const existingButtons = doc.querySelectorAll('.vmo-replace-overlay, .replace-image-btn, .replace-video-btn');
        console.log('🧹 Removing existing buttons:', existingButtons.length);
        existingButtons.forEach(btn => btn.remove());

        // COMPREHENSIVE media selectors - covers ALL possible media elements
        const mediaSelectors = [
            // VMO-specific placeholders
            '.vmo-media-placeholder',
            '[data-media-id]',
            '[data-media-type]',
            
            // Standard HTML media
            'img:not(.vmo-replace-overlay):not([data-noneditable]):not([src=""])',
            'video:not(.vmo-replace-overlay):not([data-noneditable])',
            'audio:not(.vmo-replace-overlay):not([data-noneditable])',
            'source[srcset]',
            'embed[src]',
            'object[data]',
            'canvas',
            
            // Iframe content (YouTube, Vimeo, etc.)
            'iframe[src*="youtube"]', 'iframe[src*="vimeo"]', 'iframe[src*="dailymotion"]',
            'iframe[src*="twitch"]', 'iframe[src*="facebook"]', 'iframe[src*="instagram"]',
            
            // WordPress blocks
            '.wp-block-image img', '.wp-block-image', 
            '.wp-block-video video', '.wp-block-video',
            '.wp-block-media-text img', '.wp-block-media-text',
            '.wp-block-cover', '.wp-block-gallery img', '.wp-block-gallery',
            '.wp-block-audio', '.wp-block-file',
            
            // Semantic HTML
            'figure img', 'figure video', 'figure',
            'picture img', 'picture',
            
            // Common class names and patterns
            '.media-element', '.hero-image', '.background-image', '.banner-image',
            '.featured-image', '.thumbnail', '.gallery-item', '.slider-image',
            '.card-image', '.profile-image', '.avatar', '.logo', '.icon-image',
            
            // Data attributes and roles
            '[data-type="image"]', '[data-type="video"]', '[data-type="media"]',
            '[role="img"]', '[aria-label*="image" i]', '[aria-label*="video" i]',
            
            // Background images (any element with background-image)
            '[style*="background-image"]:not(body):not(html)',
            
            // Generated content areas that might contain media
            '.content img', '.post-content img', '.entry-content img',
            '.article img', '.section img', '.container img',
            
            // Small media elements
            'img[width][height]', 'img[style*="width"]', 'img[style*="height"]',
            
            // SVG and vector graphics
            'svg image', 'svg', 'use[href*="#"]',
            
            // Plugin-generated content
            '.elementor-image img', '.elementor-video', '.elementor-background-video',
            '.vc_single_image img', '.vc_video', 
            '.fusion-image img', '.fusion-video',
            
            // Any element that looks like it could be media
            '*[src*=".jpg"]', '*[src*=".jpeg"]', '*[src*=".png"]', '*[src*=".gif"]', 
            '*[src*=".webp"]', '*[src*=".svg"]', '*[src*=".mp4"]', '*[src*=".webm"]',
            '*[href*=".jpg"]', '*[href*=".jpeg"]', '*[href*=".png"]', '*[href*=".gif"]'
        ];
        
        let allMediaEls = [];
        let elementMap = new Map(); // Prevent duplicates
        
        mediaSelectors.forEach(selector => {
            try {
                const elements = [...doc.querySelectorAll(selector)];
                elements.forEach(el => {
                    // Skip if already processed or is a button
                    if (!elementMap.has(el) && 
                        !el.classList.contains('vmo-replace-overlay') && 
                        !el.hasAttribute('data-noneditable') &&
                        el.tagName !== 'BUTTON') {
                        
                        // Additional validation for actual media content
                        if (isValidMediaElement(el)) {
                            elementMap.set(el, true);
                            allMediaEls.push(el);
                        }
                    }
                });
            } catch (e) {
                console.warn('Selector failed:', selector, e);
            }
        });
        
        // Additional scan for elements with background images
        const allElements = [...doc.querySelectorAll('*')];
        allElements.forEach(el => {
            const bgImage = window.getComputedStyle(el).backgroundImage;
            if (bgImage && bgImage !== 'none' && bgImage.includes('url(') && 
                !elementMap.has(el) && !el.classList.contains('vmo-replace-overlay')) {
                if (isValidMediaElement(el)) {
                    elementMap.set(el, true);
                    allMediaEls.push(el);
                }
            }
        });
        
        console.log('🎯 Found media elements:', allMediaEls.length, allMediaEls);

        if (!allMediaEls.length) {
            const showcasePreviewActive = (iframe.dataset && iframe.dataset.vmoPreviewMode === 'showcase-placeholder')
                || (typeof window.vmoIsShowcasePreviewActive === 'function' && window.vmoIsShowcasePreviewActive());
            const docBodyHtml = doc && doc.body ? String(doc.body.innerHTML || '').trim() : '';
            const hasShowcaseStructure = !!(doc
                && ((typeof doc.getElementById === 'function' && doc.getElementById('vmo-showcase-stage'))
                    || (typeof doc.querySelector === 'function' && doc.querySelector('.vmo-showcase-slide, .demo-hero, .demo-shell'))));

            if (showcasePreviewActive
                && (!docBodyHtml || !hasShowcaseStructure)
                && typeof window.vmoRecoverShowcasePlaceholder === 'function') {
                if (window.vmoRecoverShowcasePlaceholder('replace-buttons-empty')) {
                    return;
                }
            }
        }

        allMediaEls.forEach((el, idx) => {
            console.log(`📍 Processing media element ${idx}:`, el, 'tagName:', el.tagName);
            
            // Ensure stable id for delegation
            if (!el.dataset.mediaId) {
                el.dataset.mediaId = `media-${Date.now()}-${idx}`;
            }
            
            // Enhanced data-type detection for comprehensive media support
            if (!el.dataset.type) {
                const tagName = el.tagName.toLowerCase();
                
                if (tagName === 'video' || el.querySelector('video')) {
                    el.dataset.type = 'video';
                } else if (tagName === 'iframe' && (el.src?.includes('youtube') || el.src?.includes('vimeo'))) {
                    el.dataset.type = 'video';
                } else if (tagName === 'img' || 
                          el.style.backgroundImage || 
                          el.querySelector('img') ||
                          tagName === 'canvas' ||
                          tagName === 'svg' ||
                          el.classList.contains('wp-block-image') ||
                          el.classList.contains('wp-block-cover') ||
                          el.classList.contains('hero-image') ||
                          el.classList.contains('background-image') ||
                          el.hasAttribute('role') && el.getAttribute('role') === 'img') {
                    el.dataset.type = 'image';
                } else if (tagName === 'embed' || tagName === 'object') {
                    // Determine if it's video or image based on src/data
                    const src = el.src || el.data || '';
                    if (src.match(/\.(mp4|webm|ogg|mov|avi)$/i)) {
                        el.dataset.type = 'video';
                    } else {
                        el.dataset.type = 'image';
                    }
                } else {
                    el.dataset.type = 'image'; // safe default
                }
            }
            
            // Ensure vmo-media-placeholder class
            if (!el.classList.contains('vmo-media-placeholder')) {
                el.classList.add('vmo-media-placeholder');
            }

            // Create replace button with adaptive sizing
            const isVideo = el.dataset.type === 'video' || el.tagName.toLowerCase() === 'video';
            const btn = doc.createElement('button');
            btn.className = 'vmo-replace-overlay';
            btn.dataset.mediaId = el.dataset.mediaId;
            btn.dataset.mediaType = resolveReplaceTargetType(el);
            btn.dataset.noneditable = '1';
            btn.setAttribute('data-noneditable', '1');
            btn.contentEditable = 'false';
            btn.textContent = isVideo ? 'Replace Video' : 'Replace Image';
            
            // Get element dimensions for adaptive button sizing
            const rect = el.getBoundingClientRect();
            const isSmall = rect.width < 100 || rect.height < 100;
            const isTiny = rect.width < 50 || rect.height < 50;
            
            // Adaptive button styling based on element size
            let buttonStyles = {
                position: 'absolute',
                zIndex: '9999',
                background: '#00f8ff',
                border: 'none',
                borderRadius: '4px',
                fontWeight: '600',
                cursor: 'pointer',
                pointerEvents: 'auto',
                color: '#000',
                boxShadow: '0 2px 8px rgba(0,248,255,0.4)',
                fontFamily: 'system-ui, -apple-system, sans-serif'
            };
            
            if (isTiny) {
                // Ultra-small elements get minimal button
                Object.assign(buttonStyles, {
                    top: '2px',
                    right: '2px',
                    padding: '2px 4px',
                    fontSize: '8px',
                    borderRadius: '2px'
                });
                btn.textContent = isVideo ? '📹' : '🖼️'; // Icon only for tiny elements
            } else if (isSmall) {
                // Small elements get compact button
                Object.assign(buttonStyles, {
                    top: '4px',
                    right: '4px',
                    padding: '3px 6px',
                    fontSize: '9px'
                });
                btn.textContent = isVideo ? 'Replace' : 'Replace'; // Shorter text
            } else {
                // Normal-sized elements get full button
                Object.assign(buttonStyles, {
                    top: '6px',
                    right: '6px',
                    padding: '4px 8px',
                    fontSize: '11px'
                });
            }
            
            // Apply styles
            const styleString = Object.entries(buttonStyles)
                .map(([key, value]) => `${key.replace(/([A-Z])/g, '-$1').toLowerCase()}:${value}`)
                .join(';');
            btn.style.cssText = styleString;
            
            console.log(`✅ Created button for ${el.dataset.mediaId}:`, btn);

            // Enhanced parent positioning and button attachment
            let parent = el.parentElement;
            
            // Find the best parent for positioning
            let attempts = 0;
            while (parent && attempts < 3) {
                const parentRect = parent.getBoundingClientRect();
                const parentStyle = window.getComputedStyle(parent);
                
                // Check if parent is large enough and suitable for positioning
                if (parentRect.width > rect.width * 0.9 && parentRect.height > rect.height * 0.9) {
                    break;
                }
                parent = parent.parentElement;
                attempts++;
            }
            
            // Fall back to element itself if no suitable parent
            if (!parent || attempts >= 3) {
                parent = el;
            }
            
            // Ensure parent has relative positioning (or is already positioned)
            const parentComputedStyle = window.getComputedStyle(parent);
            const currentPosition = parentComputedStyle.position;
            
            if (!['relative', 'absolute', 'fixed', 'sticky'].includes(currentPosition)) {
                parent.style.position = 'relative';
            }
            
            // Ensure parent has space for the button
            const parentPaddingTop = parseInt(parentComputedStyle.paddingTop) || 0;
            const parentPaddingRight = parseInt(parentComputedStyle.paddingRight) || 0;
            
            // Adjust button position if parent has insufficient padding
            if (parentPaddingTop < 30) {
                parent.style.paddingTop = Math.max(parentPaddingTop, 30) + 'px';
            }
            if (parentPaddingRight < 80) {
                parent.style.paddingRight = Math.max(parentPaddingRight, 80) + 'px';
            }
            
            // Add hover effects to make button more discoverable
            btn.addEventListener('mouseenter', () => {
                btn.style.background = '#00d4ff';
                btn.style.transform = 'scale(1.05)';
            });
            
            btn.addEventListener('mouseleave', () => {
                btn.style.background = '#00f8ff';
                btn.style.transform = 'scale(1)';
            });
            
            // Append button to parent
            parent.appendChild(btn);
            
            // Add a data attribute to track that this element has a button
            el.setAttribute('data-vmo-has-button', 'true');
        });

        console.log(`🎉 Replace button injection complete: ${allMediaEls.length} elements processed`);
        
        // Set up mutation observer to handle dynamically added content
        if (!doc._vmoMutationObserver) {
            let debounceTimer = null;
            
            const observer = new MutationObserver((mutations) => {
                let hasNewMedia = false;
                mutations.forEach(mutation => {
                    if (mutation.type === 'childList') {
                        mutation.addedNodes.forEach(node => {
                            if (node.nodeType === 1) { // Element node
                                // Check if added node or its children contain media
                                const newMediaElements = [node, ...node.querySelectorAll('img, video, canvas, svg, iframe, [style*="background-image"]')];
                                if (newMediaElements.some(el => isValidMediaElement(el))) {
                                    hasNewMedia = true;
                                }
                            }
                        });
                    }
                });
                
                if (hasNewMedia) {
                    console.log('🔄 New media detected, scheduling button injection...');
                    
                    // Debounce to avoid excessive re-injections
                    clearTimeout(debounceTimer);
                    debounceTimer = setTimeout(() => {
                        vmoInjectReplaceButtonsInIframe();
                    }, 300);
                }
            });
            
            const targetNode = doc && doc.body;
            if (targetNode && targetNode.nodeType === 1) {
                observer.observe(targetNode, {
                    childList: true,
                    subtree: true,
                    attributes: false
                });
                doc._vmoMutationObserver = observer;
                console.log('👀 Mutation observer set up for dynamic content');
            } else {
                console.warn('[VMO Theme] Skipped mutation observer setup: no valid document body found');
            }
        }
    }

    /* ------------------------------------------------------------------
       2.  "VIEW IN BROWSER" BUTTON
       Opens the current local site preview in a new browser tab.
       ------------------------------------------------------------------ */
    $(document).on('click', '#vmo-view-browser-btn', function () {
        const showcasePreviewActive = isShowcasePlaceholderActive();
        const persistedPreview = readPersistedPreviewState();
        const currentIframePreview = getCurrentPreviewHtml();

        // Always sync lastContent from vmoState if available
        if (window.vmoState && window.vmoState.blocks && window.vmoState.blocks.length) {
            window.lastContent = window.vmoState.blocks.map(b => b.html).join('\n');
        }

        if (typeof window.vmoNormalizeBuilderHtml === 'function') {
            window.lastContent = window.vmoNormalizeBuilderHtml(window.lastContent || '');
        }
        
        // Fallback: try localStorage checkpoint if lastContent is still empty
        if ((!window.lastContent || !window.lastContent.trim())
            || (typeof window.vmoShouldTreatAsRealContent === 'function' && !window.vmoShouldTreatAsRealContent(window.lastContent, window.vmoState))) {
            window.lastContent = '';
            try {
                var lsHtml = localStorage.getItem('vmo_checkpoint_html');
                var normalizedLsHtml = typeof window.vmoNormalizeBuilderHtml === 'function'
                    ? window.vmoNormalizeBuilderHtml(lsHtml)
                    : (lsHtml || '');
                if (normalizedLsHtml && normalizedLsHtml.trim()
                    && (typeof window.vmoShouldTreatAsRealContent !== 'function' || window.vmoShouldTreatAsRealContent(normalizedLsHtml, window.vmoState))) {
                    window.lastContent = normalizedLsHtml;
                }
            } catch (e) { /* ignore */ }
        }

        let previewPayload = currentIframePreview || '';
        if (!previewPayload && showcasePreviewActive && typeof window.vmoGetShowcasePreviewHtml === 'function') {
            previewPayload = window.vmoGetShowcasePreviewHtml();
        }
        if (!previewPayload && !showcasePreviewActive) {
            previewPayload = window.lastContent || '';
        }
        if (!previewPayload && persistedPreview && persistedPreview.html) {
            previewPayload = persistedPreview.html;
        }
        if (!showcasePreviewActive && typeof window.vmoShouldTreatAsRealContent === 'function' && !window.vmoShouldTreatAsRealContent(previewPayload, window.vmoState)) {
            previewPayload = '';
        }

        if (!previewPayload || !previewPayload.trim()) {
            return showToast(showcasePreviewActive
                ? 'The demo showcase is still being prepared. Please wait for the preview to finish loading.'
                : 'Nothing to preview. Build or restore a website first.', 'error');
        }

        // Prefer a full HTML document so the preview renders exactly like the builder.
        // This allows the preview endpoint to split head/body/footer and use the VMO template runtime.
        try {
            if (typeof window.wrapIframeContent === 'function') {
                previewPayload = window.wrapIframeContent(previewPayload);
            }
        } catch (e) {
            // fall back to raw HTML
        }

        showToast(showcasePreviewActive ? 'Opening demo showcase in browser...' : 'Opening in browser...', 'info', true);

        $.post(vmo_ajax.ajaxurl, {
            action  : 'vmo_preview_in_browser',
            security: vmo_ajax.nonce,
            content : previewPayload
        }).done(res => {
            hideToast(true);
            const previewLink = res && res.success && res.data && res.data.link ? res.data.link : '';

            if (previewLink) {
                window.open(previewLink, '_blank', 'noopener,noreferrer');
            } else {
                showToast(res.data?.message || 'Failed to open preview.', 'error');
            }
        }).fail(() => {
            hideToast(true);
            showToast('Failed to generate preview.', 'error');
        });
    });

    /* ------------------------------------------------------------------
       3.  THEME & UI TOGGLES
       ------------------------------------------------------------------ */
    $('#vmo-theme-toggle').off('click').on('click', () => {
        $('body').toggleClass('vmo-light-mode');
        localStorage.setItem('vmo-theme', $('body').hasClass('vmo-light-mode') ? 'light' : 'dark');
    });

    if (localStorage.getItem('vmo-theme') === 'light') $('body').addClass('vmo-light-mode');

    /* Code <-> Preview toggle with token-based access control */
    $('#vmo-view-code-btn').off('click').on('click', function () {
        const showingCode = $('#vmo-code-view').is(':visible');
        
        // Check if trying to show code view (not hide it)
        if (!showingCode) {
            // Check token balance for code view access
            const currentBalance = parseInt(vmo_ajax.token_balance) || 0;
            
            if (currentBalance <= 0) {
                // No balance = no code view access
                if (typeof window.showToast === 'function') {
                    window.showToast('🔒 Code view requires an active balance. Upgrade or add an add-on to access premium features.', 'warning');
                }
                return; // Block code view access
            }
        }
        
        $('#vmo-preview-title').text(showingCode ? 'Live Preview' : 'Code View');
        $('#vmo-code-view').toggle(!showingCode);
        $('#vmo-preview-iframe').toggle(showingCode);
    });

    /* Click‑outside to close dropdown menus */
    $(document).on('click', e => {
        if (!$(e.target).closest('.vmo-load-toggle-group, #vmo_load_project_btn').length) {
            $('#vmo-load-menu').removeClass('open');
        }
        if (!$(e.target).closest('.vmo-upgrade-toggle-group').length) {
            $('#vmo-upgrade-menu').removeClass('open');
        }
    });

    // Global binding for replace button injection
    window.vmoInjectReplaceButtonsInIframe = vmoInjectReplaceButtonsInIframe;

    // Auto inject after a brief delay
    $(document).ready(function() {
        setTimeout(vmoInjectReplaceButtonsInIframe, 250);
    });

})(jQuery);