/* global jQuery, anchorkit_ajax */
jQuery(function ($) {
    'use strict';

    const anchorkitDebugLog = (...args) => {
        if (!window || !window.anchorkitDebug) {
            return;
        }

        if (window.console && typeof window.console.log === 'function') {
            window.console.log(...args);
        }
    };

    const ajaxConfig = window.anchorkit_ajax || {};
    const sidebar = $('#anchorkit-preview-sidebar');
    const previewContainer = $('#anchorkit-sidebar-toc-preview');

    if (!sidebar.length || !previewContainer.length || !ajaxConfig.ajax_url) {
        return;
    }

    const systemPreferenceQuery = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;

    function toBoolean(value) {
        return value === true || value === 1 || value === '1' || value === 'true';
    }

    const preview = {
        html: '',
        tokens: { light: {}, dark: {} },
        serverState: {},
        serverTheme: 'system',
        userMode: null,
        activeMode: 'light',
        pendingXhr: null,
        debounceTimer: null,
        cachedSettings: {},
        customCss: ''
    };

    /**
     * Boost CSS specificity by prepending high-specificity wrapper to all selectors
     * Mirrors the PHP function anchorkit_boost_css_specificity()
     * @param {string} css Raw CSS content
     * @returns {string} CSS with boosted specificity
     */
    function boostCssSpecificity(css) {
        if (!css || typeof css !== 'string') {
            return '';
        }

        // Preserve comments
        const comments = [];
        css = css.replace(/\/\*[\s\S]*?\*\//g, function (match) {
            const key = '___COMMENT_' + comments.length + '___';
            comments.push({ key: key, value: match });
            return key;
        });

        // Handle @media, @supports rules - preserve them and process content
        const atRules = [];
        css = css.replace(/@(media|supports|container)[^{]+\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/g, function (match, type, content) {
            const key = '___ATRULE_' + atRules.length + '___';
            // Recursively boost content inside
            const boostedContent = boostCssSpecificity(content);
            const condition = match.substring(0, match.indexOf('{')).trim();
            atRules.push({ key: key, value: condition + '{' + boostedContent + '}' });
            return key;
        });

        // Preserve @keyframes
        const keyframes = [];
        css = css.replace(/@keyframes[^{]+\{[^}]*(?:\{[^}]*\}[^}]*)*\}/g, function (match) {
            const key = '___KEYFRAME_' + keyframes.length + '___';
            keyframes.push({ key: key, value: match });
            return key;
        });

        // Boost regular selectors
        css = css.replace(/([^{}]+)\{([^{}]*)\}/g, function (match, selector, declarations) {
            selector = selector.trim();

            // Skip placeholders or empty selectors
            if (!selector || selector.indexOf('___') !== -1) {
                return match;
            }

            // Split comma-separated selectors
            const selectors = selector.split(',').map(function (s) { return s.trim(); });
            const boostedSelectors = selectors.map(function (sel) {
                // Don't boost if already starts with html, body, or :root
                if (/^\s*(html|body|:root)\b/i.test(sel)) {
                    return sel;
                }
                // Add ID-level specificity using :not(#id)
                return 'html:not(#anchorkit_boost) body:not(#anchorkit_boost) ' + sel;
            });

            return boostedSelectors.join(', ') + '{' + declarations + '}';
        });

        // Restore preserved parts
        keyframes.forEach(function (item) {
            css = css.replace(item.key, item.value);
        });
        atRules.forEach(function (item) {
            css = css.replace(item.key, item.value);
        });
        comments.forEach(function (item) {
            css = css.replace(item.key, item.value);
        });

        return css;
    }

    function updatePreviewCustomCss(css) {
        const styleEl = document.getElementById('anchorkit-toc-preview-inline-inline-css');
        if (!styleEl) {
            return;
        }

        if (css && typeof css === 'string') {
            styleEl.textContent = boostCssSpecificity(css);
        } else {
            styleEl.textContent = '';
        }
    }

    function normalizePreviewHtml(html) {
        if (!html) {
            return '';
        }

        return html
            .replace(/anchorkit-toc-preset-[^\s"']+/g, '')
            .replace(/\banchorkit-toc-custom-styling\b/g, '')
            .replace(/id="anchorkit-toc-list-[^"]+"/gi, 'id="anchorkit-toc-list-placeholder"')
            .replace(/aria-controls="anchorkit-toc-list-[^"]+"/gi, 'aria-controls="anchorkit-toc-list-placeholder"')
            .replace(/\s{2,}/g, ' ')
            .trim();
    }

    // Seed cached settings with server-provided defaults so preview stays consistent across tabs
    if (typeof ajaxConfig.current_preset !== 'undefined' && ajaxConfig.current_preset) {
        preview.cachedSettings.anchorkit_toc_style_preset = ajaxConfig.current_preset;
    }
    if (typeof ajaxConfig.custom_styling !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_custom_styling = toBoolean(ajaxConfig.custom_styling) ? 1 : 0;
    }
    if (typeof ajaxConfig.alignment !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_alignment = ajaxConfig.alignment;
    }
    if (typeof ajaxConfig.show_label !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_show_label = toBoolean(ajaxConfig.show_label) ? 1 : 0;
    }
    if (typeof ajaxConfig.title_text !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_title_text = ajaxConfig.title_text;
    }
    if (typeof ajaxConfig.collapsible !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_collapsible = toBoolean(ajaxConfig.collapsible) ? 1 : 0;
    }
    if (typeof ajaxConfig.hierarchical_view !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_hierarchical_view = toBoolean(ajaxConfig.hierarchical_view) ? 1 : 0;
    }
    if (typeof ajaxConfig.bullet_style !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_bullet_style = ajaxConfig.bullet_style;
    }
    if (typeof ajaxConfig.bullet_character !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_bullet_character = ajaxConfig.bullet_character;
    }

    // Seed View More settings
    if (typeof ajaxConfig.view_more_enabled !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_view_more_enabled = toBoolean(ajaxConfig.view_more_enabled) ? 1 : 0;
    }
    if (typeof ajaxConfig.initial_count !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_initial_count = ajaxConfig.initial_count;
    }
    if (typeof ajaxConfig.view_more_text !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_view_more_text = ajaxConfig.view_more_text;
    }
    if (typeof ajaxConfig.view_less_text !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_view_less_text = ajaxConfig.view_less_text;
    }

    // Seed Back to Top settings
    if (typeof ajaxConfig.back_to_top_link !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_back_to_top_link = toBoolean(ajaxConfig.back_to_top_link) ? 1 : 0;
    }
    if (typeof ajaxConfig.back_to_top_text !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_back_to_top_text = ajaxConfig.back_to_top_text;
    }
    if (typeof ajaxConfig.back_to_top_font_size !== 'undefined') {
        preview.cachedSettings.anchorkit_toc_back_to_top_font_size = ajaxConfig.back_to_top_font_size;
    }

    function getLivePreviewToggle() {
        return $('input[name="anchorkit_toc_live_preview_enabled"]');
    }

    function isPreviewEnabled() {
        const $toggle = getLivePreviewToggle();
        if ($toggle.length) {
            return $toggle.is(':checked');
        }
        return true;
    }

    function collectSettings() {
        const payload = Object.assign({}, preview.cachedSettings || {});
        const checkboxArrayTracker = Object.create(null);

        // Check if we're in Elementor editor and collect heading_levels from Elementor widget settings
        let elementorHeadingLevels = null;
        if (typeof elementor !== 'undefined' && elementor.panels && elementor.panels.currentView) {
            try {
                const currentView = elementor.panels.currentView;
                const currentElement = currentView.getOption && currentView.getOption('editedElementView');
                if (currentElement && currentElement.model) {
                    const widgetType = currentElement.model.get('widgetType');
                    if (widgetType === 'anchorkit-toc') {
                        const settings = currentElement.model.get('settings');
                        if (settings && settings.heading_levels) {
                            elementorHeadingLevels = settings.heading_levels;
                            // Map Elementor heading_levels to anchorkit_toc_include_headings
                            if (Array.isArray(elementorHeadingLevels) && elementorHeadingLevels.length > 0) {
                                payload['anchorkit_toc_include_headings'] = elementorHeadingLevels;
                            }
                        }
                    }
                }
            } catch (e) {
                // Elementor API not available or error accessing it - continue with form fields
                console.debug('[AnchorKit] Could not access Elementor widget settings:', e);
            }
        }

        // Also check for hidden fields that might be set by Elementor integration
        const $elementorHeadingLevelsField = $('input[name="anchorkit_toc_include_headings_from_elementor"], input[type="hidden"][data-elementor-heading-levels]');
        if ($elementorHeadingLevelsField.length && !elementorHeadingLevels) {
            const elementorLevelsValue = $elementorHeadingLevelsField.val();
            if (elementorLevelsValue) {
                try {
                    const parsed = JSON.parse(elementorLevelsValue);
                    if (Array.isArray(parsed) && parsed.length > 0) {
                        elementorHeadingLevels = parsed;
                        payload['anchorkit_toc_include_headings'] = parsed;
                    }
                } catch (e) {
                    // Not JSON, try as comma-separated string
                    const levels = elementorLevelsValue.split(',').map(function (s) { return s.trim(); }).filter(function (s) { return s; });
                    if (levels.length > 0) {
                        elementorHeadingLevels = levels;
                        payload['anchorkit_toc_include_headings'] = levels;
                    }
                }
            }
        }

        $('[name^="anchorkit_toc_"]').each(function () {
            const $field = $(this);
            const name = $field.attr('name');
            if (!name) {
                return;
            }

            // Skip anchorkit_toc_include_headings if we got it from Elementor
            if (name === 'anchorkit_toc_include_headings' && elementorHeadingLevels) {
                return;
            }

            if ($field.is(':disabled')) {
                if (Object.prototype.hasOwnProperty.call(payload, name)) {
                    delete payload[name];
                }
                return;
            }

            if ($field.is(':checkbox')) {
                if (name.endsWith('[]')) {
                    const baseName = name.slice(0, -2);

                    if (!checkboxArrayTracker[baseName]) {
                        payload[baseName] = [];
                        checkboxArrayTracker[baseName] = true;
                    }

                    if ($field.is(':checked')) {
                        payload[baseName].push($field.val());
                    }

                    if (Object.prototype.hasOwnProperty.call(payload, name)) {
                        delete payload[name];
                    }
                } else {
                    payload[name] = $field.is(':checked') ? 1 : 0;
                }
                return;
            }

            if ($field.is(':radio')) {
                if ($field.is(':checked')) {
                    payload[name] = $field.val();
                }
                return;
            }

            payload[name] = $field.val();
        });

        // Supplement payload with anything from cachedSettings that wasn't in the DOM
        // This is critical for multi-tab setups where inputs only exist on their respective tabs.
        const knownTocSettings = [
            'anchorkit_toc_style_preset',
            'anchorkit_toc_custom_styling',
            'anchorkit_toc_show_label',
            'anchorkit_toc_title_text',
            'anchorkit_toc_collapsible',
            'anchorkit_toc_initial_state',
            'anchorkit_toc_hierarchical_view',
            'anchorkit_toc_show_numerals',
            'anchorkit_toc_bullet_style',
            'anchorkit_toc_bullet_character',
            'anchorkit_toc_numbering_style',
            'anchorkit_toc_numbering_format',
            'anchorkit_toc_numbering_separator',
            'anchorkit_toc_alignment',
            'anchorkit_toc_float',
            'anchorkit_toc_width',
            'anchorkit_toc_view_more_enabled',
            'anchorkit_toc_initial_count',
            'anchorkit_toc_view_more_text',
            'anchorkit_toc_view_less_text',
            'anchorkit_toc_back_to_top_link',
            'anchorkit_toc_back_to_top_text',
            'anchorkit_toc_back_to_top_font_size',
            'anchorkit_toc_hide_on_mobile',
            'anchorkit_toc_mobile_breakpoint'
        ];

        knownTocSettings.forEach(function (key) {
            if (!Object.prototype.hasOwnProperty.call(payload, key) && Object.prototype.hasOwnProperty.call(preview.cachedSettings, key)) {
                payload[key] = preview.cachedSettings[key];
            }
        });
        const customStylingEnabled = !!payload['anchorkit_toc_custom_styling'];
        if (!customStylingEnabled) {
            const customColorKeys = [
                'anchorkit_toc_bg_color_light',
                'anchorkit_toc_text_color_light',
                'anchorkit_toc_link_color_light',
                'anchorkit_toc_link_hover_color_light',
                'anchorkit_toc_border_color_light',
                'anchorkit_toc_bg_color_dark',
                'anchorkit_toc_text_color_dark',
                'anchorkit_toc_link_color_dark',
                'anchorkit_toc_link_hover_color_dark',
                'anchorkit_toc_border_color_dark',
                'anchorkit_toc_bullet_color_light',
                'anchorkit_toc_bullet_color_dark',
                // Legacy / base custom styling controls
                'anchorkit_toc_bg_color',
                'anchorkit_toc_text_color',
                'anchorkit_toc_link_color',
                'anchorkit_toc_link_hover_color',
                'anchorkit_toc_border_color',
                'anchorkit_toc_font_family',
                'anchorkit_toc_font_size',
                'anchorkit_toc_padding',
                'anchorkit_toc_border_width',
                'anchorkit_toc_border_radius'
                // Note: anchorkit_toc_line_height, anchorkit_toc_letter_spacing, anchorkit_toc_text_transform, and anchorkit_toc_link_underline
                // are typography settings and should always be included, regardless of custom_styling toggle
            ];
            customColorKeys.forEach(function (key) {
                if (Object.prototype.hasOwnProperty.call(payload, key)) {
                    delete payload[key];
                }
            });
        }

        preview.cachedSettings = payload;
        return payload;
    }

    function applyTokens($toc, tokens) {
        const el = $toc.get(0);
        if (!el) return;

        const previousKeys = $toc.data('anchorkitTokenKeys');
        if (Array.isArray(previousKeys)) {
            previousKeys.forEach(function (key) {
                el.style.removeProperty(key);
            });
        }

        const keys = Object.keys(tokens || {});
        keys.forEach(function (key) {
            const value = tokens[key];
            // Handle both strings and numbers (line-height can be a unitless number)
            if (typeof value === 'string' || typeof value === 'number') {
                el.style.setProperty(key, String(value));
            }
        });

        $toc.data('anchorkitTokenKeys', keys);

        // Fix: Apply preset-specific border-top colors that match frontend dark mode styles
        // This ensures the preview matches the live TOC appearance
        if ($toc.hasClass('anchorkit-toc-preset-classic') && !$toc.hasClass('anchorkit-toc-custom-styling')) {
            if (preview.activeMode === 'dark') {
                // Classic preset dark mode: blue top border
                el.style.setProperty('border-top-color', '#5ba3d0', 'important');
            } else {
                // Classic preset light mode: blue top border (already in CSS, but ensure it's set)
                el.style.setProperty('border-top-color', '#0073aa', 'important');
            }
        }
    }

    function applyLayout($toc, state) {
        const el = $toc.get(0);
        if (!el) return;

        el.style.removeProperty('width');
        el.style.removeProperty('float');
        el.style.removeProperty('margin');
        el.style.removeProperty('position');
        el.style.removeProperty('top');
        el.style.removeProperty('z-index');

        const width = parseInt(state.width, 10);
        if (width > 0 && width <= 100) {
            el.style.setProperty('width', width + '%');
        }

        if (state.float && state.float !== 'none') {
            el.style.setProperty('float', state.float);
            el.style.setProperty('margin', state.float === 'left' ? '0 20px 20px 0' : '0 0 20px 20px');
        } else {
            const alignment = (state.alignment || 'center').toLowerCase();
            if (alignment === 'left') {
                el.style.setProperty('margin', '20px auto 20px 0');
            } else if (alignment === 'right') {
                el.style.setProperty('margin', '20px 0 20px auto');
            } else {
                el.style.setProperty('margin', '20px auto');
            }
        }

        // Remove sticky classes and styles - sticky settings should not be applied to preview
        $toc.removeClass(function (_, className) {
            return (className.match(/(^|\s)anchorkit-toc-sticky\S*/g) || []).join(' ');
        });
        // Ensure sticky styles are removed (already removed above, but keeping for clarity)
    }

    function attachBehaviors($root, state) {
        const $toc = $root.find('.anchorkit-toc-container').first();
        if (!$toc.length) return;

        const $list = $toc.find('.anchorkit-toc-list').first();
        const $toggleBtn = $toc.find('.anchorkit-toc-toggle-button');
        let scheduleCollapsibleSync = null;

        if (state.collapsible && $list.length && $toggleBtn.length) {
            const updateListHeight = function (expanded) {
                if (!expanded) {
                    $list.css('height', '0px');
                    $list.attr('aria-hidden', 'true');
                } else {
                    const scrollHeight = $list.get(0).scrollHeight;
                    $list.css('height', scrollHeight + 'px');
                    $list.attr('aria-hidden', 'false');
                }
            };

            scheduleCollapsibleSync = function () {
                requestAnimationFrame(function () {
                    requestAnimationFrame(function () {
                        const listEl = $list.get(0);
                        if (!listEl) return;
                        const expandedState = !$toc.hasClass('anchorkit-toc-collapsed');

                        listEl.style.transition = 'none';
                        listEl.style.height = 'auto';
                        const targetHeight = listEl.scrollHeight;
                        listEl.offsetHeight;
                        listEl.style.transition = '';
                        updateListHeight(expandedState);
                        if (expandedState) {
                            listEl.style.height = targetHeight + 'px';
                        }
                    });
                });
            };

            // Initialize proper height for collapsed/expanded state
            const listEl = $list.get(0);
            if (listEl) {
                const expanded = !$toc.hasClass('anchorkit-toc-collapsed');

                // Temporarily disable transition to measure actual height
                const prevTransition = listEl.style.transition;
                listEl.style.transition = 'none';
                listEl.style.height = 'auto';
                const properHeight = listEl.scrollHeight;

                // Apply initial state without animation
                if (expanded) {
                    listEl.style.height = properHeight + 'px';
                    $list.attr('aria-hidden', 'false');
                } else {
                    listEl.style.height = '0px';
                    $list.attr('aria-hidden', 'true');
                }

                // Force reflow then restore transition
                listEl.offsetHeight;
                listEl.style.transition = prevTransition;
            }

            const toggleHandler = function (e) {
                e.preventDefault();
                const currentlyCollapsed = $toc.hasClass('anchorkit-toc-collapsed');
                const willExpand = currentlyCollapsed;
                $toc.toggleClass('anchorkit-toc-collapsed', !willExpand);
                $toc.toggleClass('anchorkit-toc-expanded', willExpand);
                $toggleBtn.attr('aria-expanded', willExpand ? 'true' : 'false');
                updateListHeight(willExpand);
            };

            $toggleBtn.off('click').on('click', function (e) {
                if ($(this).is(':disabled')) return;
                toggleHandler(e);
            });

            $toc.find('.anchorkit-toc-title').off('click').on('click', function (e) {
                if ($(e.target).closest('.anchorkit-toc-toggle-button').length) return;
                toggleHandler(e);
            });
        } else if ($list.length) {
            $list.css('height', '');
            $list.removeAttr('aria-hidden');
        }

        if (!scheduleCollapsibleSync) {
            scheduleCollapsibleSync = function () { };
        }

        const $viewMoreBtn = $toc.find('.anchorkit-toc-view-more-btn');
        if ($viewMoreBtn.length && state.view_more && state.view_more.enabled) {
            const initialCount = parseInt(state.view_more.initial_count, 10) || 3;
            const moreText = state.view_more.more_text || 'View More';
            const lessText = state.view_more.less_text || 'View Less';

            const applyCollapsedState = function (isExpanded) {
                const $items = $toc.find('.anchorkit-toc-item');
                if (isExpanded) {
                    $items.removeClass('anchorkit-toc-hidden-item');
                } else {
                    $items.each(function (index) {
                        if (index >= initialCount) {
                            $(this).addClass('anchorkit-toc-hidden-item');
                        } else {
                            $(this).removeClass('anchorkit-toc-hidden-item');
                        }
                    });
                }
            };

            applyCollapsedState(false);
            const finalizeCollapsedState = function () {
                $viewMoreBtn.attr('aria-expanded', 'false');
                $viewMoreBtn.find('.anchorkit-toc-view-more-text').text(moreText);
                scheduleCollapsibleSync();
            };

            if ($list.length) {
                const listEl = $list.get(0);
                if (listEl) {
                    const prevTransition = listEl.style.transition;
                    listEl.style.transition = 'none';
                    requestAnimationFrame(function () {
                        finalizeCollapsedState();
                        requestAnimationFrame(function () {
                            listEl.style.transition = prevTransition;
                        });
                    });
                } else {
                    finalizeCollapsedState();
                }
            } else {
                finalizeCollapsedState();
            }

            $viewMoreBtn.off('click').on('click', function (e) {
                e.preventDefault();
                const isExpanded = $viewMoreBtn.attr('aria-expanded') === 'true';
                const nextExpanded = !isExpanded;
                $viewMoreBtn.attr('aria-expanded', nextExpanded ? 'true' : 'false');
                $viewMoreBtn.find('.anchorkit-toc-view-more-text').text(nextExpanded ? lessText : moreText);
                applyCollapsedState(nextExpanded);
                scheduleCollapsibleSync();
            });

            $viewMoreBtn.off('keydown').on('keydown', function (e) {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    $viewMoreBtn.trigger('click');
                }
            });
        } else if ($viewMoreBtn.length) {
            const $items = $toc.find('.anchorkit-toc-item');
            $items.removeClass('anchorkit-toc-hidden-item');
            $viewMoreBtn.attr('aria-expanded', 'true');
            const lessText = (state.view_more && state.view_more.less_text) || 'View Less';
            $viewMoreBtn.find('.anchorkit-toc-view-more-text').text(lessText);
            if (scheduleCollapsibleSync) {
                scheduleCollapsibleSync();
            }
        }
    }

    function syncExistingBehaviors($toc, state) {
        if (!$toc || !$toc.length) return;

        const $list = $toc.find('.anchorkit-toc-list').first();
        const listEl = $list.get(0);
        let scheduleCollapsibleSync = null;

        if (state.collapsible && listEl) {
            const isCollapsed = $toc.hasClass('anchorkit-toc-collapsed');
            const previousTransition = listEl.style.transition;
            listEl.style.transition = 'none';
            if (isCollapsed) {
                listEl.style.height = '0px';
                listEl.setAttribute('aria-hidden', 'true');
            } else {
                listEl.style.height = 'auto';
                const targetHeight = listEl.scrollHeight;
                listEl.style.height = targetHeight + 'px';
                listEl.setAttribute('aria-hidden', 'false');
            }
            listEl.offsetHeight;
            listEl.style.transition = previousTransition;
        }

        const $viewMoreBtn = $toc.find('.anchorkit-toc-view-more-btn');
        if ($viewMoreBtn.length && state.view_more && state.view_more.enabled) {
            const initialCount = parseInt(state.view_more.initial_count, 10) || 3;
            const isExpanded = $viewMoreBtn.attr('aria-expanded') === 'true';
            const $items = $toc.find('.anchorkit-toc-item');
            $items.each(function (index) {
                if (!isExpanded && index >= initialCount) {
                    $(this).addClass('anchorkit-toc-hidden-item');
                } else {
                    $(this).removeClass('anchorkit-toc-hidden-item');
                }
            });

            if (!scheduleCollapsibleSync) {
                scheduleCollapsibleSync = function (callback) {
                    if (typeof callback === 'function') {
                        callback();
                    }
                };
            }

            scheduleCollapsibleSync(function () {
                if (!listEl) return;
                const prevTransition = listEl.style.transition;
                listEl.style.transition = 'none';
                const collapsed = $toc.hasClass('anchorkit-toc-collapsed');
                if (collapsed) {
                    listEl.style.height = '0px';
                } else {
                    listEl.style.height = 'auto';
                    const target = listEl.scrollHeight;
                    listEl.style.height = target + 'px';
                }
                listEl.offsetHeight;
                listEl.style.transition = prevTransition;
            });
        }
    }

    function applyModeIndicator(mode) {
        const $indicator = $('.anchorkit-preview-mode-indicator');
        const $toggle = $('.anchorkit-theme-test-toggle');
        if ($indicator.length) {
            $indicator.find('.mode-text').text(mode === 'dark' ? 'Dark' : 'Light');
        }
        if ($toggle.length) {
            $toggle.attr('data-test-mode', mode);
            $toggle.attr('title', mode === 'light' ? 'Test Dark Mode' : 'Test Light Mode');
            $toggle.find('.sun-icon').toggle(mode === 'light');
            $toggle.find('.moon-icon').toggle(mode === 'dark');
        }
    }

    function updateThemeUi() {
        const serverTheme = preview.serverTheme;
        const activeMode = preview.activeMode;
        const $indicator = $('.anchorkit-preview-mode-indicator');
        const $toggle = $('.anchorkit-theme-test-toggle');

        if (serverTheme === 'system') {
            $indicator.removeClass('is-hidden').show();
            $toggle.removeClass('is-hidden').show();
            applyModeIndicator(activeMode);
        } else {
            $indicator.addClass('is-hidden').hide();
            $toggle.addClass('is-hidden').hide();
            preview.userMode = null;
        }
    }

    function syncColorPickers(mode) {
        $('.theme-aware-color').each(function () {
            const $picker = $(this);
            const colorType = $picker.data('color-type');
            if (!colorType) return;

            const $hiddenField = $('#anchorkit_toc_' + colorType + '_' + mode);
            if ($hiddenField.length) {
                const value = $hiddenField.val();
                if (value) {
                    $picker.val(value);
                    const $display = $picker.closest('.input-container, .anchorkit-input-container').find('.color-value');
                    if ($display.length) {
                        $display.text(value.toUpperCase());
                    }
                }
            }
        });
    }

    function syncShadowFields(mode) {
        $('.theme-aware-shadow').each(function () {
            const $shadowField = $(this);
            const shadowType = $shadowField.data('shadow-type');
            if (!shadowType) return;

            const $hiddenField = $('#anchorkit_toc_' + shadowType + '_' + mode);
            if ($hiddenField.length) {
                const value = $hiddenField.val();
                if (value) {
                    $shadowField.val(value);
                }
            }
        });
    }

    function resolveActiveMode() {
        if (preview.serverTheme === 'light' || preview.serverTheme === 'dark') {
            return preview.serverTheme;
        }

        if (preview.userMode) {
            return preview.userMode;
        }

        if (systemPreferenceQuery && typeof systemPreferenceQuery.matches === 'boolean') {
            return systemPreferenceQuery.matches ? 'dark' : 'light';
        }

        return 'light';
    }

    function renderPreview() {
        preview.activeMode = resolveActiveMode();
        sidebar.attr('data-preview-theme', preview.activeMode);
        sidebar.data('stored-theme', preview.serverTheme);

        // Sync simulated theme classes for presets (used to mirror frontend light/dark styling)
        sidebar.removeClass('anchorkit-test-dark-mode anchorkit-force-light');
        if (preview.serverTheme === 'system') {
            if (preview.activeMode === 'dark') {
                sidebar.addClass('anchorkit-test-dark-mode');
            } else {
                sidebar.addClass('anchorkit-force-light');
            }
        }

        if (!preview.html) {
            preview.renderedHtml = '';
            previewContainer.html('<div class="anchorkit-preview-empty">Enable the live preview to see your Table of Contents styling updates.</div>');
            updateThemeUi();
            return;
        }

        let htmlChanged = true;
        if (typeof preview.renderedHtml !== 'undefined' && preview.renderedHtml === preview.html) {
            htmlChanged = false;
        }
        if (htmlChanged && typeof preview.renderedHtml !== 'undefined') {
            const previousNormalized = normalizePreviewHtml(preview.renderedHtml);
            const nextNormalized = normalizePreviewHtml(preview.html);
            if (previousNormalized === nextNormalized) {
                htmlChanged = false;
            }
        }

        let $toc;
        if (htmlChanged) {
            updatePreviewCustomCss(preview.customCss);
            previewContainer.html(preview.html);
            preview.renderedHtml = preview.html;
            $toc = previewContainer.find('.anchorkit-toc-container').first();
        } else {
            $toc = previewContainer.find('.anchorkit-toc-container').first();
            updatePreviewCustomCss(preview.customCss);
        }
        if ($toc.length) {
            const presetClassPattern = /\banchorkit-toc-preset-[^\s]+\b/g;
            const themeClassPattern = /\banchorkit-toc-theme-[^\s]+\b/g;
            const currentClasses = $toc.attr('class') || '';
            const presetClasses = currentClasses.match(presetClassPattern) || [];
            const themeClasses = currentClasses.match(themeClassPattern) || [];
            const classesToRemove = [];

            // Update theme mode if returned
            if (preview.serverState && preview.serverState.theme) {
                sidebar.find('#toc-preview-container').attr('data-theme', preview.serverState.theme);
            }

            if (presetClasses.length) {
                classesToRemove.push(presetClasses.join(' '));
            }

            // Remove existing theme classes
            if (themeClasses.length) {
                classesToRemove.push(themeClasses.join(' '));
            }

            // Update mobile hidden indicator
            if (preview.serverState && preview.serverState.mobile) {
                const mobile = preview.serverState.mobile;
                const $tocPreview = sidebar.find('#toc-preview');
                const sidebarWidth = sidebar.width();

                // Remove existing indicator
                $tocPreview.find('.anchorkit-mobile-hidden-indicator').remove();
                $tocPreview.removeClass('is-hidden-on-mobile');

                if (mobile.hide_on_mobile && sidebarWidth <= mobile.breakpoint) {
                    $tocPreview.addClass('is-hidden-on-mobile');
                    $tocPreview.append('<div class="anchorkit-mobile-hidden-indicator"><div class="indicator-content"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="currentColor" d="M17,19H7V5H17M17,1H7C5.89,1 5,1.89 5,3V21A2,2 0 0,0 7,23H17A2,2 0 0,0 19,21V3C19,1.89 18.1,1 17,1Z" /></svg><span>Hidden on Mobile (' + mobile.breakpoint + 'px)</span></div></div>');
                }
            }
            if ($toc.hasClass('anchorkit-toc-custom-styling')) {
                classesToRemove.push('anchorkit-toc-custom-styling');
            }
            if (classesToRemove.length) {
                $toc.removeClass(classesToRemove.join(' '));
            }

            if (preview.serverState && preview.serverState.custom_styling) {
                $toc.addClass('anchorkit-toc-custom-styling');
            } else if (preview.serverState && preview.serverState.style_preset) {
                $toc.addClass('anchorkit-toc-preset-' + preview.serverState.style_preset);
            }

            // Add theme class to TOC container for explicit light/dark themes
            // For system theme, let the sidebar wrapper classes handle styling
            if (preview.serverState && preview.serverState.theme) {
                const theme = preview.serverState.theme;
                if (theme === 'light' || theme === 'dark') {
                    $toc.addClass('anchorkit-toc-theme-' + theme);
                }
            }
        }
        applyTokens($toc, preview.tokens[preview.activeMode] || {});
        applyLayout($toc, preview.serverState || {});
        if ($toc.length) {
            if (htmlChanged) {
                attachBehaviors(previewContainer, preview.serverState || {});
            } else {
                syncExistingBehaviors($toc, preview.serverState || {});
            }
        }
        updateThemeUi();
        syncColorPickers(preview.activeMode);
        syncShadowFields(preview.activeMode);

        // Ensure preview shadow reflects current component values even after re-render
        try {
            // Check if box shadow is enabled before applying
            const $shadowToggle = $('input[name="anchorkit_toc_box_shadow_enabled"]');
            const boxShadowEnabled = $shadowToggle.length ? $shadowToggle.is(':checked') : false;

            const combineFn = window.anchorkitCombineShadowComponents;
            const applyFn = window.anchorkitApplyPreviewBoxShadow;

            if (typeof combineFn === 'function' && typeof applyFn === 'function') {
                if (boxShadowEnabled) {
                    // Apply the shadow when toggle is enabled
                    const currentShadow = combineFn(preview.activeMode);
                    applyFn(currentShadow, preview.activeMode);
                } else {
                    // Explicitly remove shadow when toggle is disabled
                    applyFn('none', preview.activeMode);
                }
            } else {
                console.debug('[AnchorKit Shadow] Preview shadow helpers not initialized yet', {
                    combineFn: typeof combineFn,
                    applyFn: typeof applyFn
                });
            }
        } catch (err) {
            console.error('[AnchorKit Shadow] Unable to apply preview shadow after render:', err);
        }

        preview.renderedHtml = preview.html;
    }

    function handlePreviewResponse(response) {
        anchorkitDebugLog('[AnchorKit] Preview response:', response);
        if (!response || !response.success || !response.data) {
            previewContainer.html('<div class="anchorkit-preview-empty">Unable to load the preview. Please try again.</div>');
            return;
        }

        preview.html = response.data.html || '';
        preview.tokens = response.data.tokens || { light: {}, dark: {} };
        preview.serverState = response.data.state || {};
        preview.serverTheme = preview.serverState.theme || 'system';
        if (preview.serverState.style_preset) {
            preview.cachedSettings.anchorkit_toc_style_preset = preview.serverState.style_preset;
        }
        if (typeof preview.serverState.custom_styling !== 'undefined') {
            preview.cachedSettings.anchorkit_toc_custom_styling = preview.serverState.custom_styling ? 1 : 0;
        }

        if (preview.serverTheme !== 'system') {
            preview.userMode = null;
        }

        // Get custom CSS directly from the textarea field (not from AJAX response)
        const $customCssField = $('textarea[name="anchorkit_toc_custom_css"]');
        preview.customCss = $customCssField.length ? $customCssField.val() : '';

        renderPreview();
    }

    function refreshPreview() {
        if (!isPreviewEnabled()) {
            previewContainer.html('<div class="anchorkit-preview-empty">Enable the live preview to see your Table of Contents styling updates.</div>');
            return;
        }

        const settings = collectSettings();
        anchorkitDebugLog('[AnchorKit] Preview settings payload:', settings);

        if (preview.pendingXhr && preview.pendingXhr.readyState !== 4) {
            preview.pendingXhr.abort();
        }

        sidebar.addClass('is-loading');
        preview.pendingXhr = $.ajax({
            url: ajaxConfig.ajax_url,
            method: 'POST',
            dataType: 'json',
            data: {
                action: 'anchorkit_generate_toc_preview',
                nonce: ajaxConfig.nonce,
                settings: settings
            }
        });

        preview.pendingXhr.done(handlePreviewResponse).fail(function (xhr, status) {
            if (status !== 'abort') {
                console.error('AnchorKit: AJAX error generating preview', status, xhr && xhr.responseText);
                previewContainer.html('<div class="anchorkit-preview-empty">Unable to load the preview. Please try again.</div>');
            }
        }).always(function () {
            sidebar.removeClass('is-loading');
        });
    }

    function scheduleRefresh(delay) {
        if (preview.debounceTimer) {
            clearTimeout(preview.debounceTimer);
        }
        preview.debounceTimer = setTimeout(refreshPreview, delay || 150);
    }

    function handleThemeToggleClick(e) {
        e.preventDefault();
        if (preview.serverTheme !== 'system') {
            return;
        }
        preview.userMode = preview.activeMode === 'light' ? 'dark' : 'light';
        applyModeIndicator(preview.userMode);
        renderPreview();
        // Ensure color pickers and shadow fields sync after mode switch
        const newMode = preview.userMode || resolveActiveMode();
        syncColorPickers(newMode);
        syncShadowFields(newMode);
    }

    function handleThemePreferenceChange() {
        if (preview.serverTheme !== 'system' || preview.userMode) {
            return;
        }
        renderPreview();
    }

    function applyStoredCollapseState() {
        const stored = localStorage.getItem('anchorkit_sidebar_collapsed');
        if (stored === 'true') {
            sidebar.addClass('collapsed');
            $('.anchorkit-preview-toggle').attr('aria-expanded', 'false');
        } else {
            sidebar.removeClass('collapsed');
            $('.anchorkit-preview-toggle').attr('aria-expanded', 'true');
        }
    }

    function bindEvents() {
        $('.anchorkit-preview-toggle').on('click', function () {
            const isExpanded = $(this).attr('aria-expanded') === 'true';
            $(this).attr('aria-expanded', !isExpanded);
            sidebar.toggleClass('collapsed');
            localStorage.setItem('anchorkit_sidebar_collapsed', isExpanded ? 'true' : 'false');
        });

        $(document).on('change', 'select[name^="anchorkit_toc_"], input[type="checkbox"][name^="anchorkit_toc_"], input[type="radio"][name^="anchorkit_toc_"]', function () {
            const name = $(this).attr('name');
            // Skip preview refresh for View More toggle - it's handled client-side only
            if (name === 'anchorkit_toc_view_more_enabled') {
                return;
            }
            scheduleRefresh(0);
        });

        $(document).on('input', 'input[type="color"][name^="anchorkit_toc_"], input[type="range"][name^="anchorkit_toc_"], input[type="number"][name^="anchorkit_toc_"]', function () {
            scheduleRefresh(150);
        });

        $(document).on('blur', 'input[type="number"][name^="anchorkit_toc_"]', function () {
            scheduleRefresh(0);
        });

        $(document).on('input', 'input[type="text"][name^="anchorkit_toc_"], textarea[name^="anchorkit_toc_"]', function () {
            scheduleRefresh(300);
        });

        $('.anchorkit-theme-test-toggle').on('click', handleThemeToggleClick);

        $('select[name="anchorkit_toc_theme"]').on('change', function () {
            const $select = $(this);
            const newThemeValue = $select.val() || 'system';

            preview.serverTheme = newThemeValue;
            preview.userMode = null;
            renderPreview();
            // Ensure color pickers and shadow fields sync after theme change
            const newMode = resolveActiveMode();
            syncColorPickers(newMode);
            syncShadowFields(newMode);

            // Save the theme value to database via AJAX
            // This ensures the theme value persists across page reloads
            if (typeof anchorkit_ajax !== 'undefined' && anchorkit_ajax.ajax_url) {
                const saveData = {
                    action: 'anchorkit_update_setting',
                    option_name: 'anchorkit_toc_theme',
                    option_value: newThemeValue,
                    group: 'toc',
                    nonce: anchorkit_ajax.nonce
                };

                $.post(anchorkit_ajax.ajax_url, saveData, function (response) {
                    if (response.success) {
                        // Update localized cache
                        if (typeof anchorkit_ajax !== 'undefined') {
                            anchorkit_ajax.toc_theme = newThemeValue;
                        }

                        // Show success notification if available
                        if (typeof window.showAnchorKitNotification === 'function') {
                            window.showAnchorKitNotification('Table of Contents theme updated', 'success');
                        }
                    }
                });
            }
        });

        getLivePreviewToggle().on('change', function () {
            if ($(this).is(':checked')) {
                refreshPreview();
            } else {
                previewContainer.html('<div class="anchorkit-preview-empty">Enable the live preview to see your Table of Contents styling updates.</div>');
            }
        });

        // Handle View More toggle without server refresh (client-side only)
        $('input[name="anchorkit_toc_view_more_enabled"]').on('change', function () {
            const isEnabled = $(this).is(':checked');
            const $toc = previewContainer.find('.anchorkit-toc-container').first();
            const $viewMoreBtn = $toc.find('.anchorkit-toc-view-more-btn');
            const $items = $toc.find('.anchorkit-toc-item');

            if (!$viewMoreBtn.length || !$items.length) return;

            if (isEnabled) {
                // Enable View More - hide items beyond initial count
                const initialCount = parseInt($('input[name="anchorkit_toc_initial_count"]').val(), 10) || 3;
                const moreText = $('input[name="anchorkit_toc_view_more_text"]').val() || 'View More';

                $items.each(function (index) {
                    if (index >= initialCount) {
                        $(this).addClass('anchorkit-toc-hidden-item');
                    } else {
                        $(this).removeClass('anchorkit-toc-hidden-item');
                    }
                });

                $viewMoreBtn.attr('aria-expanded', 'false');
                $viewMoreBtn.find('.anchorkit-toc-view-more-text').text(moreText);
                $viewMoreBtn.show();
            } else {
                // Disable View More - show all items
                $items.removeClass('anchorkit-toc-hidden-item');
                $viewMoreBtn.hide();
            }

            // Sync collapsible height if needed
            const $list = $toc.find('.anchorkit-toc-list').first();
            const listEl = $list.get(0);
            if ($toc.hasClass('anchorkit-toc-collapsible') && listEl) {
                const prevTransition = listEl.style.transition;
                listEl.style.transition = 'none';
                listEl.style.height = 'auto';
                const targetHeight = listEl.scrollHeight;
                listEl.offsetHeight;
                listEl.style.transition = prevTransition;

                if (!$toc.hasClass('anchorkit-toc-collapsed')) {
                    listEl.style.height = targetHeight + 'px';
                }
            }
        });

        $(document).on('input change', '.theme-aware-color', function () {
            const $picker = $(this);
            const colorType = $picker.data('color-type');
            if (!colorType) return;

            const value = $picker.val();
            const currentMode = preview.serverTheme === 'system' ? preview.activeMode : preview.serverTheme;
            const hiddenId = '#anchorkit_toc_' + colorType + '_' + currentMode;
            const hiddenFieldName = 'anchorkit_toc_' + colorType + '_' + currentMode;

            $(hiddenId).val(value);
            $('input[name="' + hiddenFieldName + '"]').val(value);

            const baseField = $('input[name="anchorkit_toc_' + colorType + '"]');
            if (baseField.length) {
                baseField.val(value);
            }

            const $display = $picker.closest('.input-container, .anchorkit-input-container').find('.color-value');
            if ($display.length) {
                $display.text(value.toUpperCase());
            }

            // Save the hidden field value to the database via AJAX
            if (typeof window.anchorkitDebouncedColorUpdate === 'function') {
                window.anchorkitDebouncedColorUpdate(hiddenFieldName, value, '');
            }

            scheduleRefresh(150);
        });

        $(document).on('input change', '.theme-aware-shadow', function () {
            const $shadowField = $(this);
            const shadowType = $shadowField.data('shadow-type');
            if (!shadowType) return;

            const value = $shadowField.val();
            const currentMode = preview.serverTheme === 'system' ? preview.activeMode : preview.serverTheme;
            const hiddenId = '#anchorkit_toc_' + shadowType + '_' + currentMode;
            const hiddenFieldName = 'anchorkit_toc_' + shadowType + '_' + currentMode;
            const $hiddenField = $(hiddenId);

            // Update hidden field value
            $hiddenField.val(value);
            $('input[name="' + hiddenFieldName + '"]').val(value);

            // Sync legacy custom field to match light mode value (for backward compatibility)
            const legacyField = $('#anchorkit_toc_box_shadow_custom_hidden');
            if (legacyField.length && currentMode === 'light') {
                legacyField.val(value);
                // Trigger change on legacy field so it also gets saved
                legacyField.trigger('change');
            }

            // Trigger change event on hidden field so generic handler can save it
            $hiddenField.trigger('change');

            // Also save directly via AJAX as backup (using debounced update)
            if (typeof window.anchorkitDebouncedColorUpdate === 'function') {
                window.anchorkitDebouncedColorUpdate(hiddenFieldName, value, '');
            }

            scheduleRefresh(150);
        });

        if (systemPreferenceQuery) {
            if (typeof systemPreferenceQuery.addEventListener === 'function') {
                systemPreferenceQuery.addEventListener('change', handleThemePreferenceChange);
            } else if (typeof systemPreferenceQuery.addListener === 'function') {
                systemPreferenceQuery.addListener(handleThemePreferenceChange);
            }
        }

        // Listen for Elementor widget settings changes
        if (typeof elementor !== 'undefined' && elementor.on) {
            // Listen for Elementor panel changes (when widget settings are modified)
            elementor.on('panel:change', function (panel, view, settings) {
                // Check if this is our TOC widget
                if (view && view.model) {
                    const widgetType = view.model.get('widgetType');
                    if (widgetType === 'anchorkit-toc') {
                        // Check if heading_levels changed
                        if (settings && 'heading_levels' in settings) {
                            scheduleRefresh(0);
                        }
                    }
                }
            });

            // Also listen for general element changes
            elementor.hooks.addAction('panel/open_editor/widget/anchorkit-toc', function (panel, model, view) {
                // When TOC widget panel opens, set up change listener
                if (view && view.model) {
                    view.model.on('change:settings', function (model, options) {
                        const changed = options.changed;
                        if (changed && 'heading_levels' in changed) {
                            scheduleRefresh(0);
                        }
                    });
                }
            });
        }

        // Fallback: Listen for changes to hidden fields that might be updated by Elementor integration
        $(document).on('change', 'input[data-elementor-heading-levels], input[name="anchorkit_toc_include_headings_from_elementor"]', function () {
            scheduleRefresh(0);
        });
    }

    function initialize() {
        applyStoredCollapseState();
        bindEvents();
        refreshPreview();
    }

    /**
     * Initialize Shadow Component Editor
     */
    function initShadowComponentEditor() {
        const $components = $('.theme-aware-shadow-component');

        if ($components.length === 0) {
            anchorkitDebugLog('[AnchorKit Shadow] No shadow component elements found');
            return;
        }

        anchorkitDebugLog('[AnchorKit Shadow] Found', $components.length, 'shadow component fields');
        anchorkitDebugLog('[AnchorKit Shadow] Global functions available:', {
            anchorkitUpdateSetting: typeof window.anchorkitUpdateSetting,
            anchorkitDebouncedColorUpdate: typeof window.anchorkitDebouncedColorUpdate
        });

        function applyPreviewBoxShadow(shadowString, mode) {
            const $previewToc = $('#anchorkit-sidebar-toc-preview .anchorkit-toc-container').first();
            if ($previewToc.length) {
                $previewToc.css('box-shadow', shadowString);
                if (mode === 'dark') {
                    $previewToc.addClass('anchorkit-preview-force-dark-shadow');
                } else {
                    $previewToc.removeClass('anchorkit-preview-force-dark-shadow');
                }
            }
        }
        window.anchorkitApplyPreviewBoxShadow = applyPreviewBoxShadow;

        // Function to combine shadow components into CSS string
        function combineShadowComponents(mode) {
            const hOffset = parseInt($(`#anchorkit_toc_shadow_h_offset_${mode}`).val(), 10) || 0;
            const vOffset = parseInt($(`#anchorkit_toc_shadow_v_offset_${mode}`).val(), 10) || 0;
            const blur = parseInt($(`#anchorkit_toc_shadow_blur_${mode}`).val(), 10) || 0;
            const spread = parseInt($(`#anchorkit_toc_shadow_spread_${mode}`).val(), 10) || 0;
            const color = $(`#anchorkit_toc_shadow_color_${mode}`).val() || '#000000';
            const opacity = parseFloat($(`#anchorkit_toc_shadow_opacity_${mode}`).val()) || 0;

            // Convert hex to RGB
            const r = parseInt(color.substr(1, 2), 16);
            const g = parseInt(color.substr(3, 2), 16);
            const b = parseInt(color.substr(5, 2), 16);

            return `${hOffset}px ${vOffset}px ${blur}px ${spread}px rgba(${r}, ${g}, ${b}, ${opacity})`;
        }
        window.anchorkitCombineShadowComponents = combineShadowComponents;

        // Function to update hidden fields and preview
        function updateShadowFromComponents(mode) {
            const shadowString = combineShadowComponents(mode);

            anchorkitDebugLog(`[AnchorKit Shadow] Combined ${mode} shadow:`, shadowString);

            // Update hidden box-shadow field
            $(`#anchorkit_toc_box_shadow_${mode}`).val(shadowString);

            // Apply shadow directly to preview TOC container for instant feedback
            // but only if the toggle is enabled
            const $shadowToggle = $('input[name="anchorkit_toc_box_shadow_enabled"]');
            const boxShadowEnabled = $shadowToggle.length ? $shadowToggle.is(':checked') : false;

            if (boxShadowEnabled) {
                applyPreviewBoxShadow(shadowString, mode);
            } else {
                applyPreviewBoxShadow('none', mode);
            }


            // Save the combined shadow string to database (immediate)
            if (typeof window.anchorkitUpdateSetting === 'function') {
                window.anchorkitUpdateSetting(`anchorkit_toc_box_shadow_${mode}`, shadowString, '');
                anchorkitDebugLog(`[AnchorKit Shadow] Immediate save for anchorkit_toc_box_shadow_${mode}`);
            } else {
                console.error('[AnchorKit Shadow] Save function not available');
            }

            // Update legacy field for light mode
            if (mode === 'light') {
                $('#anchorkit_toc_box_shadow_custom_hidden').val(shadowString);
                // Also save legacy field
                if (typeof window.anchorkitUpdateSetting === 'function') {
                    window.anchorkitUpdateSetting('anchorkit_toc_box_shadow_custom', shadowString, '');
                    anchorkitDebugLog('[AnchorKit Shadow] Immediate save for legacy anchorkit_toc_box_shadow_custom');
                }
            }
        }

        // Function to sync visible inputs with hidden mode-specific inputs
        function syncVisibleToHidden() {
            const currentMode = preview.activeMode || 'light';

            anchorkitDebugLog('[AnchorKit Shadow] Syncing visible to hidden for mode:', currentMode);

            $('.theme-aware-shadow-component').each(function () {
                const $input = $(this);
                const component = $input.data('component');
                const value = $input.val();
                const fieldName = `anchorkit_toc_shadow_${component}_${currentMode}`;

                anchorkitDebugLog(`[AnchorKit Shadow] Updating ${fieldName} to:`, value);

                // Update hidden input
                const $hiddenField = $(`#${fieldName}`);
                $hiddenField.val(value);

                // Update color display if this is color field
                if (component === 'color') {
                    $input.closest('.anchorkit-color-picker').find('.color-value').text(value.toUpperCase());
                }

                // Save to database via AJAX (immediate save to avoid debounce conflicts)
                if (typeof window.anchorkitUpdateSetting === 'function') {
                    window.anchorkitUpdateSetting(fieldName, value, '');
                    anchorkitDebugLog(`[AnchorKit Shadow] Immediate save for ${fieldName}`);
                } else {
                    console.error('[AnchorKit Shadow] Save function not available!');
                }
            });

            // Combine and update shadow string
            updateShadowFromComponents(currentMode);

            // Update preview
            scheduleRefresh(150);
        }

        // Function to sync hidden inputs to visible inputs (when switching modes)
        function syncHiddenToVisible(mode) {
            $('#shadow_h_offset_visible').val($(`#anchorkit_toc_shadow_h_offset_${mode}`).val());
            $('#shadow_v_offset_visible').val($(`#anchorkit_toc_shadow_v_offset_${mode}`).val());
            $('#shadow_blur_visible').val($(`#anchorkit_toc_shadow_blur_${mode}`).val());
            $('#shadow_spread_visible').val($(`#anchorkit_toc_shadow_spread_${mode}`).val());
            $('#shadow_color_visible').val($(`#anchorkit_toc_shadow_color_${mode}`).val());
            $('#shadow_opacity_visible').val($(`#anchorkit_toc_shadow_opacity_${mode}`).val());

            // Update color display
            const colorValue = $(`#anchorkit_toc_shadow_color_${mode}`).val();
            $('#shadow_color_visible').closest('.anchorkit-color-picker').find('.color-value').text(colorValue.toUpperCase());

            updateShadowFromComponents(mode);
            scheduleRefresh(150);
        }

        // Listen for component changes
        $components.on('input change', function () {
            anchorkitDebugLog('[AnchorKit Shadow] Component changed:', $(this).attr('id'), '=', $(this).val());
            syncVisibleToHidden();
        });

        // Listen for theme toggle changes
        $('.anchorkit-theme-test-toggle').on('click', function () {
            setTimeout(function () {
                const newMode = preview.activeMode || 'light';
                syncHiddenToVisible(newMode);
            }, 50);
        });

        // Listen for theme dropdown changes
        $('select[name="anchorkit_toc_theme"]').on('change', function () {
            setTimeout(function () {
                const newMode = preview.activeMode || 'light';
                syncHiddenToVisible(newMode);
            }, 50);
        });

        // Listen for box shadow enabled toggle changes
        $('input[name="anchorkit_toc_box_shadow_enabled"]').on('change', function () {
            const isEnabled = $(this).is(':checked');
            const currentMode = preview.activeMode || resolveActiveMode() || 'light';

            if (isEnabled) {
                // Apply the current shadow when enabled
                const shadowString = combineShadowComponents(currentMode);
                applyPreviewBoxShadow(shadowString, currentMode);
            } else {
                // Remove shadow when disabled
                applyPreviewBoxShadow('none', currentMode);
            }

            anchorkitDebugLog('[AnchorKit Shadow] Toggle changed, enabled:', isEnabled);
        });


        // Initialize with current mode
        const initialMode = preview.activeMode || resolveActiveMode() || 'light';
        anchorkitDebugLog('[AnchorKit Shadow] Initializing with mode:', initialMode);

        // Log current hidden field values
        anchorkitDebugLog('[AnchorKit Shadow] Hidden field values on load:', {
            h_offset: $(`#anchorkit_toc_shadow_h_offset_${initialMode}`).val(),
            v_offset: $(`#anchorkit_toc_shadow_v_offset_${initialMode}`).val(),
            blur: $(`#anchorkit_toc_shadow_blur_${initialMode}`).val(),
            spread: $(`#anchorkit_toc_shadow_spread_${initialMode}`).val(),
            color: $(`#anchorkit_toc_shadow_color_${initialMode}`).val(),
            opacity: $(`#anchorkit_toc_shadow_opacity_${initialMode}`).val()
        });

        syncHiddenToVisible(initialMode);
        updateShadowFromComponents(initialMode);
        scheduleRefresh(0);

        anchorkitDebugLog('[AnchorKit Shadow] Component editor initialized with mode:', initialMode);
    }

    initialize();

    // Initialize shadow editor if elements are present (with slight delay to ensure global functions are available)
    setTimeout(function () {
        if ($('.theme-aware-shadow-component').length > 0) {
            anchorkitDebugLog('[AnchorKit] Shadow component elements found, initializing...');

            // Verify preview is ready
            anchorkitDebugLog('[AnchorKit Shadow] Preview activeMode:', preview.activeMode);
            anchorkitDebugLog('[AnchorKit Shadow] Preview serverTheme:', preview.serverTheme);

            initShadowComponentEditor();
        }
    }, 250);

    window.updateTocPreview = refreshPreview;
});
