        (function() {
            /* ── Show / hide API key ── */
            var toggleBtn   = document.getElementById('aivt-toggle-key-vis');
            var keyInput    = document.getElementById('aivt_api_key_input');
            var toggleLabel = document.getElementById('aivt-toggle-label');
            var keyMasked = true;
            if (keyInput) {
                // Start masked — apply CSS mask trick (doesn't trigger autofill like type=password)
                keyInput.style.webkitTextSecurity = 'disc';
                keyInput.style.textSecurity = 'disc';
            }
            if (toggleBtn && keyInput) {
                toggleBtn.addEventListener('click', function() {
                    keyMasked = !keyMasked;
                    keyInput.style.webkitTextSecurity = keyMasked ? 'disc' : 'none';
                    keyInput.style.textSecurity = keyMasked ? 'disc' : 'none';
                    toggleLabel.textContent = keyMasked ? 'Show' : 'Hide';
                });
            }

            /* ── Live color + button text preview ── */
            var colorInput   = document.getElementById('aivt_theme_color');
            var hexDisplay   = document.getElementById('aivt-color-hex-display');
            var previewBtn   = document.getElementById('aivt-preview-btn');
            var btnTextInput = document.getElementById('aivt_button_text');
            var previewText  = document.getElementById('aivt-preview-text');

            if (colorInput) {
                colorInput.addEventListener('input', function() {
                    var val = this.value;
                    if (hexDisplay)  hexDisplay.textContent  = val;
                    if (previewBtn)  previewBtn.style.background = val;
                });
            }
            if (btnTextInput && previewText) {
                btnTextInput.addEventListener('input', function() {
                    previewText.textContent = this.value || 'Try On';
                });
            }

            /* ── Range sliders ── */
            var radiusInput  = document.getElementById('aivt_btn_border_radius');
            var radiusVal    = document.getElementById('aivt-radius-val');
            var fontSzInput  = document.getElementById('aivt_btn_font_size');
            var fontSzVal    = document.getElementById('aivt-fontsize-val');

            function updatePreviewStyles() {
                if (!previewBtn) return;
                if (radiusInput)  previewBtn.style.borderRadius = radiusInput.value + 'px';
                if (fontSzInput)  previewBtn.style.fontSize = fontSzInput.value + 'px';
                var padV = document.querySelector('[name="aivt_btn_padding_v"]');
                var padH = document.querySelector('[name="aivt_btn_padding_h"]');
                if (padV && padH) previewBtn.style.padding = padV.value + 'px ' + padH.value + 'px';
                var fontWt = document.querySelector('[name="aivt_btn_font_weight"]');
                if (fontWt) previewBtn.style.fontWeight = fontWt.value;
            }

            if (radiusInput) {
                radiusInput.addEventListener('input', function() {
                    if (radiusVal) radiusVal.textContent = this.value + 'px';
                    updatePreviewStyles();
                });
            }
            if (fontSzInput) {
                fontSzInput.addEventListener('input', function() {
                    if (fontSzVal) fontSzVal.textContent = this.value + 'px';
                    updatePreviewStyles();
                });
            }
            document.querySelectorAll('[name="aivt_btn_padding_v"],[name="aivt_btn_padding_h"],[name="aivt_btn_font_weight"]').forEach(function(el) {
                el.addEventListener('change', updatePreviewStyles);
                el.addEventListener('input', updatePreviewStyles);
            });

            // Init preview with saved values
            updatePreviewStyles();

            /* ── Select all categories ── */
            var selectAll = document.getElementById('aivt-select-all-cats');
            if (selectAll) {
                selectAll.addEventListener('change', function() {
                    var boxes = document.querySelectorAll('.aivt-cat-checkbox');
                    for (var i = 0; i < boxes.length; i++) {
                        boxes[i].checked = this.checked;
                    }
                });
            }

            /* ── Individual product search ── */
            (function() {
                var searchInput   = document.getElementById('aivt-product-search-input');
                var chipsWrap     = document.getElementById('aivt-product-chips');
                var loadingEl     = document.getElementById('aivt-product-search-loading');
                var ajaxUrl       = aivtAdmin.ajaxUrl;
                var searchNonce   = aivtAdmin.searchNonce;
                var debounceTimer = null;
                var selectedIds   = aivtAdmin.selectedIds;

                // Portal dropdown — appended to <body> so it's never clipped by card overflow
                var portal = document.createElement('div');
                portal.id  = 'aivt-product-results-portal';
                document.body.appendChild( portal );

                function positionPortal() {
                    var rect = searchInput.getBoundingClientRect();
                    portal.style.top   = ( rect.bottom + 4 ) + 'px';
                    portal.style.left  = rect.left + 'px';
                    portal.style.width = rect.width + 'px';
                }

                function openPortal() {
                    positionPortal();
                    portal.classList.add('open');
                }

                function closePortal() {
                    portal.classList.remove('open');
                    portal.innerHTML = '';
                }

                function escHtml( str ) {
                    return String(str)
                        .replace(/&/g,'&amp;').replace(/</g,'&lt;')
                        .replace(/>/g,'&gt;').replace(/"/g,'&quot;');
                }

                function addChip( id, title ) {
                    if ( selectedIds.indexOf( id ) !== -1 ) return;
                    selectedIds.push( id );
                    var chip = document.createElement('div');
                    chip.className = 'aivt-product-chip';
                    chip.setAttribute('data-id', id);
                    chip.innerHTML =
                        '<span>' + escHtml(title) + '</span>' +
                        '<input type="hidden" name="aivt_enabled_products[]" value="' + id + '" />' +
                        '<button type="button" class="aivt-product-chip-remove" aria-label="Remove">&times;</button>';
                    chip.querySelector('.aivt-product-chip-remove').addEventListener('click', function() {
                        var idx = selectedIds.indexOf( id );
                        if ( idx !== -1 ) selectedIds.splice( idx, 1 );
                        chip.parentNode.removeChild( chip );
                    });
                    chipsWrap.appendChild( chip );
                }

                // Wire remove buttons on server-rendered chips
                chipsWrap.querySelectorAll('.aivt-product-chip-remove').forEach(function(btn) {
                    btn.addEventListener('click', function() {
                        var chip = btn.closest('.aivt-product-chip');
                        var id   = parseInt( chip.getAttribute('data-id'), 10 );
                        var idx  = selectedIds.indexOf( id );
                        if ( idx !== -1 ) selectedIds.splice( idx, 1 );
                        chip.parentNode.removeChild( chip );
                    });
                });

                function renderResults( products ) {
                    portal.innerHTML = '';
                    if ( ! products || products.length === 0 ) {
                        portal.innerHTML = '<div class="aivt-product-result-empty">No products found. Try a different keyword.</div>';
                        openPortal();
                        return;
                    }
                    products.forEach(function( p ) {
                        var already = selectedIds.indexOf( p.id ) !== -1;
                        var item = document.createElement('div');
                        item.className = 'aivt-product-result-item' + ( already ? ' aivt-result-added' : '' );
                        var thumbHtml = p.thumbnail
                            ? '<img src="' + escHtml(p.thumbnail) + '" class="aivt-product-result-thumb" alt="" />'
                            : '<div class="aivt-product-result-thumb"></div>';
                        item.innerHTML =
                            thumbHtml +
                            '<div class="aivt-product-result-info">' +
                                '<div class="aivt-product-result-title">' + escHtml(p.title) + '</div>' +
                                '<div class="aivt-product-result-price">' + escHtml(p.price) + '</div>' +
                            '</div>' +
                            '<span class="aivt-product-result-add">' + ( already ? '&#10003; Added' : '+ Add' ) + '</span>';
                        if ( ! already ) {
                            item.style.cursor = 'pointer';
                            item.addEventListener('click', function() {
                                addChip( p.id, p.title );
                                // Keep dropdown open — just mark this item as added
                                item.classList.add('aivt-result-added');
                                item.style.opacity = '0.55';
                                item.style.cursor  = 'default';
                                var addLabel = item.querySelector('.aivt-product-result-add');
                                if ( addLabel ) addLabel.textContent = '✓ Added';
                                item.replaceWith( item.cloneNode(true) ); // remove click listener
                            });
                        } else {
                            item.style.opacity = '0.55';
                        }
                        portal.appendChild( item );
                    });
                    openPortal();
                }

                function doSearch( q ) {
                    loadingEl.style.display = 'block';
                    closePortal();
                    var fd = new FormData();
                    fd.append('action', 'aivt_search_products');
                    fd.append('nonce', searchNonce);
                    fd.append('q', q);
                    fetch(ajaxUrl, { method:'POST', body:fd, credentials:'same-origin' })
                        .then(function(r) { return r.json(); })
                        .then(function(data) {
                            loadingEl.style.display = 'none';
                            if ( data.success ) renderResults( data.data );
                        })
                        .catch(function() { loadingEl.style.display = 'none'; });
                }

                if ( searchInput ) {
                    searchInput.addEventListener('input', function() {
                        clearTimeout( debounceTimer );
                        var q = this.value.trim();
                        if ( q.length < 2 ) {
                            closePortal();
                            loadingEl.style.display = 'none';
                            return;
                        }
                        debounceTimer = setTimeout(function() { doSearch(q); }, 300);
                    });

                    // Reposition on scroll/resize so it tracks the input
                    window.addEventListener('scroll', function() {
                        if ( portal.classList.contains('open') ) positionPortal();
                    }, true);
                    window.addEventListener('resize', function() {
                        if ( portal.classList.contains('open') ) positionPortal();
                    });

                    // Close when clicking outside
                    document.addEventListener('mousedown', function(e) {
                        if ( e.target !== searchInput && ! portal.contains(e.target) ) {
                            closePortal();
                        }
                    });
                }
            })();

            /* ── Connection test ── */
            var testBtn    = document.getElementById('aivt-test-connection');
            var testResult = document.getElementById('aivt-test-result');
            if (testBtn && testResult) {
                testBtn.addEventListener('click', function() {
                    testBtn.disabled = true;
                    testResult.className = 'aivt-test-result testing';
                    testResult.style.display = 'block';
                    testResult.innerHTML = '&#9679; Testing connection...';

                    var formData = new FormData();
                    formData.append('action', 'aivt_test_connection');
                    formData.append('nonce', aivtAdmin.testNonce);

                    fetch(aivtAdmin.ajaxUrl, {
                        method: 'POST',
                        body: formData,
                        credentials: 'same-origin',
                    })
                    .then(function(res) { return res.json(); })
                    .then(function(data) {
                        if (data.success) {
                            testResult.className = 'aivt-test-result success';
                            testResult.innerHTML = '&#10003; Connected! Plan: <strong>' + data.data.plan + '</strong> &nbsp;|&nbsp; Usage: ' + data.data.usage + ' / ' + data.data.limit + ' TryOns';
                        } else {
                            testResult.className = 'aivt-test-result error';
                            testResult.innerHTML = '&#10007; ' + data.data.message;
                        }
                    })
                    .catch(function() {
                        testResult.className = 'aivt-test-result error';
                        testResult.innerHTML = '&#10007; Connection failed. Check the API URL and try again.';
                    })
                    .finally(function() {
                        testBtn.disabled = false;
                    });
                });
            }
        })();
        
