/**
 * WYSIWYG Form Builder — Vanilla JS
 *
 * Drag-and-drop form template builder using SortableJS.
 * Works for both admin (WP Admin) and vendor (Dokan Dashboard).
 *
 * Config is injected via wp_localize_script('wahrb-form-builder-js', 'wahrbFormBuilderConfig', {...})
 *
 * @package WahraRentalsBookings
 * @since   2.3.0
 */

(function () {
    'use strict';

    /* ===================================================================
       Field Type Icon Map
       =================================================================== */
    var FIELD_ICONS = {
        text: '✏️', email: '📧', number: '🔢', phone: '📞', date: '📅', textarea: '📝',
        select: '▾', checkbox: '☑️', radio: '◉',
        heading: '═', html: '&lt;/&gt;',
        hidden: '👁', consent: '✅'
    };

    /* ===================================================================
       WAHRBFormBuilder — Main Controller
       =================================================================== */
    window.WAHRBFormBuilder = {

        /* ── State ── */
        config: {},
        root: null,
        view: 'list',              // 'list' | 'builder' | 'preview'
        templates: [],
        currentTemplate: null,     // template being edited (null = new)
        fields: [],                // current template field array
        selectedIndex: -1,         // which field is selected in canvas
        saving: false,
        loading: false,
        sortableCanvas: null,
        sortablePalettes: [],

        /* ── Helpers ── */
        __: function (key, fallback) {
            return (this.config.i18n && this.config.i18n[key]) || fallback || key;
        },

        getApiBase: function () {
            var role = this.config.role || 'admin';
            return this.config.apiUrl + '/' + (role === 'vendor' ? 'vendor' : 'admin') + '/form-templates';
        },

        api: function (url, method, data) {
            var self = this;
            var opts = {
                method: method || 'GET',
                headers: {
                    'X-WP-Nonce': this.config.nonce,
                    'Content-Type': 'application/json'
                }
            };
            if (data && method !== 'GET') {
                opts.body = JSON.stringify(data);
            }
            return fetch(url, opts).then(function (r) {
                return r.json().then(function (body) {
                    if (!r.ok) {
                        throw new Error(body.message || self.__('unknownError', 'An error occurred'));
                    }
                    return body;
                });
            });
        },

        /* =================================================================
           Initialization
           ================================================================= */
        init: function () {
            this.config = window.wahrbFormBuilderConfig || {};
            this.root = document.getElementById('wahrb-form-builder-root');
            if (!this.root) return;

            // Single delegated event handlers (attached once, never duplicated)
            var self = this;
            this.root.addEventListener('click', function (e) { self._handleRootClick(e); });
            this.root.addEventListener('input', function (e) { self._handleRootInput(e); });
            this.root.addEventListener('change', function (e) { self._handleRootChange(e); });

            this.loadTemplates();
        },

        /* =================================================================
           Data Loading
           ================================================================= */
        loadTemplates: function () {
            var self = this;
            this.loading = true;
            this.renderLoading();

            this.api(this.getApiBase(), 'GET')
                .then(function (resp) {
                    self.templates = (resp.data || resp || []);
                    if (!Array.isArray(self.templates)) self.templates = [];
                    self.loading = false;
                    self.view = 'list';
                    self.render();
                })
                .catch(function (err) {
                    self.loading = false;
                    self.showNotice('error', err.message);
                    self.templates = [];
                    self.view = 'list';
                    self.render();
                });
        },

        /* =================================================================
           Master Render
           ================================================================= */
        render: function () {
            if (!this.root) return;
            this.root.innerHTML = '';

            if (this.view === 'list') {
                this.renderListView();
            } else if (this.view === 'builder') {
                this.renderBuilderView();
            } else if (this.view === 'preview') {
                this.renderPreviewView();
            }
        },

        renderLoading: function () {
            if (!this.root) return;
            this.root.innerHTML =
                '<div class="wahrb-fb-loading">' +
                '<span class="wahrb-fb-spinner"></span>' +
                this.__('loading', 'Loading...') +
                '</div>';
        },

        /* =================================================================
           LIST VIEW — Template table
           ================================================================= */
        renderListView: function () {
            var self = this;
            var html = '';

            // Toolbar
            html += '<div class="wahrb-fb-toolbar">';
            html += '<div class="wahrb-fb-toolbar-left">';
            html += '<h2>' + this.__('formTemplates', 'Form Templates') + '</h2>';
            html += '<span class="wahrb-fb-badge wahrb-fb-badge-count">' + this.templates.length + '</span>';
            html += '</div>';
            html += '<div class="wahrb-fb-toolbar-right">';
            html += '<button class="wahrb-fb-btn wahrb-fb-btn-primary" data-action="create-new">';
            html += '+ ' + this.__('createNew', 'Create New');
            html += '</button>';
            html += '</div>';
            html += '</div>';

            // Table
            html += '<div class="wahrb-fb-table-wrap">';
            html += '<table class="wahrb-fb-table">';
            html += '<thead><tr>';
            html += '<th>' + this.__('name', 'Name') + '</th>';
            html += '<th>' + this.__('scope', 'Scope') + '</th>';
            html += '<th>' + this.__('category', 'Category') + '</th>';
            html += '<th>' + this.__('fields', 'Fields') + '</th>';
            html += '<th>' + this.__('status', 'Status') + '</th>';
            html += '<th>' + this.__('actions', 'Actions') + '</th>';
            html += '</tr></thead><tbody>';

            if (this.templates.length === 0) {
                html += '<tr class="wahrb-fb-empty-row"><td colspan="6">';
                html += this.__('noTemplates', 'No form templates yet. Create your first one!');
                html += '</td></tr>';
            } else {
                for (var i = 0; i < this.templates.length; i++) {
                    var t = this.templates[i];
                    var fCount = (t.fields || []).length;
                    var isActive = t.is_active === '1' || t.is_active === 1 || t.is_active === true;
                    var isOwn = this.config.role === 'admin' ||
                        (t.vendor_id && parseInt(t.vendor_id, 10) === parseInt(this.config.vendorId, 10));

                    html += '<tr>';
                    html += '<td><strong>' + this.esc(t.template_name || '') + '</strong>';
                    if (t.description) html += '<br><small style="color:#94a3b8">' + this.esc(t.description) + '</small>';
                    html += '</td>';
                    html += '<td><span class="wahrb-fb-badge wahrb-fb-badge-scope">' + this.esc(t.scope || 'global') + '</span></td>';
                    html += '<td>' + this.esc(t.category_slug || '—') + '</td>';
                    html += '<td><span class="wahrb-fb-badge wahrb-fb-badge-count">' + fCount + '</span></td>';
                    html += '<td><span class="wahrb-fb-badge ' + (isActive ? 'wahrb-fb-badge-active' : 'wahrb-fb-badge-inactive') + '">';
                    html += isActive ? this.__('active', 'Active') : this.__('inactive', 'Inactive');
                    html += '</span></td>';
                    html += '<td class="wahrb-fb-actions">';
                    if (isOwn) {
                        html += '<button class="wahrb-fb-action-edit" data-action="edit" data-id="' + t.template_id + '">' + this.__('edit', 'Edit') + '</button>';
                        html += '<button class="wahrb-fb-action-delete" data-action="delete" data-id="' + t.template_id + '">' + this.__('delete', 'Delete') + '</button>';
                    } else {
                        html += '<span style="color:#94a3b8;font-size:12px">' + this.__('readOnly', 'Read-only') + '</span>';
                    }
                    html += '</td>';
                    html += '</tr>';
                }
            }

            html += '</tbody></table></div>';

            this.root.innerHTML = html;
            this.bindListEvents();
        },

        bindListEvents: function () {
            // Handled by single delegated handler (managed via _handleRootClick)
        },

        /* =================================================================
           BUILDER VIEW — 3-panel layout
           ================================================================= */
        startNewTemplate: function () {
            this.currentTemplate = null;
            this.fields = [];
            this.selectedIndex = -1;
            this.view = 'builder';
            this.render();
        },

        editTemplate: function (id) {
            var self = this;
            // Find in cache first
            var cached = null;
            for (var i = 0; i < this.templates.length; i++) {
                if (parseInt(this.templates[i].template_id, 10) === id) {
                    cached = this.templates[i];
                    break;
                }
            }
            if (cached) {
                self.currentTemplate = JSON.parse(JSON.stringify(cached));
                self.fields = self.currentTemplate.fields || [];
                self.selectedIndex = -1;
                self.view = 'builder';
                self.render();
            }
        },

        deleteTemplate: function (id) {
            var self = this;
            if (!confirm(this.__('confirmDelete', 'Are you sure you want to delete this template?'))) return;

            this.api(this.getApiBase() + '/' + id, 'DELETE')
                .then(function () {
                    self.templates = self.templates.filter(function (t) {
                        return parseInt(t.template_id, 10) !== id;
                    });
                    self.showNotice('success', self.__('templateDeleted', 'Template deleted.'));
                    self.render();
                })
                .catch(function (err) {
                    self.showNotice('error', err.message);
                });
        },

        renderBuilderView: function () {
            var html = '';

            // ── Back + Save toolbar ──
            html += '<div class="wahrb-fb-toolbar">';
            html += '<div class="wahrb-fb-toolbar-left">';
            html += '<button class="wahrb-fb-btn wahrb-fb-btn-secondary" data-action="back">← ' + this.__('back', 'Back') + '</button>';
            html += '<h2>' + (this.currentTemplate ? this.__('editTemplate', 'Edit Template') : this.__('newTemplate', 'New Template')) + '</h2>';
            html += '</div>';
            html += '<div class="wahrb-fb-toolbar-right">';
            html += '<button class="wahrb-fb-btn wahrb-fb-btn-secondary" data-action="preview">👁 ' + this.__('preview', 'Preview') + '</button>';
            html += '<button class="wahrb-fb-btn wahrb-fb-btn-primary" data-action="save">' + this.__('save', 'Save') + '</button>';
            html += '</div>';
            html += '</div>';

            // ── Template metadata ──
            html += this.renderMetaForm();

            // ── 3-panel builder ──
            html += '<div class="wahrb-fb-builder">';
            html += this.renderPalette();
            html += this.renderCanvas();
            html += this.renderProperties();
            html += '</div>';

            this.root.innerHTML = html;
            this.initSortable();
        },

        /* ── Meta form ── */
        renderMetaForm: function () {
            var t = this.currentTemplate || {};
            var scopes = this.config.allowedScopes || ['global'];
            var cats = this.config.categories || {};
            var catKeys = Object.keys(cats);
            var scope = t.scope || 'global';

            var html = '<div class="wahrb-fb-meta">';

            // Name
            html += '<div class="wahrb-fb-meta-field wahrb-fb-meta-name">';
            html += '<label>' + this.__('templateName', 'Template Name') + ' *</label>';
            html += '<input type="text" id="fb-meta-name" class="wahrb-fb-prop-input" value="' + this.esc(t.template_name || '') + '" placeholder="' + this.__('enterName', 'Enter template name…') + '">';
            html += '</div>';

            // Description
            html += '<div class="wahrb-fb-meta-field wahrb-fb-meta-desc">';
            html += '<label>' + this.__('description', 'Description') + '</label>';
            html += '<input type="text" id="fb-meta-desc" class="wahrb-fb-prop-input" value="' + this.esc(t.description || '') + '" placeholder="' + this.__('optional', 'Optional') + '">';
            html += '</div>';

            // Scope
            html += '<div class="wahrb-fb-meta-field">';
            html += '<label>' + this.__('scope', 'Scope') + '</label>';
            html += '<select id="fb-meta-scope" class="wahrb-fb-prop-select">';
            for (var i = 0; i < scopes.length; i++) {
                var s = scopes[i];
                html += '<option value="' + s + '"' + (scope === s ? ' selected' : '') + '>' + this.scopeLabel(s) + '</option>';
            }
            html += '</select>';
            html += '</div>';

            // Category (conditional — shown when scope is category or vendor)
            var showCat = (scope === 'category' || scope === 'vendor');
            html += '<div class="wahrb-fb-meta-field" id="fb-meta-cat-wrap" style="' + (showCat ? '' : 'display:none') + '">';
            html += '<label>' + this.__('category', 'Category') + '</label>';
            html += '<select id="fb-meta-category" class="wahrb-fb-prop-select">';
            html += '<option value="">' + this.__('selectCategory', 'Select…') + '</option>';
            for (var k = 0; k < catKeys.length; k++) {
                var cSlug = catKeys[k];
                var cData = cats[cSlug];
                var sel = (t.category_slug === cSlug) ? ' selected' : '';
                html += '<option value="' + cSlug + '"' + sel + '>' + (cData.emoji || '') + ' ' + (cData.label || cSlug) + '</option>';
            }
            html += '</select>';
            html += '</div>';

            // Product ID (conditional — shown when scope is product)
            var showProd = (scope === 'product');
            html += '<div class="wahrb-fb-meta-field" id="fb-meta-prod-wrap" style="' + (showProd ? '' : 'display:none') + '">';
            html += '<label>' + this.__('productId', 'Product ID') + '</label>';
            html += '<input type="number" id="fb-meta-product-id" class="wahrb-fb-prop-input" value="' + (t.product_id || '') + '" placeholder="0" min="0">';
            html += '</div>';

            // Active toggle
            var isActive = this.currentTemplate ? (t.is_active === '1' || t.is_active === 1 || t.is_active === true) : true;
            html += '<div class="wahrb-fb-meta-field">';
            html += '<label>' + this.__('status', 'Status') + '</label>';
            html += '<label class="wahrb-fb-prop-checkbox">';
            html += '<input type="checkbox" id="fb-meta-active"' + (isActive ? ' checked' : '') + '>';
            html += this.__('active', 'Active');
            html += '</label>';
            html += '</div>';

            html += '</div>';
            return html;
        },

        /* ── Palette (left panel) ── */
        renderPalette: function () {
            var groups = this.config.fieldTypeGroups || [];
            var html = '<div class="wahrb-fb-palette">';
            html += '<h3>' + this.__('fieldTypes', 'Field Types') + '</h3>';

            for (var g = 0; g < groups.length; g++) {
                var group = groups[g];
                html += '<div class="wahrb-fb-palette-group">';
                html += '<div class="wahrb-fb-palette-group-title">' + this.esc(group.label) + '</div>';
                html += '<div class="wahrb-fb-palette-list" data-group="' + group.key + '">';

                for (var t = 0; t < group.types.length; t++) {
                    var ft = group.types[t];
                    html += '<div class="wahrb-fb-palette-item" data-field-type="' + ft.value + '">';
                    html += '<span class="wahrb-fb-palette-icon">' + (FIELD_ICONS[ft.value] || '•') + '</span>';
                    html += '<span class="wahrb-fb-palette-label">' + this.esc(ft.label) + '</span>';
                    html += '</div>';
                }

                html += '</div>';
                html += '</div>';
            }

            html += '</div>';
            return html;
        },

        /* ── Canvas (center panel) ── */
        renderCanvas: function () {
            var html = '<div class="wahrb-fb-canvas">';

            html += '<div class="wahrb-fb-canvas-header">';
            html += '<h3>' + this.__('formFields', 'Form Fields') + '</h3>';
            html += '<span class="wahrb-fb-canvas-count">' + this.fields.length + ' ' + this.__('fields', 'fields') + '</span>';
            html += '</div>';

            html += '<div class="wahrb-fb-canvas-body" id="fb-canvas-body">';

            if (this.fields.length === 0) {
                html += '<div class="wahrb-fb-canvas-empty">';
                html += '<div class="wahrb-fb-canvas-empty-icon">📋</div>';
                html += this.__('dragFieldsHere', 'Drag fields here from the palette');
                html += '</div>';
            } else {
                for (var i = 0; i < this.fields.length; i++) {
                    html += this.renderFieldCard(i);
                }
            }

            html += '</div>';
            html += '</div>';
            return html;
        },

        renderFieldCard: function (index) {
            var field = this.fields[index];
            var selected = index === this.selectedIndex;
            var icon = FIELD_ICONS[field.type] || '•';

            var widthLabel = field.width === 'half' ? '½' : field.width === 'third' ? '⅓' : '';

            var html = '<div class="wahrb-fb-field' + (selected ? ' wahrb-fb-field-selected' : '') + '" data-index="' + index + '">';
            html += '<span class="wahrb-fb-field-handle" title="Drag to reorder">⠿</span>';
            html += '<span class="wahrb-fb-field-icon">' + icon + '</span>';
            html += '<div class="wahrb-fb-field-info">';
            html += '<div class="wahrb-fb-field-label">' + this.esc(field.label || this.__('untitled', '(Untitled)')) + '</div>';
            html += '<div class="wahrb-fb-field-type">' + this.esc(field.type) + (field.field_key ? ' · ' + this.esc(field.field_key) : '') + '</div>';
            html += '</div>';
            if (widthLabel) {
                html += '<span class="wahrb-fb-field-width-badge" title="Width">' + widthLabel + '</span>';
            }
            if (field.required) {
                html += '<span class="wahrb-fb-field-required" title="Required">*</span>';
            }
            html += '<button class="wahrb-fb-field-delete" data-action="delete-field" data-index="' + index + '" title="' + this.__('removeField', 'Remove field') + '">✕</button>';
            html += '</div>';
            return html;
        },

        /* ── Properties (right panel) ── */
        renderProperties: function () {
            var html = '<div class="wahrb-fb-properties">';
            html += '<div class="wahrb-fb-properties-header">';
            html += '<h3>' + this.__('fieldProperties', 'Field Properties') + '</h3>';
            html += '</div>';

            if (this.selectedIndex < 0 || this.selectedIndex >= this.fields.length) {
                html += '<div class="wahrb-fb-properties-empty">';
                html += '<div class="wahrb-fb-properties-empty-icon">👆</div>';
                html += this.__('selectField', 'Click a field in the canvas to edit its properties');
                html += '</div>';
            } else {
                html += '<div class="wahrb-fb-properties-body" id="fb-props-body">';
                html += this.renderFieldProps(this.fields[this.selectedIndex]);
                html += '</div>';
            }

            html += '</div>';
            return html;
        },

        renderFieldProps: function (field) {
            var html = '';
            var type = field.type;
            var isDisplay = (type === 'heading' || type === 'html');
            var isHidden = (type === 'hidden');
            var isChoice = (type === 'select' || type === 'checkbox' || type === 'radio');
            var isConsent = (type === 'consent');

            // Field key (readonly)
            html += '<div class="wahrb-fb-prop-group">';
            html += '<label class="wahrb-fb-prop-label">' + this.__('fieldKey', 'Field Key') + '</label>';
            html += '<input type="text" class="wahrb-fb-prop-input" id="fb-prop-key" value="' + this.esc(field.field_key || '') + '" readonly>';
            html += '</div>';

            // Label
            html += '<div class="wahrb-fb-prop-group">';
            html += '<label class="wahrb-fb-prop-label">' + this.__('label', 'Label') + '</label>';
            html += '<input type="text" class="wahrb-fb-prop-input" data-prop="label" value="' + this.esc(field.label || '') + '">';
            html += '</div>';

            // Width
            html += '<div class="wahrb-fb-prop-group">';
            html += '<label class="wahrb-fb-prop-label">' + this.__('width', 'Width') + '</label>';
            html += '<select class="wahrb-fb-prop-select" data-prop="width">';
            var w = field.width || 'full';
            html += '<option value="full"' + (w === 'full' ? ' selected' : '') + '>' + this.__('widthFull', 'Full width') + '</option>';
            html += '<option value="half"' + (w === 'half' ? ' selected' : '') + '>' + this.__('widthHalf', 'Half (1/2)') + '</option>';
            html += '<option value="third"' + (w === 'third' ? ' selected' : '') + '>' + this.__('widthThird', 'Third (1/3)') + '</option>';
            html += '</select>';
            html += '</div>';

            // Required (not for display/hidden types)
            if (!isDisplay && !isHidden) {
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-checkbox">';
                html += '<input type="checkbox" data-prop="required"' + (field.required ? ' checked' : '') + '>';
                html += this.__('required', 'Required');
                html += '</label>';
                html += '</div>';
            }

            // Placeholder (text types)
            if (['text', 'email', 'phone', 'number', 'textarea'].indexOf(type) !== -1) {
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('placeholder', 'Placeholder') + '</label>';
                html += '<input type="text" class="wahrb-fb-prop-input" data-prop="placeholder" value="' + this.esc(field.placeholder || '') + '">';
                html += '</div>';
            }

            // Default value (most non-display types)
            if (!isDisplay && type !== 'consent') {
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('defaultValue', 'Default Value') + '</label>';
                html += '<input type="text" class="wahrb-fb-prop-input" data-prop="default" value="' + this.esc(field['default'] || '') + '">';
                html += '</div>';
            }

            // Number min/max
            if (type === 'number') {
                html += '<div class="wahrb-fb-prop-group" style="display:flex;gap:8px">';
                html += '<div style="flex:1">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('min', 'Min') + '</label>';
                html += '<input type="number" class="wahrb-fb-prop-input" data-prop="min" value="' + (field.min !== undefined ? field.min : '') + '">';
                html += '</div>';
                html += '<div style="flex:1">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('max', 'Max') + '</label>';
                html += '<input type="number" class="wahrb-fb-prop-input" data-prop="max" value="' + (field.max !== undefined ? field.max : '') + '">';
                html += '</div>';
                html += '</div>';
            }

            // Options (select, radio, checkbox)
            if (isChoice) {
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('options', 'Options') + '</label>';
                html += '<div class="wahrb-fb-options-list" id="fb-options-list">';
                var opts = field.options || [];
                for (var i = 0; i < opts.length; i++) {
                    html += '<div class="wahrb-fb-option-row">';
                    html += '<input type="text" value="' + this.esc(opts[i]) + '" data-option-index="' + i + '">';
                    html += '<button class="wahrb-fb-option-remove" data-action="remove-option" data-option-index="' + i + '">✕</button>';
                    html += '</div>';
                }
                html += '</div>';
                html += '<button class="wahrb-fb-btn wahrb-fb-btn-sm wahrb-fb-btn-secondary wahrb-fb-option-add" data-action="add-option">';
                html += '+ ' + this.__('addOption', 'Add Option');
                html += '</button>';
                html += '</div>';
            }

            // HTML content
            if (type === 'html') {
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('htmlContent', 'HTML Content') + '</label>';
                html += '<textarea class="wahrb-fb-prop-textarea" data-prop="content" rows="4">' + this.esc(field.content || '') + '</textarea>';
                html += '</div>';
            }

            // Consent fields
            if (isConsent) {
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('consentText', 'Consent Text') + '</label>';
                html += '<input type="text" class="wahrb-fb-prop-input" data-prop="consent_text" value="' + this.esc(field.consent_text || '') + '">';
                html += '</div>';
                html += '<div class="wahrb-fb-prop-group">';
                html += '<label class="wahrb-fb-prop-label">' + this.__('consentUrl', 'Terms URL') + '</label>';
                html += '<input type="url" class="wahrb-fb-prop-input" data-prop="consent_url" value="' + this.esc(field.consent_url || '') + '">';
                html += '</div>';
            }

            return html;
        },

        /* =================================================================
           PREVIEW VIEW
           ================================================================= */
        renderPreviewView: function () {
            var self = this;
            var html = '';

            // Toolbar
            html += '<div class="wahrb-fb-toolbar">';
            html += '<div class="wahrb-fb-toolbar-left">';
            html += '<button class="wahrb-fb-btn wahrb-fb-btn-secondary" data-action="back-to-builder">← ' + this.__('backToBuilder', 'Back to Builder') + '</button>';
            html += '<h2>' + this.__('formPreview', 'Form Preview') + '</h2>';
            html += '</div>';
            html += '</div>';

            // Preview card — flex-wrap for multi-column
            html += '<div class="wahrb-fb-table-wrap"><div class="wahrb-fb-preview wahrb-fb-preview-grid">';

            if (this.fields.length === 0) {
                html += '<p style="color:#94a3b8;text-align:center;padding:40px 0">' + this.__('noFieldsPreview', 'No fields to preview. Add some fields in the builder.') + '</p>';
            } else {
                for (var i = 0; i < this.fields.length; i++) {
                    html += this.renderPreviewField(this.fields[i]);
                }
            }

            html += '</div></div>';

            this.root.innerHTML = html;
        },

        renderPreviewField: function (field) {
            var self = this;
            var key = field.field_key || '';
            var label = field.label || '';
            var rq = field.required ? '<span class="required">*</span>' : '';
            var ph = field.placeholder || '';
            var def = field['default'] || '';
            var widthClass = field.width && field.width !== 'full' ? ' wahrb-fb-preview-field-' + field.width : '';

            if (field.type === 'heading') {
                return '<h4 class="wahrb-fb-preview-heading' + widthClass + '">' + this.esc(label) + '</h4>';
            }
            if (field.type === 'html') {
                return '<div class="wahrb-fb-preview-html">' + (field.content || '') + '</div>';
            }
            if (field.type === 'hidden') {
                return ''; // Not visible
            }

            var html = '<div class="wahrb-fb-preview-field' + widthClass + '">';

            if (field.type === 'consent') {
                html += '<div class="wahrb-fb-preview-consent">';
                html += '<input type="checkbox" disabled>';
                html += '<span>' + this.esc(field.consent_text || label);
                if (field.consent_url) {
                    html += ' <a href="' + this.esc(field.consent_url) + '" target="_blank">' + this.__('viewTerms', 'View terms') + '</a>';
                }
                html += rq + '</span>';
                html += '</div>';
                html += '</div>';
                return html;
            }

            html += '<label>' + this.esc(label) + ' ' + rq + '</label>';

            switch (field.type) {
                case 'textarea':
                    html += '<textarea rows="3" placeholder="' + this.esc(ph) + '" disabled>' + this.esc(def) + '</textarea>';
                    break;
                case 'select':
                    html += '<select disabled>';
                    html += '<option>' + this.__('select', 'Select...') + '</option>';
                    (field.options || []).forEach(function (o) { html += '<option>' + self.esc(o) + '</option>'; });
                    html += '</select>';
                    break;
                case 'radio':
                    (field.options || []).forEach(function (o) {
                        html += '<div style="margin:4px 0"><label><input type="radio" name="preview_' + key + '" disabled> ' + self.esc(o) + '</label></div>';
                    });
                    break;
                case 'checkbox':
                    if (field.options && field.options.length) {
                        field.options.forEach(function (o) {
                            html += '<div style="margin:4px 0"><label><input type="checkbox" disabled> ' + self.esc(o) + '</label></div>';
                        });
                    } else {
                        html += '<label><input type="checkbox" disabled> ' + this.esc(label) + '</label>';
                    }
                    break;
                case 'date':
                    html += '<input type="date" value="' + this.esc(def) + '" disabled>';
                    break;
                case 'email':
                    html += '<input type="email" placeholder="' + this.esc(ph) + '" value="' + this.esc(def) + '" disabled>';
                    break;
                case 'number':
                    html += '<input type="number" placeholder="' + this.esc(ph) + '" value="' + this.esc(def) + '"' +
                        (field.min !== undefined ? ' min="' + field.min + '"' : '') +
                        (field.max !== undefined ? ' max="' + field.max + '"' : '') + ' disabled>';
                    break;
                default: // text, phone
                    html += '<input type="text" placeholder="' + this.esc(ph) + '" value="' + this.esc(def) + '" disabled>';
                    break;
            }

            html += '</div>';
            return html;
        },

        bindPreviewEvents: function () {
            // Use single delegated handler (managed via _rootHandler)
        },

        /* =================================================================
           Builder Events
           ================================================================= */
        bindBuilderEvents: function () {
            // Handled by single delegated handler (managed via _rootHandler)
        },

        /**
         * Single delegated event handler for all views.
         * Attached once in init(), never duplicated.
         */
        _handleRootClick: function (e) {
            var self = this;
                var btn = e.target.closest('[data-action]');
                if (btn) {
                    var action = btn.getAttribute('data-action');
                    if (action === 'back' || action === 'back-to-builder') {
                        if (self.view === 'preview') {
                            self.view = 'builder';
                            self.render();
                        } else {
                            self.view = 'list';
                            self.loadTemplates();
                        }
                        return;
                    }
                    if (action === 'save') {
                        self.saveTemplate();
                        return;
                    }
                    if (action === 'preview') {
                        self.view = 'preview';
                        self.render();
                        return;
                    }
                    if (action === 'create-new') {
                        self.startNewTemplate();
                        return;
                    }
                    if (action === 'edit') {
                        self.editTemplate(parseInt(btn.getAttribute('data-id'), 10));
                        return;
                    }
                    if (action === 'delete') {
                        self.deleteTemplate(parseInt(btn.getAttribute('data-id'), 10));
                        return;
                    }
                    if (action === 'delete-field') {
                        var idx = parseInt(btn.getAttribute('data-index'), 10);
                        self.removeField(idx);
                        return;
                    }
                    if (action === 'add-option') {
                        self.addOption();
                        return;
                    }
                    if (action === 'remove-option') {
                        var oi = parseInt(btn.getAttribute('data-option-index'), 10);
                        self.removeOption(oi);
                        return;
                    }
                }

                // Click on field card → select
                var fieldEl = e.target.closest('.wahrb-fb-field');
                if (fieldEl && !e.target.closest('[data-action]')) {
                    var fi = parseInt(fieldEl.getAttribute('data-index'), 10);
                    self.selectField(fi);
                }
        },

        _handleRootInput: function (e) {
            var self = this;
                var prop = e.target.getAttribute('data-prop');
                if (prop && self.selectedIndex >= 0) {
                    self.updateFieldProp(prop, e.target);
                }

                // Option value changes
                if (e.target.getAttribute('data-option-index') !== null && self.selectedIndex >= 0) {
                    var optIdx = parseInt(e.target.getAttribute('data-option-index'), 10);
                    var field = self.fields[self.selectedIndex];
                    if (field && field.options) {
                        field.options[optIdx] = e.target.value;
                    }
                }

                // Scope dropdown → show/hide category/product
                if (e.target.id === 'fb-meta-scope') {
                    var scope = e.target.value;
                    var catWrap = document.getElementById('fb-meta-cat-wrap');
                    var prodWrap = document.getElementById('fb-meta-prod-wrap');
                    if (catWrap) catWrap.style.display = (scope === 'category' || scope === 'vendor') ? '' : 'none';
                    if (prodWrap) prodWrap.style.display = (scope === 'product') ? '' : 'none';
                }
        },

        _handleRootChange: function (e) {
            var self = this;
            var prop = e.target.getAttribute('data-prop');
            if (prop && self.selectedIndex >= 0) {
                self.updateFieldProp(prop, e.target);
            }
            if (e.target.id === 'fb-meta-scope') {
                var scope = e.target.value;
                var catWrap = document.getElementById('fb-meta-cat-wrap');
                var prodWrap = document.getElementById('fb-meta-prod-wrap');
                if (catWrap) catWrap.style.display = (scope === 'category' || scope === 'vendor') ? '' : 'none';
                if (prodWrap) prodWrap.style.display = (scope === 'product') ? '' : 'none';
            }
        },

        /* =================================================================
           SortableJS initialization
           ================================================================= */
        initSortable: function () {
            var self = this;

            // Destroy previous instances
            if (this.sortableCanvas) {
                this.sortableCanvas.destroy();
                this.sortableCanvas = null;
            }
            this.sortablePalettes.forEach(function (s) { s.destroy(); });
            this.sortablePalettes = [];

            // Canvas sortable
            var canvasEl = document.getElementById('fb-canvas-body');
            if (!canvasEl || typeof Sortable === 'undefined') return;

            this.sortableCanvas = Sortable.create(canvasEl, {
                group: { name: 'fields', pull: false, put: true },
                animation: 150,
                handle: '.wahrb-fb-field-handle',
                ghostClass: 'sortable-ghost',
                chosenClass: 'sortable-chosen',
                draggable: '.wahrb-fb-field',
                onAdd: function (evt) {
                    // New field dropped from palette
                    var paletteItem = evt.item;
                    var fieldType = paletteItem.getAttribute('data-field-type');

                    // Remove the cloned palette element from canvas (we'll re-render)
                    if (paletteItem.parentNode) {
                        paletteItem.parentNode.removeChild(paletteItem);
                    }

                    if (fieldType) {
                        var newField = self.createDefaultField(fieldType, evt.newIndex);
                        self.fields.splice(evt.newIndex, 0, newField);
                        self.selectedIndex = evt.newIndex;
                        self.refreshCanvas();
                        self.refreshProperties();
                        self.refreshCanvasCount();
                    }
                },
                onEnd: function (evt) {
                    if (evt.oldIndex !== evt.newIndex && evt.oldIndex !== undefined && evt.newIndex !== undefined) {
                        // Reorder fields
                        var item = self.fields.splice(evt.oldIndex, 1)[0];
                        self.fields.splice(evt.newIndex, 0, item);

                        // Update selected index
                        if (self.selectedIndex === evt.oldIndex) {
                            self.selectedIndex = evt.newIndex;
                        } else if (self.selectedIndex > evt.oldIndex && self.selectedIndex <= evt.newIndex) {
                            self.selectedIndex--;
                        } else if (self.selectedIndex < evt.oldIndex && self.selectedIndex >= evt.newIndex) {
                            self.selectedIndex++;
                        }

                        self.refreshCanvas();
                    }
                }
            });

            // Palette sortables (one per group) — clone source
            var paletteLists = this.root.querySelectorAll('.wahrb-fb-palette-list');
            paletteLists.forEach(function (listEl) {
                var s = Sortable.create(listEl, {
                    group: { name: 'fields', pull: 'clone', put: false },
                    sort: false,
                    animation: 150
                });
                self.sortablePalettes.push(s);
            });
        },

        /* =================================================================
           Field Operations
           ================================================================= */
        createDefaultField: function (type, index) {
            var fieldTypes = {};
            (this.config.fieldTypes || []).forEach(function (ft) { fieldTypes[ft.value] = ft.label; });

            return {
                field_key: 'field_' + Date.now() + '_' + index,
                label: fieldTypes[type] || type,
                type: type,
                width: 'full',
                required: false,
                placeholder: '',
                'default': '',
                options: (type === 'select' || type === 'radio') ? ['Option 1', 'Option 2'] : [],
                sort_order: index,
                content: (type === 'html') ? '' : undefined,
                consent_text: (type === 'consent') ? '' : undefined,
                consent_url: (type === 'consent') ? '' : undefined,
                min: (type === 'number') ? undefined : undefined,
                max: (type === 'number') ? undefined : undefined
            };
        },

        selectField: function (index) {
            this.selectedIndex = index;
            this.refreshCanvas();
            this.refreshProperties();
        },

        removeField: function (index) {
            this.fields.splice(index, 1);
            if (this.selectedIndex === index) {
                this.selectedIndex = -1;
            } else if (this.selectedIndex > index) {
                this.selectedIndex--;
            }
            this.refreshCanvas();
            this.refreshProperties();
            this.refreshCanvasCount();
        },

        updateFieldProp: function (prop, el) {
            if (this.selectedIndex < 0 || this.selectedIndex >= this.fields.length) return;
            var field = this.fields[this.selectedIndex];

            if (prop === 'required') {
                field.required = el.checked;
            } else if (prop === 'min' || prop === 'max') {
                field[prop] = el.value !== '' ? parseFloat(el.value) : undefined;
            } else {
                field[prop] = el.value;
            }

            // Update canvas card labels in real-time
            this.refreshCanvasCard(this.selectedIndex);
        },

        addOption: function () {
            if (this.selectedIndex < 0) return;
            var field = this.fields[this.selectedIndex];
            if (!field.options) field.options = [];
            field.options.push('Option ' + (field.options.length + 1));
            this.refreshProperties();
        },

        removeOption: function (optIndex) {
            if (this.selectedIndex < 0) return;
            var field = this.fields[this.selectedIndex];
            if (field.options) {
                field.options.splice(optIndex, 1);
                this.refreshProperties();
            }
        },

        /* =================================================================
           Partial Refreshes (avoid full re-render)
           ================================================================= */
        refreshCanvas: function () {
            var canvasBody = document.getElementById('fb-canvas-body');
            if (!canvasBody) return;

            var html = '';
            if (this.fields.length === 0) {
                html = '<div class="wahrb-fb-canvas-empty">';
                html += '<div class="wahrb-fb-canvas-empty-icon">📋</div>';
                html += this.__('dragFieldsHere', 'Drag fields here from the palette');
                html += '</div>';
            } else {
                for (var i = 0; i < this.fields.length; i++) {
                    html += this.renderFieldCard(i);
                }
            }
            canvasBody.innerHTML = html;

            // Re-init sortable on canvas (because innerHTML replaced children)
            this.initCanvasSortable();
        },

        refreshProperties: function () {
            var propsContainer = this.root.querySelector('.wahrb-fb-properties');
            if (!propsContainer) return;

            var html = '<div class="wahrb-fb-properties-header">';
            html += '<h3>' + this.__('fieldProperties', 'Field Properties') + '</h3>';
            html += '</div>';

            if (this.selectedIndex < 0 || this.selectedIndex >= this.fields.length) {
                html += '<div class="wahrb-fb-properties-empty">';
                html += '<div class="wahrb-fb-properties-empty-icon">👆</div>';
                html += this.__('selectField', 'Click a field in the canvas to edit its properties');
                html += '</div>';
            } else {
                html += '<div class="wahrb-fb-properties-body" id="fb-props-body">';
                html += this.renderFieldProps(this.fields[this.selectedIndex]);
                html += '</div>';
            }

            propsContainer.innerHTML = html;
        },

        refreshCanvasCard: function (index) {
            var cards = this.root.querySelectorAll('.wahrb-fb-field');
            if (cards[index]) {
                var field = this.fields[index];
                var labelEl = cards[index].querySelector('.wahrb-fb-field-label');
                if (labelEl) labelEl.textContent = field.label || this.__('untitled', '(Untitled)');
                var reqEl = cards[index].querySelector('.wahrb-fb-field-required');
                if (field.required && !reqEl) {
                    var span = document.createElement('span');
                    span.className = 'wahrb-fb-field-required';
                    span.title = 'Required';
                    span.textContent = '*';
                    cards[index].querySelector('.wahrb-fb-field-delete').before(span);
                } else if (!field.required && reqEl) {
                    reqEl.remove();
                }
            }
        },

        refreshCanvasCount: function () {
            var countEl = this.root.querySelector('.wahrb-fb-canvas-count');
            if (countEl) {
                countEl.textContent = this.fields.length + ' ' + this.__('fields', 'fields');
            }
        },

        initCanvasSortable: function () {
            var self = this;
            var canvasEl = document.getElementById('fb-canvas-body');
            if (!canvasEl || typeof Sortable === 'undefined') return;

            // Destroy old canvas sortable
            if (this.sortableCanvas) {
                this.sortableCanvas.destroy();
            }

            this.sortableCanvas = Sortable.create(canvasEl, {
                group: { name: 'fields', pull: false, put: true },
                animation: 150,
                handle: '.wahrb-fb-field-handle',
                ghostClass: 'sortable-ghost',
                chosenClass: 'sortable-chosen',
                draggable: '.wahrb-fb-field',
                onAdd: function (evt) {
                    var paletteItem = evt.item;
                    var fieldType = paletteItem.getAttribute('data-field-type');
                    if (paletteItem.parentNode) {
                        paletteItem.parentNode.removeChild(paletteItem);
                    }
                    if (fieldType) {
                        var newField = self.createDefaultField(fieldType, evt.newIndex);
                        self.fields.splice(evt.newIndex, 0, newField);
                        self.selectedIndex = evt.newIndex;
                        self.refreshCanvas();
                        self.refreshProperties();
                        self.refreshCanvasCount();
                    }
                },
                onEnd: function (evt) {
                    if (evt.oldIndex !== evt.newIndex && evt.oldIndex !== undefined && evt.newIndex !== undefined) {
                        var item = self.fields.splice(evt.oldIndex, 1)[0];
                        self.fields.splice(evt.newIndex, 0, item);
                        if (self.selectedIndex === evt.oldIndex) {
                            self.selectedIndex = evt.newIndex;
                        } else if (self.selectedIndex > evt.oldIndex && self.selectedIndex <= evt.newIndex) {
                            self.selectedIndex--;
                        } else if (self.selectedIndex < evt.oldIndex && self.selectedIndex >= evt.newIndex) {
                            self.selectedIndex++;
                        }
                        self.refreshCanvas();
                    }
                }
            });
        },

        /* =================================================================
           Save Template
           ================================================================= */
        saveTemplate: function () {
            var self = this;
            if (this.saving) return;

            // Gather metadata from form
            var name = (document.getElementById('fb-meta-name') || {}).value || '';
            var desc = (document.getElementById('fb-meta-desc') || {}).value || '';
            var scope = (document.getElementById('fb-meta-scope') || {}).value || 'global';
            var catSlug = (document.getElementById('fb-meta-category') || {}).value || '';
            var productId = parseInt((document.getElementById('fb-meta-product-id') || {}).value, 10) || 0;
            var isActive = (document.getElementById('fb-meta-active') || {}).checked;

            // Validate
            if (!name.trim()) {
                this.showNotice('error', this.__('nameRequired', 'Template name is required.'));
                return;
            }
            if (this.fields.length === 0) {
                this.showNotice('error', this.__('fieldsRequired', 'Add at least one field.'));
                return;
            }

            // Prepare fields with sort_order
            var fields = this.fields.map(function (f, i) {
                var clean = {
                    field_key: f.field_key,
                    label: f.label || '',
                    type: f.type,
                    width: f.width || 'full',
                    required: !!f.required,
                    placeholder: f.placeholder || '',
                    'default': f['default'] || '',
                    options: f.options || [],
                    sort_order: i
                };
                if (f.type === 'html') clean.content = f.content || '';
                if (f.type === 'consent') {
                    clean.consent_text = f.consent_text || '';
                    clean.consent_url = f.consent_url || '';
                }
                if (f.type === 'number') {
                    if (f.min !== undefined) clean.min = f.min;
                    if (f.max !== undefined) clean.max = f.max;
                }
                return clean;
            });

            var data = {
                template_name: name.trim(),
                description: desc.trim(),
                scope: scope,
                category_slug: (scope === 'category' || scope === 'vendor') ? catSlug : '',
                product_id: (scope === 'product') ? productId : 0,
                fields: fields,
                is_active: isActive
            };

            // Vendor scope → set vendor_id
            if (scope === 'vendor' && this.config.vendorId) {
                data.vendor_id = parseInt(this.config.vendorId, 10);
            }

            this.saving = true;
            var url, method;
            if (this.currentTemplate && this.currentTemplate.template_id) {
                url = this.getApiBase() + '/' + this.currentTemplate.template_id;
                method = 'PUT';
            } else {
                url = this.getApiBase();
                method = 'POST';
            }

            this.api(url, method, data)
                .then(function (resp) {
                    self.saving = false;
                    // Update currentTemplate with response data
                    if (resp.data && resp.data.template_id) {
                        self.currentTemplate = resp.data;
                    } else if (resp.template_id) {
                        self.currentTemplate = resp;
                    } else if (!self.currentTemplate && method === 'POST') {
                        // For POST, go back to list
                        self.view = 'list';
                        self.loadTemplates();
                        return;
                    }
                    self.showNotice('success', self.__('templateSaved', 'Template saved successfully.'));
                })
                .catch(function (err) {
                    self.saving = false;
                    self.showNotice('error', err.message);
                });
        },

        /* =================================================================
           Notices
           ================================================================= */
        showNotice: function (type, message) {
            // Remove existing notices
            var existing = this.root.querySelectorAll('.wahrb-fb-notice');
            existing.forEach(function (el) { el.remove(); });

            var notice = document.createElement('div');
            notice.className = 'wahrb-fb-notice wahrb-fb-notice-' + type;
            notice.innerHTML = '<span>' + (type === 'success' ? '✓' : type === 'error' ? '✕' : 'ℹ') + '</span> ' + this.esc(message);

            // Insert after toolbar
            var toolbar = this.root.querySelector('.wahrb-fb-toolbar');
            if (toolbar && toolbar.nextSibling) {
                toolbar.parentNode.insertBefore(notice, toolbar.nextSibling);
            } else {
                this.root.prepend(notice);
            }

            // Auto-dismiss after 5s
            setTimeout(function () {
                if (notice.parentNode) notice.remove();
            }, 5000);
        },

        /* =================================================================
           Utilities
           ================================================================= */
        esc: function (str) {
            if (!str) return '';
            var div = document.createElement('div');
            div.textContent = String(str);
            return div.innerHTML;
        },

        scopeLabel: function (scope) {
            var labels = {
                global: this.__('scopeGlobal', 'Global'),
                category: this.__('scopeCategory', 'Category'),
                product: this.__('scopeProduct', 'Product'),
                vendor: this.__('scopeVendor', 'Vendor')
            };
            return labels[scope] || scope;
        }
    };

    /* ===================================================================
       Auto-init on DOMContentLoaded
       =================================================================== */
    document.addEventListener('DOMContentLoaded', function () {
        if (document.getElementById('wahrb-form-builder-root')) {
            WAHRBFormBuilder.init();
        }
    });

})();
