<?php

namespace FleekDash\Admin\Editor;

use FleekDash\Admin\Iframe\IframeHelpers;

/**
 * Editor Iframe Management
 *
 * Handles JavaScript injection for nested iframes in both TinyMCE (Classic Editor)
 * and Gutenberg (Block Editor).
 *
 * @package FleekDash\Admin\Editor
 * @since 2.2.0
 */
class EditorIframeManager
{
    public static function injectEditorIframeScripts()
    {
        // CRITICAL OPTIMIZATION: Only load TinyMCE iframe sync on post edit/create pages
        $current_screen = get_current_screen();
        $is_post_edit_screen = false;

        if ($current_screen) {
            // Check if we're on post edit, page edit, or custom post type edit screens
            $is_post_edit_screen = (
                $current_screen->base === 'post' ||
                ($current_screen->base === 'post' && $current_screen->action === 'add') ||
                in_array($current_screen->post_type, ['post', 'page']) ||
                (isset($current_screen->post_type) && \post_type_supports($current_screen->post_type, 'editor'))
            );
        }

        // If not on a post edit screen, skip TinyMCE iframe sync completely
        if (!$is_post_edit_screen) {
            return;
        }

        $theme_css_url = \FleekDash\Libs\Assets\getCssUrl(
            \FleekDash\Admin\Iframe\IframeCSSManager::getAdminSkinCssEntry()
        );
        $should_inject_theme_css = !IframeHelpers::isProtectedRequest();
        $debugModeJS = false; // Verbose iframe logging: add ?fleekdash-debug or localStorage fleekdash-debug
        ?>
        <script>
            ( function () {
                window.fleekDashIframeSyncInitialized = window.fleekDashIframeSyncInitialized || false;
                if ( window.fleekDashIframeSyncInitialized ) return;
                window.fleekDashIframeSyncInitialized = true;

                const INJECTION_TIMEOUT = 500;
                const lastInjectionTime = new Map();

                // Optimized logging - only log errors and critical events
                const isDebugMode = window.location.search.includes( 'fleekdash-debug' ) || localStorage.getItem( 'fleekdash-debug' ) === 'true';

                function log ( ...args ) {
                    if ( isDebugMode ) {
                        console.log( 'FleekDash:', ...args );
                    }
                }

                // REMOVED: debounce() function
                // No longer needed with cascaded inheritance system

                // REMOVED: Enhanced execution control system
                // No longer needed with cascaded inheritance system

                function canInjectResources ( iframe ) {
                    if ( !iframe ) return false;
                    const iframeId = iframe.id || iframe.name || iframe.src;
                    const now = Date.now();
                    const lastTime = lastInjectionTime.get( iframeId ) || 0;
                    if ( now - lastTime > INJECTION_TIMEOUT ) {
                        lastInjectionTime.set( iframeId, now );
                        return true;
                    }
                    log( 'Skipping recent iframe, too soon to reinject', iframeId );
                    return false;
                }

                // REMOVED: syncIframeThemeNow() function
                // Replaced by cascaded inheritance system that automatically inherits from parent

                // Inject theme CSS and helper scripts into the editor iframe document
                function injectResources ( iframe ) {
                    if ( !iframe || !iframe.contentDocument || !iframe.contentWindow ) {
                        log( 'Iframe, contentDocument or contentWindow not available' );
                        return false;
                    }

                    try {
                        // Throttle reinjection per iframe
                        if ( !canInjectResources( iframe ) ) return false;

                        const iframeHtml = iframe.contentDocument.documentElement;
                        if ( !iframeHtml ) {
                            log( 'Iframe HTML element not found.' );
                            return false;
                        }

                        // Skip if this iframe was already initialized (unless hotkey script is missing)
                        if ( iframeHtml.getAttribute( 'data-fleekdash-initialized' ) === 'true' ) {
                            // Check if hotkey script exists, if not inject it
                            const hotkeyScriptId = 'fleekdash-theme-script';
                            if ( !iframe.contentDocument.getElementById( hotkeyScriptId ) ) {
                                // Continue with script injection below
                            } else {
                                return false;
                            }
                        }
                        iframeHtml.setAttribute( 'data-fleekdash-initialized', 'true' );

                        // Apply initial theme - REFACTORED to use shared module
                        let isDark;
                        let theme;

                        // Check if shared module is available
                        if (typeof window.fleekDashThemeSync !== 'undefined') {
                            const result = window.fleekDashThemeSync.syncTheme({ verbose: false });
                            isDark = result.isDark;
                            theme = document.documentElement.getAttribute('data-theme') || 'starter';
                            log('Theme applied via shared module:', { isDark, theme, mode: result.mode });
                        } else {
                            // Fallback if module not loaded
                            isDark = document.documentElement.classList.contains('dark');
                            theme = document.documentElement.getAttribute('data-theme') || 'starter';
                            log('Theme applied via fallback (module not loaded):', { isDark, theme });
                        }

                        iframeHtml.classList.remove('dark', 'light');
                        iframeHtml.classList.add(isDark ? 'dark' : 'light');
                        iframeHtml.setAttribute('data-theme', theme);

                        // Transparent background
                        iframeHtml.style.backgroundColor = 'transparent';
                        iframeHtml.style.color = isDark ? 'white' : 'var(--foreground)';

                        log('Initial theme applied:', { iframe: iframe.id, isDark, theme });

                        // Theme will be handled by main application sync

                        // 2. Inject CSS only when protected mode is not active
                        const shouldInjectThemeCss = <?php echo $should_inject_theme_css ? 'true' : 'false'; ?>;
                        if ( shouldInjectThemeCss ) {
                            const cssUrl = '<?php echo \esc_url($theme_css_url); ?>';
                            const cssId = 'fleekdash-theme-css';
                            if ( !iframe.contentDocument.getElementById( cssId ) ) {
                                const cssLink = document.createElement( 'link' );
                                cssLink.rel = 'stylesheet';
                                cssLink.href = cssUrl;
                                cssLink.type = 'text/css';
                                cssLink.id = cssId;
                                iframe.contentDocument.head.appendChild( cssLink );
                                log( 'Injected CSS into iframe', iframe.id || iframe.src );
                            } else {
                                log( 'CSS already exists in iframe', iframe.id || iframe.src );
                            }
                        }

                        // 2.5. Theme shortcut script (keyboard shortcuts) — inject once per iframe
                        const hotkeyScriptId = 'fleekdash-theme-shortcut';
                        if ( !iframe.contentDocument.getElementById( hotkeyScriptId ) ) {
                            const hotkeyScriptUrl = '<?php echo \esc_url(\FleekDash\Libs\Assets\getJsUrl('theme-shortcut')); ?>';
                            const hotkeyScript = document.createElement( 'script' );
                            hotkeyScript.src = hotkeyScriptUrl;
                            hotkeyScript.type = 'text/javascript';
                            hotkeyScript.id = hotkeyScriptId;
                            hotkeyScript.defer = true;
                            iframe.contentDocument.head.appendChild( hotkeyScript );
                            log( 'Injected theme-shortcut.js into iframe for hotkeys', iframe.id || iframe.src );
                        } else {
                            log( 'Theme-shortcut.js already exists in iframe', iframe.id || iframe.src );
                        }

                        // 3. Inline theme sync script — inject once per iframe
                        const scriptId = 'fleekdash-theme-script';
                        if ( !iframe.contentDocument.getElementById( scriptId ) ) {
                            // Listens for postMessage theme updates and applies classes/attributes
                            const syncScript = `
                                (function() {
                                    if (window.fleekDashThemeSyncInitialized) return;
                                    window.fleekDashThemeSyncInitialized = true;
                                    const debug = <?php echo json_encode($debugModeJS); ?>;


                                    // FORCE TRANSPARENT BACKGROUND FOR TINYMCE
                                    function forceTransparentBackground() {
                                        try {
                                            // Apply transparent background to all possible TinyMCE elements
                                            const elements = [
                                                document.documentElement,
                                                document.body,
                                                document.getElementById('tinymce'),
                                                document.querySelector('.mce-content-body'),
                                                document.querySelector('#tinymce'),
                                                document.querySelector('body.mce-content-body')
                                            ].filter(Boolean);

                                            elements.forEach(el => {
                                                if (el) {
                                                    el.style.backgroundColor = 'transparent';
                                                    el.style.background = 'transparent';
                                                }
                                            });

                                            // Also apply via CSS injection
                                            const style = document.createElement('style');
                                            style.textContent = \`
                                                html, body, #tinymce, .mce-content-body, body.mce-content-body {
                                                    background: transparent !important;
                                                    background-color: transparent !important;
                                                }
                                            \`;
                                            document.head.appendChild(style);

                                            if (debug) console.log('FleekDash TinyMCE: Forced transparent background');
                                        } catch (e) {
                                            if (debug) console.warn('FleekDash TinyMCE: Error forcing transparent background:', e);
                                        }
                                    }

                                    // Apply immediately and on theme changes
                                    forceTransparentBackground();

                                    // REMOVED: applyDefinitiveTheme() function
                                    // Replaced by syncAllIframesDefinitive() which handles everything more efficiently

                                    // Extract handlers for cleanup
                                    const handleTinyMCEStorage = function(e) {
                                        if (e.key === 'fleekdash-dark-mode' || e.key === 'fleekdash-theme') {
                                            if (debug) console.log('FleekDash TinyMCE: Theme changed in localStorage');
                                            // Theme changes handled by main application sync
                                        }
                                    };

                                    const handleTinyMCEMessage = function(event) {
                                        if (event.data && event.data.type === 'themeChange') {
                                            if (debug) console.log('FleekDash TinyMCE: Received theme change message');
                                            // Theme changes handled by main application sync
                                        }
                                    };

                                    // Simple event listeners - NO COMPLEX OBSERVERS
                                    window.addEventListener('storage', handleTinyMCEStorage);
                                    window.addEventListener('message', handleTinyMCEMessage);

                                    // Simple parent observer - NO COMPLEX LOGIC
                                    let tinyMCEParentObserver = null;
                                    // Store timeout ID for TinyMCE/Gutenberg detection cleanup
                                    let tinyMCEDetectionTimeout = null;
                                    if (window.parent) {
                                        tinyMCEParentObserver = new MutationObserver((mutations) => {
                                            const hasThemeChange = mutations.some(mutation =>
                                                mutation.type === 'attributes' &&
                                                (mutation.attributeName === 'class' || mutation.attributeName === 'data-theme')
                                            );
                                            if (hasThemeChange) {
                                                if (debug) console.log('FleekDash TinyMCE: Parent theme changed');
                                                // Theme changes handled by main application sync
                                            }
                                        });

                                        tinyMCEParentObserver.observe(window.parent.document.documentElement, {
                                            attributes: true,
                                            attributeFilter: ['class', 'data-theme']
                                        });

                                        if (debug) console.log('FleekDash TinyMCE: Parent theme observer active');
                                    }

                                    // REMOVED: applyReceivedTheme() function
                                    // Replaced by cascaded inheritance system that automatically syncs with parent theme changes

                                    // REMOVED: Duplicate message listener
                                    // Theme changes are now handled automatically by cascaded inheritance system
                                    // The parent observer and storage listener already handle all theme synchronization

                                    // *** HOTKEY SYSTEM FOR NESTED IFRAMES (TinyMCE/Gutenberg) ***
                                    function shouldAllowHotkeyInInput(event) {
                                        const activeElement = document.activeElement;
                                        const isEditableElement = activeElement && (
                                            activeElement.tagName === 'INPUT' ||
                                            activeElement.tagName === 'TEXTAREA' ||
                                            activeElement.contentEditable === 'true' ||
                                            activeElement.isContentEditable
                                        );

                                        if (!isEditableElement) return true;

                                        // Allow composite hotkeys and ESC even in editable elements
                                        const isCompositeHotkey = (
                                            ((event.ctrlKey || event.metaKey) && event.shiftKey) ||  // Ctrl/Cmd+Shift+*
                                            ((event.ctrlKey || event.metaKey) && event.altKey) ||    // Ctrl/Cmd+Alt+*
                                            (event.altKey && event.shiftKey) ||   // Alt+Shift+*
                                            (event.altKey) ||                     // Alt+* (like Alt+T, Alt+M, Alt+W)
                                            (event.key === 'Escape') ||           // ESC key
                                            ((event.ctrlKey || event.metaKey) && (event.code === 'Space' || event.key === ' ')) // Ctrl/Cmd+Space
                                        );

                                        return isCompositeHotkey;
                                    }

                                    function shouldForwardCmdkToFleekDash() {
                                        try {
                                            const topDoc = window.top.document;
                                            if (topDoc.body && topDoc.body.classList.contains('inside-iframe')) {
                                                return true;
                                            }
                                            if (topDoc.documentElement && topDoc.documentElement.classList.contains('fleekdash-inside-iframe')) {
                                                return true;
                                            }
                                        } catch (e) {
                                            // Cross-origin — fall through
                                        }
                                        return window.self !== window.top;
                                    }

                                    function forwardHotkeyToParent(e) {
                                        const now = Date.now();
                                        if (now - (window.lastHotkeyForward || 0) < 100) return; // Debounce
                                        window.lastHotkeyForward = now;

                                        const {ctrlKey, metaKey, altKey, shiftKey, code, key} = e;

                                        // Define hotkeys that should be forwarded - ENHANCED detection with cross-platform support
                                        const hotkeys = {
                                            'ctrl+space': ctrlKey && (code === 'Space' || key === ' '),
                                            'cmd+space': metaKey && (code === 'Space' || key === ' '),
                                            'ctrl+k': shouldForwardCmdkToFleekDash() && ctrlKey && (code === 'KeyK' || key.toLowerCase() === 'k'),
                                            'cmd+k': shouldForwardCmdkToFleekDash() && metaKey && (code === 'KeyK' || key.toLowerCase() === 'k'),
                                            'alt+t': altKey && (code === 'KeyT' || key.toLowerCase() === 't'),
                                            'alt+m': altKey && (code === 'KeyM' || key.toLowerCase() === 'm'),
                                            'alt+w': altKey && (code === 'KeyW' || key.toLowerCase() === 'w'),
                                            'ctrl+shift+f': ctrlKey && shiftKey && !altKey && (code === 'KeyF' || key.toLowerCase() === 'f'),
                                            'cmd+shift+f': metaKey && shiftKey && !altKey && (code === 'KeyF' || key.toLowerCase() === 'f'),
                                            'ctrl+alt+t': ctrlKey && altKey && !shiftKey && (code === 'KeyT' || key.toLowerCase() === 't'),
                                            'cmd+alt+t': metaKey && altKey && !shiftKey && (code === 'KeyT' || key.toLowerCase() === 't'),
                                            'esc': code === 'Escape' || key === 'Escape'
                                        };

                                        let handled = false;
                                        for (const [combo, matches] of Object.entries(hotkeys)) {
                                            if (matches) {
                                                // Check if we should allow this hotkey
                                                if (!shouldAllowHotkeyInInput(e)) {
                                                    return;
                                                }

                                                e.preventDefault();
                                                e.stopPropagation();
                                                e.stopImmediatePropagation();

                                                // Forward to parent windows (nested forwarding)
                                                try {
                                                    // Send to immediate parent
                                                    if (window.parent && window.parent !== window) {
                                                        window.parent.postMessage({
                                                            type: 'hotkey',
                                                            combination: combo,
                                                            source: 'tinymce-nested-iframe',
                                                            originalEvent: {
                                                                ctrlKey, altKey, shiftKey, code, key,
                                                                type: e.type,
                                                                isTrusted: e.isTrusted
                                                            }
                                                        }, '*');
                                                    }

                                                    // Also try to send to top-level window
                                                    if (window.top && window.top !== window && window.top !== window.parent) {
                                                        window.top.postMessage({
                                                            type: 'hotkey',
                                                            combination: combo,
                                                            source: 'tinymce-nested-iframe-to-top',
                                                            originalEvent: {
                                                                ctrlKey, altKey, shiftKey, code, key,
                                                                type: e.type,
                                                                isTrusted: e.isTrusted
                                                            }
                                                        }, '*');
                                                    }
                                                } catch (err) {
                                                    if (debug) console.warn('FleekDash TinyMCE: Error forwarding hotkey:', err);
                                                }

                                                handled = true;
                                                break;
                                            }
                                        }

                                        return handled;
                                    }

                                    // Add hotkey event listeners with maximum priority
                                    const hotkeyOptions = { capture: true, passive: false };

                                    document.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                    window.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);

                                    // Also add to body when available
                                    if (document.body) {
                                        document.body.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                    } else {
                                        document.addEventListener('DOMContentLoaded', () => {
                                            if (document.body) {
                                                document.body.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                            }
                                        });
                                    }

                                    if (debug) console.log('FleekDash TinyMCE: Hotkey forwarding system initialized in nested iframe');

                                    // CRITICAL: Force immediate detection of TinyMCE content area
                                    // Store timeout ID for cleanup
                                    tinyMCEDetectionTimeout = setTimeout(() => {
                                        tinyMCEDetectionTimeout = null; // Clear ref when timeout executes
                                        const isTinyMCE = document.body && (
                                            document.body.classList.contains('mce-content-body') ||
                                            document.body.id === 'tinymce' ||
                                            window.location.href.includes('content_ifr') ||
                                            document.querySelector('.mce-content-body') ||
                                            window.name && window.name.includes('content_ifr')
                                        );

                                        const isGutenberg = document.body && (
                                            document.body.classList.contains('block-editor-iframe__body') ||
                                            document.querySelector('.block-editor-iframe__body') ||
                                            document.querySelector('.wp-block') ||
                                            window.name && window.name.includes('editor-canvas') ||
                                            window.name && window.name.includes('editor') ||
                                            document.title && document.title.includes('Editor canvas') ||
                                            document.title && document.title.includes('Editor') ||
                                            window.location.href.includes('blob:') ||
                                            document.querySelector('[data-rich-text-placeholder]') ||
                                            document.querySelector('.block-editor-block-list__layout')
                                        );

                                        if (isTinyMCE) {
                                            // Add extra listeners specifically for TinyMCE content
                                            if (document.body) {
                                                // Must pass same capture/options as addEventListener or removal is a no-op
                                                document.body.removeEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                                document.body.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                            }
                                        } else if (isGutenberg) {
                                            // Add extra listeners specifically for Gutenberg content
                                            if (document.body) {
                                                document.body.removeEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                                document.body.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                            }

                                            // Also add listeners to specific Gutenberg elements
                                            const gutenbergElements = document.querySelectorAll('.block-editor-rich-text__editable, .rich-text, .wp-block');
                                            gutenbergElements.forEach(element => {
                                                element.addEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                            });
                                        }
                                    }, 100);

                                    // Ask parent for current theme once (initial sync)
                                    if (window.parent && window.parent !== window) {
                                         if (debug) console.log('FleekDash Iframe: Requesting initial theme from parent');
                                        // No extra delay: theme was already applied during injection
                                        try {
                                             window.parent.postMessage({ type: 'fleekdash-request-theme', iframeId: window.name || window.location.href }, '*');
                                        } catch(e) {
                                            if (debug) console.warn('FleekDash Iframe: Failed to request theme from parent:', e);
                                        }
                                    }

                                    // Cleanup TinyMCE listeners and observers on page unload
                                    window.addEventListener('beforeunload', function() {
                                        // Clear TinyMCE detection timeout
                                        if (tinyMCEDetectionTimeout) {
                                            clearTimeout(tinyMCEDetectionTimeout);
                                            tinyMCEDetectionTimeout = null;
                                        }

                                        // Disconnect parent observer
                                        if (tinyMCEParentObserver) {
                                            tinyMCEParentObserver.disconnect();
                                            tinyMCEParentObserver = null;
                                        }

                                        // Remove event listeners
                                        window.removeEventListener('storage', handleTinyMCEStorage);
                                        window.removeEventListener('message', handleTinyMCEMessage);

                                        // Remove keydown listeners (body must match addEventListener options: capture)
                                        document.removeEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                        window.removeEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                        if (document.body) {
                                            document.body.removeEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                        }

                                        // Remove listeners from Gutenberg elements if they exist
                                        const gutenbergElements = document.querySelectorAll('.block-editor-rich-text__editable, .rich-text, .wp-block');
                                        gutenbergElements.forEach(element => {
                                            element.removeEventListener('keydown', forwardHotkeyToParent, hotkeyOptions);
                                        });
                                    });
                                })();
                            `;
                            const script = document.createElement( 'script' );
                            script.textContent = syncScript;
                            script.id = scriptId;
                            iframe.contentDocument.head.appendChild( script );
                            log( 'Injected sync script into iframe', iframe.id || iframe.src );
                        } else {
                            log( 'Sync script already exists in iframe', iframe.id || iframe.src );
                        }

                        return true;
                    } catch ( error ) {
                        console.error( 'FleekDash: Error injecting resources:', error );
                        return false;
                    }
                }

                function findEditorIframes() {
                    const selectors = [
                        '#content_ifr',
                        '.block-editor-iframe__container iframe',
                        '.block-editor-iframe__container .components-resizable-box iframe',
                        '.edit-post-visual-editor iframe',
                        'iframe[name^="editor-"]', // Gutenberg editor-canvas
                        'iframe[src*="post.php"]',
                        'iframe[src*="post-new.php"]',
                        // Gutenberg Block Editor specific
                        '.block-editor-iframe__html',
                        'iframe[title*="editor"]',
                        'iframe[title*="Editor"]',
                        'iframe[title*="canvas"]',
                        '.wp-block-editor iframe',
                        // More specific Gutenberg selectors
                        '.editor-canvas iframe',
                        '.block-editor-editor-canvas iframe',
                        '.block-editor-iframe__body',
                        // Generic iframe detection for Gutenberg
                        'iframe[data-rich-text-placeholder]'
                    ];
                    const iframes = new Set(); // Dedupe by reference

                    // First try specific selectors
                    selectors.forEach(selector => {
                        const found = document.querySelectorAll(selector);
                        if (found.length) {
                            found.forEach(iframe => iframes.add(iframe));
                        }
                    });

                    // If no iframes found, try broader search
                    if (iframes.size === 0) {
                        const allIframes = document.querySelectorAll('iframe');
                        allIframes.forEach(iframe => {
                            try {
                                // Check if iframe has editor-like content or attributes
                                if (iframe.contentDocument &&
                                     (iframe.contentDocument.querySelector('[data-rich-text-placeholder]') ||
                                      iframe.contentDocument.querySelector('.block-editor-block-list__layout') ||
                                      iframe.contentDocument.querySelector('.mce-content-body') ||
                                      iframe.contentDocument.body?.getAttribute('contenteditable') === 'true' ||
                                      iframe.src?.includes('editor') ||
                                      iframe.name?.includes('editor') ||
                                      iframe.title?.includes('editor') ||
                                      iframe.title?.includes('canvas'))) {
                                    iframes.add(iframe);
                                }
                            } catch (e) {
                                // Cross-origin, skip
                            }
                        });
                    }

                    return Array.from(iframes);
                }

                // DEFINITIVE SOLUTION: Inject resources and apply themes
                function syncAllIframesDefinitive() {
                    const editorIframes = findEditorIframes();

                    editorIframes.forEach(iframe => {
                        try {
                            // Inject resources (including hotkey script)
                            injectResources(iframe);
                        } catch (e) {
                            // Error processing iframe, skip
                        }
                    });
                }

                // --- Observadores e Event Listeners ---

                // Declare observer variables in IIFE scope for proper cleanup access
                let domObserver = null;
                let themeObserver = null;
                let blockEditorObserver = null;
                // Store timeout IDs for cleanup to prevent accumulation
                let domObserverSyncTimeout = null;
                let themeObserverSyncTimeout = null;

                // 1. Watch DOM for new editor iframes (debounced)
                domObserver = new MutationObserver( ( mutations ) => {
                    let foundNewIframe = false;

                    for ( const mutation of mutations ) {
                        if ( mutation.addedNodes.length > 0 ) {
                            for ( const node of mutation.addedNodes ) {
                                // Match iframe nodes or elements that wrap an iframe
                                if ( node.nodeType === 1 ) { // Element node
                                    const isIframe = node.tagName === 'IFRAME';
                                    const containsIframe = node.querySelector && node.querySelector( 'iframe' );

                                    if ( isIframe || containsIframe ) {
                                        foundNewIframe = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if ( foundNewIframe ) break;
                    }

                    if ( foundNewIframe ) {
                            // Clear any pending timeout before creating new one
                            // This prevents timeout accumulation when observer fires rapidly
                            if (domObserverSyncTimeout) {
                                clearTimeout(domObserverSyncTimeout);
                                domObserverSyncTimeout = null;
                            }
                            // Apply definitive sync to new iframes
                            domObserverSyncTimeout = setTimeout(() => {
                                domObserverSyncTimeout = null;
                                syncAllIframesDefinitive();
                            }, 100);
                    }
                } );
                domObserver.observe( document.body, { childList: true, subtree: true } );

                // 2. Watch main HTML document theme changes (simplified, aggressive sync)
                let lastThemeState = {
                    theme: document.documentElement.getAttribute( 'data-theme' ),
                    isDark: document.documentElement.classList.contains( 'dark' )
                };

                // REMOVED: debouncedSync function
                // Theme changes are now handled automatically by cascaded inheritance system

                themeObserver = new MutationObserver( ( mutations ) => {
                    // Detect any theme-related attribute change
                    const hasThemeChange = mutations.some( mutation => {
                        if ( mutation.attributeName === 'data-theme' ) return true;
                        if ( mutation.attributeName === 'class' ) {
                            const currentIsDark = mutation.target.classList.contains( 'dark' );
                            return currentIsDark !== lastThemeState.isDark;
                        }
                        return false;
                    } );

                    if ( hasThemeChange ) {
                        // Clear any pending timeout before creating new one
                        // This prevents timeout accumulation when theme changes rapidly
                        if (themeObserverSyncTimeout) {
                            clearTimeout(themeObserverSyncTimeout);
                            themeObserverSyncTimeout = null;
                        }
                        // Apply definitive sync to all iframes
                        themeObserverSyncTimeout = setTimeout(() => {
                            themeObserverSyncTimeout = null;
                            syncAllIframesDefinitive();
                        }, 100);
                    }
                } );
                themeObserver.observe( document.documentElement, {
                    attributes: true,
                    attributeFilter: [ 'class', 'data-theme' ]
                } );

                // 3. Handle theme requests from child iframes
                // Extract handler function for cleanup
                const handleThemeRequestMessage = function ( event ) {
                    if ( event.data && event.data.type === 'fleekdash-request-theme' && event.source ) {
                        try {
                            // Find the iframe that sent the message
                            const targetIframe = Array.from( document.querySelectorAll( 'iframe' ) ).find( iframe => iframe.contentWindow === event.source );

                            if ( targetIframe ) {
                                // Resolve theme using shared sync module
                                let isDarkMode;

                                if (typeof window.fleekDashThemeSync !== 'undefined') {
                                    // Use shared module - respects data-mode
                                    const container = targetIframe.closest( '.fleek-window' );
                                    const mode = container ? container.getAttribute('data-mode') : 'trusted';
                                    const parentIsDark = document.documentElement.classList.contains('dark');

                                    isDarkMode = window.fleekDashThemeSync.getThemeBasedOnMode(
                                        mode || 'trusted',
                                        parentIsDark
                                    );
                                } else {
                                    // Fallback if module not loaded
                                    const container = targetIframe.closest( '.fleek-window' );
                                    let isLightMode;

                                    if ( container ) {
                                        if ( container.classList.contains( 'light' ) ) {
                                            isLightMode = true;
                                        } else if ( container.classList.contains( 'dark' ) ) {
                                            isLightMode = false;
                                        } else {
                                            isLightMode = !document.documentElement.classList.contains( 'dark' );
                                        }
                                    } else {
                                        isLightMode = !document.documentElement.classList.contains( 'dark' );
                                    }

                                    isDarkMode = !isLightMode;
                                }

                                const themeName = document.documentElement.getAttribute( 'data-theme' ) || 'starter';

                                // Post back the resolved theme to the iframe
                                event.source.postMessage( {
                                    type: 'fleekdash-apply-theme',
                                    isDarkMode: isDarkMode,
                                    theme: themeName
                                }, '*' );
                            }
                        } catch ( e ) {
                            console.error( 'FleekDash: Error responding to theme request', e );
                        }
                    }
                };
                window.addEventListener( 'message', handleThemeRequestMessage );

                // --- Additional TinyMCE detection (placeholder; sync via cascade) ---

                // REMOVED: forceSyncAllPossibleIframes() function
                // Replaced by cascaded inheritance system that handles all iframes automatically

                // --- Initialization ---

                log( 'Initializing FleekDash iframe synchronization...' );


                // DEFINITIVE INITIALIZATION - Ultra-simple, impossible to fail
                log( 'Starting DEFINITIVE iframe synchronization...' );

                // Function to apply theme to block editor elements
                function applyThemeToBlockEditorElements() {
                    const parentHtml = document.documentElement;
                    const isDark = parentHtml.classList.contains('dark');
                    const theme = parentHtml.getAttribute('data-theme') || 'starter';

                    // Apply to all possible block editor elements
                    const blockEditorElements = [
                        ...document.querySelectorAll('.block-editor-iframe__html'),
                        ...document.querySelectorAll('html'),
                        document.documentElement
                    ];

                    blockEditorElements.forEach(element => {
                        if (element) {
                            element.classList.remove('dark', 'light');
                            element.classList.add(isDark ? 'dark' : 'light');
                            element.setAttribute('data-theme', theme);
                        }
                    });

                }

                // Immediate sync
                syncAllIframesDefinitive();
                applyThemeToBlockEditorElements();

                // Use debounced initialization instead of multiple separate timeouts
                // This prevents timer accumulation and reduces overhead
                let initializationTimeout = null;
                // Track wrapper timeouts to prevent memory leaks
                let initializationWrapperTimeout1 = null;
                let initializationWrapperTimeout2 = null;
                function scheduleInitialization() {
                    if (initializationTimeout) {
                        clearTimeout(initializationTimeout);
                    }
                    initializationTimeout = setTimeout(() => {
                        initializationTimeout = null;
                        syncAllIframesDefinitive();
                        applyThemeToBlockEditorElements();
                    }, 100);
                }

                // Schedule initialization multiple times - only last one executes
                // This achieves the "reliability" goal without creating multiple timers
                // Store timeout IDs for cleanup
                scheduleInitialization();
                initializationWrapperTimeout1 = setTimeout(() => {
                    initializationWrapperTimeout1 = null; // Clear ref when timeout executes
                    scheduleInitialization();
                }, 0);
                initializationWrapperTimeout2 = setTimeout(() => {
                    initializationWrapperTimeout2 = null; // Clear ref when timeout executes
                    scheduleInitialization();
                }, 200);

                // Continuous monitoring for block editor elements
                blockEditorObserver = new MutationObserver(() => {
                    applyThemeToBlockEditorElements();
                });

                blockEditorObserver.observe(document.body, {
                    childList: true,
                    subtree: true
                });

                // Cleanup on page unload
                // Use direct references to observer variables (declared in IIFE scope)
                // This ensures cleanup handler has proper access to observers
                window.addEventListener('beforeunload', function() {
                    // Clear all pending timeouts
                    if (domObserverSyncTimeout) {
                        clearTimeout(domObserverSyncTimeout);
                        domObserverSyncTimeout = null;
                    }
                    if (themeObserverSyncTimeout) {
                        clearTimeout(themeObserverSyncTimeout);
                        themeObserverSyncTimeout = null;
                    }
                    if (initializationTimeout) {
                        clearTimeout(initializationTimeout);
                        initializationTimeout = null;
                    }
                    // Clear wrapper timeouts to prevent memory leaks
                    if (initializationWrapperTimeout1) {
                        clearTimeout(initializationWrapperTimeout1);
                        initializationWrapperTimeout1 = null;
                    }
                    if (initializationWrapperTimeout2) {
                        clearTimeout(initializationWrapperTimeout2);
                        initializationWrapperTimeout2 = null;
                    }

                    // Disconnect all observers using direct variable references
                    if (domObserver) {
                        domObserver.disconnect();
                        domObserver = null;
                    }
                    if (themeObserver) {
                        themeObserver.disconnect();
                        themeObserver = null;
                    }
                    if (blockEditorObserver) {
                        blockEditorObserver.disconnect();
                        blockEditorObserver = null;
                    }

                    // Remove message listener
                    if (handleThemeRequestMessage) {
                        window.removeEventListener('message', handleThemeRequestMessage);
                    }
                });

            } )();
        </script>
        <?php
    }
}
