/**
 * Manual Editor Module
 * Handles: JSON editing, formatting, line numbers, stats
 */
(function($) {
    'use strict';

    window.SchemafyEditor = {
        /**
         * Initialize enhanced manual editor
         */
        initEnhancedManualEditor: function() {
            this.updateLineNumbers();
            this.updateEditorStats();

            // Bind editor events
            $(document).on('input', '#schemafy-manual-json', () => {
                this.updateLineNumbers();
                this.updateEditorStats();
                this.runRealtimeValidation();
            });

            // Strip <script type="application/ld+json"> wrapper on paste so users
            // can paste full schema snippets from the web without getting parse errors.
            $(document).on('paste', '#schemafy-manual-json', (e) => {
                const pasted = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
                if (!pasted) return;
                const stripped = this.stripScriptWrapper(pasted);
                if (stripped !== pasted) {
                    e.preventDefault();
                    const ta = e.target;
                    const start = ta.selectionStart;
                    const end = ta.selectionEnd;
                    const current = ta.value;
                    ta.value = current.substring(0, start) + stripped + current.substring(end);
                    ta.selectionStart = ta.selectionEnd = start + stripped.length;
                    $(ta).trigger('input');
                }
            });

            // No scroll sync needed — textarea auto-expands so it never scrolls internally

            // Initialize URL combobox
            this.initManualUrlCombobox();
        },

        /**
         * URL combobox — same UX as Smart Builder, adapted for manual form IDs
         */
        initManualUrlCombobox: function() {
            const self = this;
            const $input   = $('#schemafy-manual-url-combobox');
            const $results = $('#schemafy-manual-url-results');

            if ($input.length === 0) return;

            let allPages = [];

            $.ajax({
                url: schemafy_ajax.ajax_url,
                method: 'POST',
                data: { action: 'schemafy_get_site_urls', nonce: schemafy_ajax.nonce },
                beforeSend: function() { $input.attr('placeholder', 'Loading pages…'); },
                success: function(response) {
                    $input.attr('placeholder', 'Search pages or paste a URL…');
                    if (response.success && response.data.urls) allPages = response.data.urls;
                },
                error: function() { $input.attr('placeholder', 'Paste a URL and press Enter…'); }
            });

            function esc(s) { return window.SchemafyUtilities.escapeHtml(s); }

            function renderResults(q) {
                const isUrl = /^https?:\/\//i.test(q.trim());
                const lower = q.toLowerCase();
                let html = '';
                if (isUrl) {
                    html = `<div class="schemafy-url-result schemafy-url-result-paste" data-url="${esc(q.trim())}" data-title="${esc(q.trim())}">
                        <span class="dashicons dashicons-admin-links"></span>
                        <div class="schemafy-url-result-body">
                            <span class="schemafy-url-result-title">Add this URL</span>
                            <span class="schemafy-url-result-url">${esc(q.trim())}</span>
                        </div></div>`;
                } else {
                    const filtered = q.length >= 1
                        ? allPages.filter(p => (p.title + ' ' + p.url).toLowerCase().includes(lower)).slice(0, 10)
                        : allPages.slice(0, 10);
                    if (filtered.length === 0 && q.length >= 2) {
                        html = `<div class="schemafy-url-result-empty">No pages found — press Enter to add as URL</div>`;
                    } else {
                        const grouped = {};
                        filtered.forEach(p => {
                            const label = p.post_type_label || 'Other';
                            if (!grouped[label]) grouped[label] = [];
                            grouped[label].push(p);
                        });
                        Object.keys(grouped).sort().forEach(type => {
                            html += `<div class="schemafy-url-result-group">${esc(type)}</div>`;
                            grouped[type].forEach(p => {
                                html += `<div class="schemafy-url-result" data-url="${esc(p.url)}" data-title="${esc(p.title)}">
                                    <span class="dashicons dashicons-admin-page"></span>
                                    <div class="schemafy-url-result-body">
                                        <span class="schemafy-url-result-title">${esc(p.title)}</span>
                                        <span class="schemafy-url-result-url">${esc(p.url)}</span>
                                    </div></div>`;
                            });
                        });
                    }
                }
                $results.html(html);
                html ? $results.show() : $results.hide();
            }

            function addChip(url, label) {
                const $hidden = $('#schemafy-manual-target-urls');
                const $chips  = $('#schemafy-manual-selected-urls');
                let urls = [];
                try { urls = JSON.parse($hidden.val() || '[]'); } catch(e) {}
                const editingId = $('#schemafy-manual-form').data('editing-id');
                if (editingId && urls.length >= 1) {
                    window.SchemafyUtilities && window.SchemafyUtilities.showNotification('Only one URL allowed when editing a schema', 'warning');
                    return;
                }
                if (urls.indexOf(url) !== -1) {
                    window.SchemafyUtilities && window.SchemafyUtilities.showNotification('This URL is already added', 'warning');
                    return;
                }
                urls.push(url);
                $hidden.val(JSON.stringify(urls));
                const display = label || url;
                $chips.append(`<div class="schemafy-url-chip" data-url="${esc(url)}">
                    <span class="dashicons dashicons-admin-links"></span>
                    <span class="schemafy-url-chip-text" title="${esc(url)}">${esc(display)}</span>
                    <button type="button" class="schemafy-chip-remove" title="Remove"><span class="dashicons dashicons-no-alt"></span></button>
                </div>`);
            }

            $input.on('focus', function() { renderResults($(this).val()); });
            $input.on('input', function() { renderResults($(this).val()); });
            $input.on('keydown', function(e) {
                if (e.key === 'Enter') {
                    e.preventDefault();
                    const val = $(this).val().trim();
                    if (!val) return;
                    const $first = $results.find('.schemafy-url-result').first();
                    if ($first.length) addChip($first.data('url'), $first.data('title'));
                    else addChip(val, val);
                    $(this).val('');
                    $results.hide();
                } else if (e.key === 'Escape') {
                    $results.hide();
                }
            });
            $results.on('click', '.schemafy-url-result', function() {
                addChip($(this).data('url'), $(this).data('title'));
                $input.val('').focus();
                $results.hide();
            });
            $(document).on('click.manualCombobox', function(e) {
                if (!$(e.target).closest('#schemafy-manual-url-dropdown-container').length) {
                    $results.hide();
                }
            });
            $('#schemafy-manual-selected-urls').on('click', '.schemafy-chip-remove', function() {
                const $chip = $(this).closest('.schemafy-url-chip');
                const url = $chip.data('url');
                const editingId = $('#schemafy-manual-form').data('editing-id');
                if (editingId) {
                    window.SchemafyUtilities && window.SchemafyUtilities.showNotification('Cannot remove URL while editing a schema', 'warning');
                    return;
                }
                let urls = [];
                try { urls = JSON.parse($('#schemafy-manual-target-urls').val() || '[]'); } catch(e) {}
                urls = urls.filter(u => u !== url);
                $('#schemafy-manual-target-urls').val(JSON.stringify(urls));
                $chip.remove();
            });
        },

        /**
         * Load site URLs for dropdown and initialize multi-URL selector (legacy — no longer used)
         */
        loadSiteUrls: function() {
            const self = this;
            const $select = $('#schemafy-manual-url');
            const $customInput = $('#schemafy-manual-custom-url');
            const $addBtn = $('#schemafy-manual-add-url');
            const $toggle = $('#schemafy-manual-toggle');

            if ($select.length === 0) return;

            // Show the + add button always so user can explicitly add selected URL
            $addBtn.show();

            // Load URLs into dropdown
            $.ajax({
                url: schemafy_ajax.ajax_url,
                method: 'POST',
                data: {
                    action: 'schemafy_get_site_urls',
                    nonce: schemafy_ajax.nonce
                },
                beforeSend: function() {
                    $select.html('<option value="">Loading URLs...</option>');
                },
                success: function(response) {
                    if (response.success && response.data.urls) {
                        $select.html('<option value="">Select a URL...</option>');

                        const grouped = {};
                        response.data.urls.forEach(url => {
                            const type = url.post_type_label || 'Other';
                            if (!grouped[type]) grouped[type] = [];
                            grouped[type].push(url);
                        });

                        Object.keys(grouped).sort().forEach(type => {
                            const $optgroup = $('<optgroup>').attr('label', type);
                            grouped[type].forEach(url => {
                                $optgroup.append($('<option>').val(url.url).text(url.title));
                            });
                            $select.append($optgroup);
                        });
                    }
                },
                error: function() {
                    $select.html('<option value="">Failed to load URLs</option>');
                }
            });

            // Add URL on dropdown change
            $select.off('change.manualAdd').on('change.manualAdd', function() {
                const val = $(this).val();
                if (val) {
                    self.addManualUrlChip(val);
                    $(this).val('');
                }
            });

            // Add URL button click (off first to prevent duplicate handlers on re-init)
            $addBtn.off('click.manualAdd').on('click.manualAdd', function() {
                let url = '';
                if ($customInput.is(':visible')) {
                    url = $customInput.val().trim();
                    if (url) $customInput.val('');
                } else {
                    url = $select.val();
                    if (url) $select.val('');
                }
                if (url) {
                    self.addManualUrlChip(url);
                } else {
                    // Show feedback when no URL is selected
                    if (window.SchemafyUtilities) {
                        window.SchemafyUtilities.showNotification(
                            $customInput.is(':visible')
                                ? 'Please enter a URL first.'
                                : 'Please select a URL from the list first.',
                            'warning'
                        );
                    }
                    ($customInput.is(':visible') ? $customInput : $select).focus();
                }
            });

            // Enter key on custom input
            $customInput.off('keydown.manualAdd').on('keydown.manualAdd', function(e) {
                if (e.key === 'Enter') {
                    e.preventDefault();
                    $addBtn.trigger('click.manualAdd');
                }
            });

            // Toggle manual/dropdown
            $toggle.off('click.manualToggle').on('click.manualToggle', function() {
                const isCustom = $customInput.is(':visible');
                if (isCustom) {
                    $customInput.hide();
                    $select.show().focus();
                    $toggle.find('.dashicons').removeClass('dashicons-arrow-left-alt2').addClass('dashicons-edit');
                    $addBtn.hide();
                } else {
                    $select.hide();
                    $customInput.show().focus();
                    $toggle.find('.dashicons').removeClass('dashicons-edit').addClass('dashicons-arrow-left-alt2');
                    $addBtn.show();
                }
            });

            // Remove chip handler
            $('#schemafy-manual-selected-urls').off('click.manualChip').on('click.manualChip', '.schemafy-chip-remove', function() {
                const url = $(this).closest('.schemafy-url-chip').data('url');
                self.removeManualUrlChip(url);
            });
        },

        /**
         * Add a URL chip in the manual editor
         */
        addManualUrlChip: function(url) {
            const $container = $('#schemafy-manual-selected-urls');
            const $hidden = $('#schemafy-manual-target-urls');

            let urls = [];
            try { urls = JSON.parse($hidden.val() || '[]'); } catch(e) { urls = []; }

            // Block adding more URLs in edit mode (one URL per schema)
            const editingId = $('#schemafy-manual-form').data('editing-id');
            if (editingId && urls.length >= 1) {
                if (window.SchemafyUtilities) {
                    window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.only_one_url) || 'Only one URL allowed when editing a schema', 'warning');
                }
                return;
            }

            if (urls.indexOf(url) !== -1) {
                if (window.SchemafyUtilities) {
                    window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.url_already_added) || 'This URL is already added', 'warning');
                }
                return;
            }

            urls.push(url);
            $hidden.val(JSON.stringify(urls));

            const $option = $(`#schemafy-manual-url option[value="${CSS.escape(url)}"]`);
            const displayText = $option.length ? $option.text() : url;

            const chipHtml = `
                <div class="schemafy-url-chip" data-url="${window.SchemafyUtilities.escapeHtml(url)}">
                    <span class="dashicons dashicons-admin-links"></span>
                    <span class="schemafy-url-chip-text" title="${window.SchemafyUtilities.escapeHtml(url)}">${window.SchemafyUtilities.escapeHtml(displayText)}</span>
                    <button type="button" class="schemafy-chip-remove" title="Remove">
                        <span class="dashicons dashicons-no-alt"></span>
                    </button>
                </div>
            `;
            $container.append(chipHtml);
        },

        /**
         * Remove a URL chip from manual editor
         */
        removeManualUrlChip: function(url) {
            // Block removing URLs in edit mode
            const editingId = $('#schemafy-manual-form').data('editing-id');
            if (editingId) {
                if (window.SchemafyUtilities) {
                    window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.cannot_remove_url) || 'Cannot remove URL while editing a schema', 'warning');
                }
                return;
            }

            const $container = $('#schemafy-manual-selected-urls');
            const $hidden = $('#schemafy-manual-target-urls');

            let urls = [];
            try { urls = JSON.parse($hidden.val() || '[]'); } catch(e) { urls = []; }

            urls = urls.filter(u => u !== url);
            $hidden.val(JSON.stringify(urls));

            $container.find(`.schemafy-url-chip[data-url="${CSS.escape(url)}"]`).remove();
        },

        /**
         * Get selected URLs from manual editor chip list
         */
        getManualSelectedUrls: function() {
            const $hidden = $('#schemafy-manual-target-urls');
            try {
                return JSON.parse($hidden.val() || '[]');
            } catch(e) {
                return [];
            }
        },

        /**
         * Update line numbers display
         */
        updateLineNumbers: function() {
            const $textarea = $('#schemafy-manual-json');
            const $lineNumbers = $('#schemafy-line-numbers');
            if ($textarea.length === 0 || $lineNumbers.length === 0) return;

            const ta = $textarea[0];
            const value = $textarea.val() || '';
            const lines = value.split('\n');
            // Always count all lines including the trailing empty one — suppressing it
            // caused the last line to have no number when the content ended with \n.
            const lineCount = lines.length;

            // Read exact values from computed style — no rounding to avoid per-line accumulation
            const cs = window.getComputedStyle(ta);
            const lineH = cs.lineHeight; // exact string e.g. "20.8px"
            const padTop = cs.paddingTop;
            const padBot = cs.paddingBottom;

            $lineNumbers.css({ 'padding-top': padTop, 'padding-bottom': padBot });

            const html = [];
            for (let i = 1; i <= lineCount; i++) {
                html.push(`<div style="height:${lineH};line-height:${lineH}">${i}</div>`);
            }
            $lineNumbers.html(html.join(''));

            // Auto-expand textarea so it never scrolls internally — eliminates scroll-sync drift
            ta.style.height = 'auto';
            ta.style.height = Math.max(400, ta.scrollHeight) + 'px';
        },

        /**
         * Update AI editor line numbers
         */
        updateAiLineNumbers: function() {
            const $textarea = $('#schemafy-ai-json');
            const $lineNumbers = $('#schemafy-ai-line-numbers');
            if ($textarea.length === 0 || $lineNumbers.length === 0) return;

            const ta = $textarea[0];
            const value = $textarea.val() || '';
            const lines = value.split('\n');
            const lineCount = lines.length;

            const cs = window.getComputedStyle(ta);
            const lineH = cs.lineHeight;
            const padTop = cs.paddingTop;
            const padBot = cs.paddingBottom;

            $lineNumbers.css({ 'padding-top': padTop, 'padding-bottom': padBot });

            const html = [];
            for (let i = 1; i <= lineCount; i++) {
                html.push(`<div style="height:${lineH};line-height:${lineH}">${i}</div>`);
            }
            $lineNumbers.html(html.join(''));

            ta.style.height = 'auto';
            ta.style.height = Math.max(300, ta.scrollHeight) + 'px';
        },

        /**
         * Update editor statistics
         */
        updateEditorStats: function() {
            const $textarea = $('#schemafy-manual-json');
            if ($textarea.length === 0) return;

            const value = $textarea.val() || '';
            const lines = value.split('\n').length;
            const chars = value.length;
            const kb    = chars > 0 ? (new Blob([value]).size / 1024).toFixed(2) : '0.00';

            $('#schemafy-json-lines').text(lines);
            $('#schemafy-json-chars').text(chars);
            $('#schemafy-json-size').text(kb);

            // Validate and show status
            this.runRealtimeValidation();
        },

        /**
         * Run real-time validation
         */
        runRealtimeValidation: function() {
            const $textarea = $('#schemafy-manual-json');
            const $status = $('#schemafy-editor-status');

            if ($textarea.length === 0 || $status.length === 0) return;

            const value = $textarea.val();

            if (!value || !value.trim()) {
                $status.html('<span class="dashicons dashicons-info"></span> Enter JSON')
                    .removeClass('valid invalid');
                return;
            }

            // Security check: block script/html injection before JSON parsing
            if (/<script[\s>]/i.test(value)) {
                $status.html('<span class="dashicons dashicons-dismiss"></span> Invalid — &lt;script&gt; tag detected, please remove it')
                    .removeClass('valid').addClass('invalid');
                return;
            }
            if (/<\/?[a-z]/i.test(value)) {
                $status.html('<span class="dashicons dashicons-dismiss"></span> Invalid — HTML tag detected, JSON must not contain raw HTML')
                    .removeClass('valid').addClass('invalid');
                return;
            }

            try {
                const parsed = JSON.parse(value);
                const hasContext = !!parsed['@context'];
                const hasType = !!parsed['@type'];

                if (hasContext && hasType) {
                    $status.html('<span class="dashicons dashicons-yes-alt"></span> Valid Schema')
                        .removeClass('invalid').addClass('valid');
                } else {
                    const missing = [];
                    if (!hasContext) missing.push('@context');
                    if (!hasType) missing.push('@type');
                    $status.html('<span class="dashicons dashicons-warning"></span> Missing: ' + missing.join(', '))
                        .removeClass('valid').addClass('invalid');
                }
            } catch (e) {
                // Show specific parse error so user knows which line/issue to fix
                let errMsg = e.message || 'syntax error';
                const posMatch = errMsg.match(/position (\d+)/);
                if (posMatch) {
                    const pos = parseInt(posMatch[1]);
                    const lines = value.substring(0, pos).split('\n');
                    errMsg = 'Line ' + lines.length + ': ' + errMsg;
                }
                $status.html('<span class="dashicons dashicons-dismiss"></span> Invalid JSON — ' + errMsg)
                    .removeClass('valid').addClass('invalid');
            }
        },

        /**
         * Format JSON in editor
         */
        formatJson: function(selector) {
            const $textarea = $(selector);
            const value = $textarea.val();

            try {
                const parsed = JSON.parse(value);
                const formatted = JSON.stringify(parsed, null, 2);
                $textarea.val(formatted);
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.json_formatted_manual) || 'JSON formatted', 'success');

                if (selector === '#schemafy-manual-json') {
                    this.updateLineNumbers();
                    this.updateEditorStats();
                }
            } catch(e) {
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.invalid_json_cannot_format) || 'Invalid JSON - cannot format', 'error');
            }
        },

        /**
         * Minify JSON in editor
         */
        minifyJson: function(selector) {
            const $textarea = $(selector);
            const value = $textarea.val();

            try {
                const parsed = JSON.parse(value);
                const minified = JSON.stringify(parsed);
                $textarea.val(minified);
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.json_minified) || 'JSON minified', 'success');

                if (selector === '#schemafy-manual-json') {
                    this.updateLineNumbers();
                    this.updateEditorStats();
                }
            } catch(e) {
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.invalid_json_cannot_minify) || 'Invalid JSON - cannot minify', 'error');
            }
        },

        /**
         * Copy JSON to clipboard
         */
        copyJson: function(selector) {
            const json = $(selector || '#schemafy-manual-json').val();

            navigator.clipboard.writeText(json).then(() => {
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.json_copied) || 'JSON copied to clipboard!', 'success');
            }).catch(() => {
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.failed_copy_clipboard) || 'Failed to copy to clipboard', 'error');
            });
        },

        /**
         * Clear editor
         */
        clearEditor: function(selector) {
            window.SchemafyUtilities.confirm(
                'Clear the editor? This action cannot be undone.',
                () => {
                    $(selector).val('');
                    window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.editor_cleared) || 'Editor cleared', 'success');

                    if (selector === '#schemafy-manual-json') {
                        this.updateLineNumbers();
                        this.updateEditorStats();
                    }
                }
            );
        },

        /**
         * Insert variable at cursor position
         */
        insertVariable: function(selector, variable) {
            const $textarea = $(selector);
            if ($textarea.length === 0) {
                console.error('Textarea not found:', selector);
                return;
            }

            const textarea = $textarea[0];
            const pos = textarea.selectionStart || 0;
            const value = $textarea.val();
            const newValue = value.substring(0, pos) + variable + value.substring(pos);

            $textarea.val(newValue);

            const newPos = pos + variable.length;
            textarea.setSelectionRange(newPos, newPos);
            $textarea.focus();

            $textarea.trigger('input');
        },

        /**
         * Save manual schema (supports single and multi-URL)
         */
        saveManualSchema: function(e) {
            e.preventDefault();
            const $form = $('#schemafy-manual-form');
            const formData = window.SchemafyUtilities.getFormData($form);

            // Validate JSON
            const jsonData = formData.schema_data || $('#schemafy-manual-json').val();
            try {
                JSON.parse(jsonData);
            } catch (err) {
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.invalid_json_format) || 'Invalid JSON format', 'error');
                return;
            }

            const editingId = $form.data('editing-id');

            if (editingId) {
                // Editing mode: use first URL from chips
                const urls = this.getManualSelectedUrls();
                const url = urls.length > 0 ? urls[0] : '';
                if (!url) {
                    window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.add_target_url) || 'Please add a Target URL', 'error');
                    return;
                }

                formData.url = url;
                const data = {
                    action: 'schemafy_update_schema',
                    nonce: schemafy_ajax.nonce,
                    id: editingId,
                    meta_title: '',
                    meta_description: '',
                    ...formData
                };

                $.ajax({
                    url: schemafy_ajax.ajax_url,
                    type: 'POST',
                    data: data,
                    success: (response) => {
                        if (response.success) {
                            window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.schema_updated) || 'Schema updated successfully!', 'success');
                            this.resetManualForm($form);
                        } else {
                            window.SchemafyUtilities.showNotification(response.data || (schemafy_ajax.i18n && schemafy_ajax.i18n.error_updating_schema) || 'Error updating schema', 'error');
                        }
                    },
                    error: () => {
                        window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.error_updating_schema) || 'Error updating schema', 'error');
                    }
                });
                return;
            }

            // New schema: get URLs from chip list
            const urls = this.getManualSelectedUrls();

            if (urls.length === 0) {
                window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.add_one_target_url) || 'Please add at least one Target URL', 'error');
                return;
            }

            if (urls.length === 1) {
                // Single URL: use existing save flow
                formData.url = urls[0];
                const data = {
                    action: 'schemafy_save_schema',
                    nonce: schemafy_ajax.nonce,
                    meta_title: '',
                    meta_description: '',
                    ...formData
                };

                $.ajax({
                    url: schemafy_ajax.ajax_url,
                    type: 'POST',
                    data: data,
                    success: (response) => {
                        if (response.success) {
                            window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.schema_saved) || 'Schema saved successfully!', 'success');
                            this.resetManualForm($form);
                        } else {
                            window.SchemafyUtilities.showNotification(response.data || (schemafy_ajax.i18n && schemafy_ajax.i18n.error_saving_schema) || 'Error saving schema', 'error');
                        }
                    },
                    error: () => {
                        window.SchemafyUtilities.showNotification((schemafy_ajax.i18n && schemafy_ajax.i18n.error_saving_schema) || 'Error saving schema', 'error');
                    }
                });
            } else {
                // Multiple URLs: use bulk save
                if (window.SchemafyOperations && typeof window.SchemafyOperations.proceedToSaveSchemaBulk === 'function') {
                    window.SchemafyOperations.proceedToSaveSchemaBulk(
                        urls,
                        formData.schema_name,
                        formData.schema_type,
                        formData,
                        jsonData,
                        () => { this.resetManualForm($form); }
                    );
                }
            }
        },

        /**
         * Reset manual form after successful save
         */
        resetManualForm: function($form) {
            $form.removeData('editing-id');
            this.hideEditBanner();
            $form[0].reset();

            // Clear URL chips and restore combobox
            $('#schemafy-manual-selected-urls').empty();
            $('#schemafy-manual-target-urls').val('[]');
            $('#schemafy-manual-url-combobox').val('').prop('disabled', false).css('opacity', '');

            // Restore save button text
            const $saveBtn = $form.find('button[type="submit"]');
            if ($saveBtn.length && $saveBtn.data('original-html')) {
                $saveBtn.html($saveBtn.data('original-html'));
                $saveBtn.removeData('original-html');
            }

            if (window.SchemafyBulk && typeof window.SchemafyBulk.loadBulkSchemas === 'function') {
                window.SchemafyBulk.loadBulkSchemas();
            }
            if (window.SchemafyDashboard && typeof window.SchemafyDashboard.refreshStats === 'function') {
                window.SchemafyDashboard.refreshStats();
            }
        },

        /**
         * Toggle variables panel
         */
        toggleVariablesPanel: function() {
            const $panel = $('#schemafy-variables-panel');
            if ($panel.is(':visible')) {
                $panel.slideUp(200);
            } else {
                $panel.slideDown(200);
            }
        },

        /**
         * Restore selected URL from storage (no-op, kept for backward compat)
         */
        restoreSelectedUrl: function() {
            // Multi-URL mode doesn't auto-restore; chips are managed manually
        },

        /**
         * Handle URL dropdown change (legacy, now handled by loadSiteUrls)
         */
        handleUrlSelection: function() {
            // Multi-URL mode handles selection via chip system in loadSiteUrls()
        },

        /**
         * Strip <script type="application/ld+json">...</script> wrapper from pasted text.
         * Users often copy full schema snippets from the web including the wrapper tags.
         */
        stripScriptWrapper: function(text) {
            const trimmed = text.trim();
            const stripped = trimmed.replace(/^<script[^>]*type=["']application\/ld\+json["'][^>]*>\s*/i, '')
                                    .replace(/\s*<\/script>\s*$/i, '');
            return stripped.trim();
        },

        // ── Template picker ───────────────────────────────────────────
        templates: {
            article: JSON.stringify({
                "@context": "https://schema.org",
                "@type": "Article",
                "headline": "{{post_title}}",
                "description": "{{post_excerpt}}",
                "datePublished": "{{post_date}}",
                "dateModified": "{{post_modified}}",
                "author": { "@type": "Person", "name": "{{post_author}}" },
                "publisher": {
                    "@type": "Organization",
                    "name": "{{site_name}}",
                    "logo": { "@type": "ImageObject", "url": "{{site_url}}/logo.png" }
                },
                "image": "{{featured_image}}",
                "url": "{{post_url}}"
            }, null, 2),

            product: JSON.stringify({
                "@context": "https://schema.org",
                "@type": "Product",
                "name": "{{post_title}}",
                "description": "{{post_excerpt}}",
                "image": "{{featured_image}}",
                "url": "{{post_url}}",
                "offers": {
                    "@type": "Offer",
                    "price": "{{product_price}}",
                    "priceCurrency": "{{product_currency}}",
                    "availability": "{{product_stock_status}}",
                    "url": "{{post_url}}"
                },
                "aggregateRating": {
                    "@type": "AggregateRating",
                    "ratingValue": "{{product_rating}}",
                    "reviewCount": "{{product_review_count}}"
                }
            }, null, 2),

            organization: JSON.stringify({
                "@context": "https://schema.org",
                "@type": "Organization",
                "name": "{{site_name}}",
                "url": "{{site_url}}",
                "description": "{{site_description}}",
                "logo": "{{site_url}}/logo.png",
                "sameAs": [],
                "contactPoint": {
                    "@type": "ContactPoint",
                    "contactType": "customer service",
                    "email": ""
                }
            }, null, 2),

            faq: JSON.stringify({
                "@context": "https://schema.org",
                "@type": "FAQPage",
                "mainEntity": [
                    {
                        "@type": "Question",
                        "name": "Your question here?",
                        "acceptedAnswer": { "@type": "Answer", "text": "Your answer here." }
                    },
                    {
                        "@type": "Question",
                        "name": "Another question?",
                        "acceptedAnswer": { "@type": "Answer", "text": "Another answer." }
                    }
                ]
            }, null, 2),

            localbusiness: JSON.stringify({
                "@context": "https://schema.org",
                "@type": "LocalBusiness",
                "name": "{{site_name}}",
                "url": "{{site_url}}",
                "description": "{{site_description}}",
                "address": {
                    "@type": "PostalAddress",
                    "streetAddress": "",
                    "addressLocality": "",
                    "addressRegion": "",
                    "postalCode": "",
                    "addressCountry": ""
                },
                "telephone": "",
                "openingHours": ["Mo-Fr 09:00-17:00"],
                "geo": { "@type": "GeoCoordinates", "latitude": "", "longitude": "" }
            }, null, 2),

            event: JSON.stringify({
                "@context": "https://schema.org",
                "@type": "Event",
                "name": "{{post_title}}",
                "description": "{{post_excerpt}}",
                "startDate": "{{post_date}}",
                "endDate": "",
                "eventStatus": "https://schema.org/EventScheduled",
                "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
                "location": {
                    "@type": "Place",
                    "name": "",
                    "address": { "@type": "PostalAddress", "addressLocality": "", "addressCountry": "" }
                },
                "organizer": { "@type": "Organization", "name": "{{site_name}}", "url": "{{site_url}}" },
                "image": "{{featured_image}}",
                "url": "{{post_url}}"
            }, null, 2)
        },

        insertTemplate: function(key) {
            const tpl = this.templates[key];
            if (!tpl) return;
            const $ta = $('#schemafy-manual-json');
            $ta.val(tpl);
            $ta.trigger('input');
            this.updateLineNumbers();
            this.updateEditorStats();
            window.SchemafyUtilities.showNotification('Template inserted — fill in the placeholders', 'success');
        },

        // ── Edit mode banner ──────────────────────────────────────────
        showEditBanner: function(name) {
            $('#schemafy-manual-edit-name').text(name || 'Unnamed');
            $('#schemafy-manual-edit-banner').slideDown(180);
        },

        hideEditBanner: function() {
            $('#schemafy-manual-edit-banner').slideUp(180);
        }
    };

})(jQuery);
