(function() {
    'use strict';

    window.IDVE = window.IDVE || {};

    // ── State ──
    IDVE.state = {
        tree: { sections: [] },
        selectedId: null,
        selectedType: null,
        dirty: false
    };

    // ── Column Presets ──
    var PRESETS = [
        { label: '1 Column', columns: ['1/1'] },
        { label: '2 Equal', columns: ['1/2', '1/2'] },
        { label: 'Left Sidebar', columns: ['1/3', '2/3'] },
        { label: 'Right Sidebar', columns: ['2/3', '1/3'] },
        { label: '3 Equal', columns: ['1/3', '1/3', '1/3'] },
        { label: '4 Equal', columns: ['1/4', '1/4', '1/4', '1/4'] },
        { label: 'Narrow-Wide-Narrow', columns: ['1/4', '1/2', '1/4'] }
    ];

    // ── Width fractions to percentages ──
    var WIDTH_MAP = {
        '1/1': 100, '1/2': 50, '1/3': 33.333, '2/3': 66.667,
        '1/4': 25, '3/4': 75, '1/5': 20, '2/5': 40, '3/5': 60, '4/5': 80
    };

    // ── Editor ──
    IDVE.Editor = {
        container: null,
        canvas: null,
        autosaveTimer: null,

        init: function() {
            this.container = document.getElementById('idve-editor');
            if (!this.container) return;

            if (!idveData.isActive) {
                // Assets loaded but editor not active yet — wait for toggle
                return;
            }

            this.activate();
        },

        activate: function() {
            if (this._activated) return;
            this._activated = true;

            this.container = document.getElementById('idve-editor');
            if (!this.container) return;

            this.buildChrome();
            IDVE.History.init();
            IDVE.RichText.init();
            IDVE.DragDrop.init();
            IDVE.Panel.init();

            this.load();
            this.bindKeyboard();
            this.startAutosave();
        },

        // ── Build editor shell ──
        buildChrome: function() {
            // Detect WP publish button label
            var wpPublishBtn = document.getElementById('publish');
            var publishLabel = wpPublishBtn ? (wpPublishBtn.value || 'Update') : 'Update';

            this.container.innerHTML =
                '<div id="idve-toolbar">' +
                    '<img src="' + idveData.logoUrl + '" alt="ID Visual Editor" class="idve-toolbar-logo" />' +
                    '<button type="button" class="idve-btn" id="idve-add-section">+ Section</button>' +
                    '<button type="button" class="idve-btn" id="idve-undo" disabled>Undo</button>' +
                    '<button type="button" class="idve-btn" id="idve-redo" disabled>Redo</button>' +
                    '<div class="idve-toolbar-spacer"></div>' +
                    '<button type="button" class="idve-btn" id="idve-global-styles">Global Styles</button>' +
                    '<span id="idve-unsaved-warning">Unsaved changes &mdash; save before updating</span>' +
                    '<button type="button" class="idve-btn idve-btn-primary" id="idve-save">Save</button>' +
                    '<button type="button" class="idve-btn idve-btn-publish" id="idve-publish">' + publishLabel + '</button>' +
                '</div>' +
                '<div id="idve-canvas"></div>';

            this.canvas = document.getElementById('idve-canvas');

            // Canvas events (bind once — delegation handles dynamic content)
            this.bindCanvasEvents();

            // Toolbar events
            document.getElementById('idve-add-section').addEventListener('click', this.showPresetPicker.bind(this));
            document.getElementById('idve-undo').addEventListener('click', function() { IDVE.History.undo(); });
            document.getElementById('idve-redo').addEventListener('click', function() { IDVE.History.redo(); });
            document.getElementById('idve-save').addEventListener('click', this.save.bind(this));
            document.getElementById('idve-publish').addEventListener('click', this.publish.bind(this));
            document.getElementById('idve-global-styles').addEventListener('click', this.showGlobalStylesEditor.bind(this));
        },

        // ── Generate ID ──
        generateId: function(prefix) {
            return prefix + '_' + Math.random().toString(16).substr(2, 8);
        },

        // ── Recursive block search helper ──
        _findInBlocks: function(blocks, id) {
            for (var b = 0; b < blocks.length; b++) {
                if (blocks[b].id === id) return { element: blocks[b], parent: blocks, index: b, type: 'block' };
                // Search group children
                if (blocks[b].type === 'group' && blocks[b].blocks) {
                    var found = this._findInBlocks(blocks[b].blocks, id);
                    if (found) return found;
                }
            }
            return null;
        },

        // ── Find element in tree by ID ──
        findElement: function(id) {
            var tree = IDVE.state.tree;
            for (var s = 0; s < tree.sections.length; s++) {
                var sec = tree.sections[s];
                if (sec.id === id) return { element: sec, parent: tree.sections, index: s, type: 'section' };
                var rows = sec.rows || [];
                for (var r = 0; r < rows.length; r++) {
                    var row = rows[r];
                    if (row.id === id) return { element: row, parent: rows, index: r, type: 'row' };
                    var cols = row.columns || [];
                    for (var c = 0; c < cols.length; c++) {
                        var col = cols[c];
                        if (col.id === id) return { element: col, parent: cols, index: c, type: 'column' };
                        var blockResult = this._findInBlocks(col.blocks || [], id);
                        if (blockResult) return blockResult;
                    }
                }
            }
            return null;
        },

        // ── Recursive search helper for blocks ──
        _searchBlocksForChild: function(blocks, childId) {
            for (var b = 0; b < blocks.length; b++) {
                if (blocks[b].id === childId) return true;
                if (blocks[b].type === 'group' && blocks[b].blocks) {
                    if (this._searchBlocksForChild(blocks[b].blocks, childId)) return true;
                }
            }
            return false;
        },

        // ── Find the parent row of a column or block ──
        findParentRow: function(childId) {
            var tree = IDVE.state.tree;
            for (var s = 0; s < tree.sections.length; s++) {
                var rows = tree.sections[s].rows || [];
                for (var r = 0; r < rows.length; r++) {
                    var cols = rows[r].columns || [];
                    for (var c = 0; c < cols.length; c++) {
                        if (cols[c].id === childId) return rows[r];
                        if (this._searchBlocksForChild(cols[c].blocks || [], childId)) return rows[r];
                    }
                }
            }
            return null;
        },

        markDirty: function() {
            IDVE.state.dirty = true;
            var warning = document.getElementById('idve-unsaved-warning');
            if (warning) warning.style.display = 'inline-block';
        },

        clearSelection: function() {
            IDVE.state.selectedId = null;
            IDVE.state.selectedType = null;
            var selected = this.canvas.querySelectorAll('.idve-selected');
            for (var i = 0; i < selected.length; i++) {
                selected[i].classList.remove('idve-selected');
            }
        },

        selectElement: function(id, type) {
            this.clearSelection();
            IDVE.state.selectedId = id;
            IDVE.state.selectedType = type;
            var el = this.canvas.querySelector('[data-id="' + id + '"]');
            if (el) el.classList.add('idve-selected');
            IDVE.Panel.openModal(type, id);
        },

        // ── Render the entire canvas ──
        renderCanvas: function() {
            var tree = IDVE.state.tree;
            var html = '';

            for (var s = 0; s < tree.sections.length; s++) {
                html += this.renderSection(tree.sections[s], s);
            }

            html += '<button type="button" class="idve-add-section-btn" id="idve-add-section-bottom">+ Add Section</button>';
            this.canvas.innerHTML = html;

            // Re-init drag drop
            IDVE.DragDrop.init();

            // Restore selection
            if (IDVE.state.selectedId) {
                var el = this.canvas.querySelector('[data-id="' + IDVE.state.selectedId + '"]');
                if (el) el.classList.add('idve-selected');
            }
        },

        renderSection: function(section, index) {
            var s = section.settings || {};
            this._collapsedSections = this._collapsedSections || {};
            var isCollapsed = !!this._collapsedSections[section.id];
            var cls = 'idve-editor-section' + (isCollapsed ? ' idve-section-collapsed' : '');
            var html = '<div class="' + cls + '" data-id="' + section.id + '">';
            html += '<div class="idve-editor-section-header">';
            html += '<span class="idve-drag-handle" draggable="true">&#9776;</span>';
            html += '<span class="idve-label">Section</span>';
            html += '<div class="idve-actions">';
            html += '<button type="button" class="idve-action-btn idve-settings-btn" data-action="settings" title="Section Settings">&#9881;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="move-up" title="Move Up">&#8593;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="move-down" title="Move Down">&#8595;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="duplicate" title="Duplicate">&#10697;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="delete" title="Delete">&times;</button>';
            html += '</div>';
            html += '<button type="button" class="idve-collapse-btn" data-action="collapse" title="' + (isCollapsed ? 'Expand' : 'Collapse') + '">&#9654;</button>';
            html += '</div>';

            html += '<div class="idve-section-body" style="' + (isCollapsed ? 'display:none' : '') + '">';
            var rows = section.rows || [];
            for (var r = 0; r < rows.length; r++) {
                html += this.renderRow(rows[r]);
            }
            html += '<button type="button" class="idve-add-row-btn" data-section="' + section.id + '">+ Add Row</button>';
            html += '</div>';

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

        renderRow: function(row) {
            var cols = row.columns || [];

            // Check if columns add up to 1
            var total = 0;
            for (var i = 0; i < cols.length; i++) {
                total += (WIDTH_MAP[cols[i].width] || 100) / 100;
            }
            var warning = '';
            if (cols.length > 0 && Math.abs(total - 1) > 0.01) {
                warning = '<div class="idve-width-warning">Column widths don\'t add up to 100% (currently ' + Math.round(total * 100) + '%)</div>';
            }

            var html = '<div class="idve-editor-row" data-id="' + row.id + '">';
            html += '<div class="idve-editor-row-header">';
            html += '<span class="idve-drag-handle" draggable="true">&#9776;</span>';
            html += '<span class="idve-label">Row</span>';
            html += '<div class="idve-actions">';
            html += '<button type="button" class="idve-action-btn idve-settings-btn" data-action="settings" title="Row Settings">&#9881;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="move-up" title="Move Up">&#8593;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="move-down" title="Move Down">&#8595;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="duplicate" title="Duplicate">&#10697;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="delete" title="Delete">&times;</button>';
            html += '</div></div>';
            if (warning) html += warning;

            html += '<div class="idve-editor-row-content">';
            for (var c = 0; c < cols.length; c++) {
                html += this.renderColumn(cols[c]);
            }
            html += '</div>';

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

        renderColumn: function(col) {
            var pct = WIDTH_MAP[col.width] || 100;
            var html = '<div class="idve-editor-column" data-id="' + col.id + '" data-width="' + col.width + '" style="flex:0 1 ' + pct + '%;min-width:0">';
            html += '<div class="idve-editor-column-header">';
            html += '<span class="idve-drag-handle" draggable="true">&#9776;</span>';
            html += '<span class="idve-label">' + col.width + '</span>';
            html += '<div class="idve-actions">';
            html += '<button type="button" class="idve-action-btn idve-settings-btn" data-action="settings" title="Column Settings">&#9881;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="delete" title="Delete Column">&times;</button>';
            html += '</div>';
            html += '</div>';

            var blocks = col.blocks || [];
            for (var b = 0; b < blocks.length; b++) {
                html += this.renderBlock(blocks[b]);
            }

            html += '<button type="button" class="idve-add-block-btn" data-column="' + col.id + '">+ Add Block</button>';
            html += '</div>';
            return html;
        },

        renderBlock: function(block) {
            var visible = block.settings && block.settings.visible !== false;
            var cls = 'idve-editor-block' + (!visible ? ' idve-hidden' : '');
            var label = block.type;
            var blockDef = IDVE.Blocks.get(block.type);
            if (blockDef) label = blockDef.label;

            var html = '<div class="' + cls + '" data-id="' + block.id + '" data-type="' + block.type + '">';
            html += '<div class="idve-editor-block-header">';
            html += '<span class="idve-drag-handle" draggable="true">&#9776;</span>';
            html += '<span class="idve-label">' + label + '</span>';
            html += '<div class="idve-actions">';
            html += '<button type="button" class="idve-action-btn idve-settings-btn" data-action="settings" title="Settings">&#9881;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="duplicate" title="Duplicate">&#10697;</button>';
            html += '<button type="button" class="idve-action-btn" data-action="delete" title="Delete">&times;</button>';
            html += '</div></div>';

            if (block.type === 'group') {
                html += '<div class="idve-editor-group-content">';
                var children = block.blocks || [];
                for (var i = 0; i < children.length; i++) {
                    html += this.renderBlock(children[i]);
                }
                html += '<button type="button" class="idve-add-block-btn" data-column="' + block.id + '">+ Add Block</button>';
                html += '</div>';
            } else {
                html += '<div class="idve-editor-block-content">';
                html += IDVE.Blocks.renderPreview(block.type, block.data || {});
                html += '</div>';
            }

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

        // ── Bind canvas events (delegation) ──
        bindCanvasEvents: function() {
            var self = this;
            var canvas = this.canvas;

            canvas.addEventListener('click', function(e) {
                // Collapse/expand section
                var collapseBtn = e.target.closest('.idve-collapse-btn');
                if (collapseBtn) {
                    var sectionEl = collapseBtn.closest('.idve-editor-section');
                    if (sectionEl) {
                        self.handleAction('collapse', sectionEl.getAttribute('data-id'));
                    }
                    return;
                }

                // Add section bottom
                if (e.target.id === 'idve-add-section-bottom') {
                    self.showPresetPicker();
                    return;
                }

                // Add row button
                var addRowBtn = e.target.closest('.idve-add-row-btn');
                if (addRowBtn) {
                    var sectionId = addRowBtn.getAttribute('data-section');
                    self.showPresetPickerForSection(sectionId);
                    return;
                }

                // Add block button
                var addBlockBtn = e.target.closest('.idve-add-block-btn');
                if (addBlockBtn) {
                    var colId = addBlockBtn.getAttribute('data-column');
                    self.showBlockPicker(colId);
                    return;
                }

                // Settings gear icon (on any element)
                var settingsBtn = e.target.closest('.idve-settings-btn');
                if (settingsBtn) {
                    var parentEl = settingsBtn.closest('[data-id]');
                    if (parentEl) {
                        var elId = parentEl.getAttribute('data-id');
                        var found = self.findElement(elId);
                        if (found) {
                            self.selectElement(elId, found.type);
                        }
                    }
                    return;
                }

                // Action buttons (move, duplicate, delete)
                var actionBtn = e.target.closest('.idve-action-btn');
                if (actionBtn) {
                    var action = actionBtn.getAttribute('data-action');
                    var parent = actionBtn.closest('[data-id]');
                    if (parent) {
                        var id = parent.getAttribute('data-id');
                        self.handleAction(action, id);
                    }
                    return;
                }

                // Select block (click anywhere on block)
                var blockEl = e.target.closest('.idve-editor-block');
                if (blockEl) {
                    e.stopPropagation();
                    self.selectElement(blockEl.getAttribute('data-id'), 'block');
                    return;
                }
            });

            // Double-click for rich text editing
            canvas.addEventListener('dblclick', function(e) {
                var blockContent = e.target.closest('.idve-editor-block-content');
                if (!blockContent) return;
                var blockEl = blockContent.closest('.idve-editor-block');
                if (!blockEl) return;
                var type = blockEl.getAttribute('data-type');
                if (type !== 'text' && type !== 'heading') return;

                var blockId = blockEl.getAttribute('data-id');
                var found = self.findElement(blockId);
                if (!found) return;

                IDVE.RichText.activate(blockContent, function(newContent) {
                    IDVE.History.push();
                    found.element.data.content = newContent;
                    self.markDirty();
                });
            });
        },

        // ── Action Handler ──
        handleAction: function(action, id) {
            var found = this.findElement(id);
            if (!found) return;

            switch (action) {
                case 'collapse':
                    this._collapsedSections = this._collapsedSections || {};
                    this._collapsedSections[id] = !this._collapsedSections[id];
                    this.renderCanvas();
                    return; // UI-only — no history push, no dirty

                case 'delete':
                    // Guard: if deleting the last column in a row, delete the row instead
                    if (found.type === 'column' && found.parent.length === 1) {
                        if (!confirm('This is the only column in this row. Delete the entire row?')) return;
                        var parentRow = this.findParentRow(id);
                        if (parentRow) {
                            var rowFound = this.findElement(parentRow.id);
                            if (rowFound) {
                                IDVE.History.push();
                                rowFound.parent.splice(rowFound.index, 1);
                                if (IDVE.state.selectedId === id) IDVE.Panel.close();
                                break;
                            }
                        }
                        return;
                    }
                    IDVE.History.push();
                    found.parent.splice(found.index, 1);
                    if (IDVE.state.selectedId === id) {
                        IDVE.Panel.close();
                    }
                    break;

                case 'duplicate':
                    IDVE.History.push();
                    var clone = JSON.parse(JSON.stringify(found.element));
                    this.regenerateIds(clone);
                    found.parent.splice(found.index + 1, 0, clone);
                    break;

                case 'move-up':
                    if (found.index > 0) {
                        IDVE.History.push();
                        var item = found.parent.splice(found.index, 1)[0];
                        found.parent.splice(found.index - 1, 0, item);
                    }
                    break;

                case 'move-down':
                    if (found.index < found.parent.length - 1) {
                        IDVE.History.push();
                        var item2 = found.parent.splice(found.index, 1)[0];
                        found.parent.splice(found.index + 1, 0, item2);
                    }
                    break;
            }

            this.renderCanvas();
            this.markDirty();
        },

        regenerateIds: function(obj) {
            if (obj.id) {
                var prefix = obj.id.split('_').slice(0, 2).join('_');
                obj.id = this.generateId(prefix);
            }
            if (obj.rows) {
                for (var r = 0; r < obj.rows.length; r++) {
                    this.regenerateIds(obj.rows[r]);
                    var cols = obj.rows[r].columns || [];
                    for (var c = 0; c < cols.length; c++) {
                        this.regenerateIds(cols[c]);
                        var blocks = cols[c].blocks || [];
                        for (var b = 0; b < blocks.length; b++) {
                            this.regenerateIds(blocks[b]);
                        }
                    }
                }
            }
            if (obj.columns) {
                for (var c2 = 0; c2 < obj.columns.length; c2++) {
                    this.regenerateIds(obj.columns[c2]);
                    var blocks2 = obj.columns[c2].blocks || [];
                    for (var b2 = 0; b2 < blocks2.length; b2++) {
                        this.regenerateIds(blocks2[b2]);
                    }
                }
            }
            // Recurse into group block children
            if (obj.type && obj.blocks) {
                for (var g = 0; g < obj.blocks.length; g++) {
                    this.regenerateIds(obj.blocks[g]);
                }
            }
        },

        // ── Add Section (Preset Picker) ──
        showPresetPicker: function() {
            var self = this;
            var overlay = document.createElement('div');
            overlay.className = 'idve-modal-overlay';
            var html = '<div class="idve-modal"><div class="idve-modal-header"><h3>Choose a Layout</h3><button type="button" class="idve-modal-close">&times;</button></div><div class="idve-modal-body"><div class="idve-preset-picker">';

            for (var i = 0; i < PRESETS.length; i++) {
                var p = PRESETS[i];
                html += '<div class="idve-preset-item" data-preset="' + i + '">';
                html += '<div class="idve-preset-visual">';
                for (var j = 0; j < p.columns.length; j++) {
                    var w = WIDTH_MAP[p.columns[j]] || 100;
                    html += '<div class="idve-preset-col" style="flex:0 0 ' + w + '%"></div>';
                }
                html += '</div><div class="idve-preset-label">' + p.label + '</div></div>';
            }

            html += '</div></div></div>';
            overlay.innerHTML = html;
            document.body.appendChild(overlay);

            overlay.querySelector('.idve-modal-close').addEventListener('click', function() {
                document.body.removeChild(overlay);
            });
            overlay.addEventListener('click', function(e) {
                if (e.target === overlay) document.body.removeChild(overlay);
                var item = e.target.closest('.idve-preset-item');
                if (item) {
                    var idx = parseInt(item.getAttribute('data-preset'));
                    self.addSection(PRESETS[idx].columns);
                    document.body.removeChild(overlay);
                }
            });
        },

        addSection: function(columnWidths) {
            IDVE.History.push();
            var columns = [];
            for (var i = 0; i < columnWidths.length; i++) {
                columns.push({
                    id: this.generateId('idve_col'),
                    width: columnWidths[i],
                    settings: { padding: {top:0,right:0,bottom:0,left:0}, margin: {top:0,right:0,bottom:0,left:0}, backgroundColor: '', verticalAlign: 'top', border: {width:{top:0,right:0,bottom:0,left:0},color:'#000000',style:'solid',radius:{topLeft:0,topRight:0,bottomRight:0,bottomLeft:0}} },
                    blocks: []
                });
            }
            var section = {
                id: this.generateId('idve_sec'),
                settings: {
                    backgroundColor: '', backgroundImage: '',
                    padding: {top:0,right:0,bottom:0,left:0},
                    margin: {top:0,right:0,bottom:0,left:0},
                    border: {width:{top:0,right:0,bottom:0,left:0},color:'#000000',style:'solid',radius:{topLeft:0,topRight:0,bottomRight:0,bottomLeft:0}},
                    maxWidth: '', cssClass: '', cssId: '',
                    stretch: 'default', contentMaxWidth: ''
                },
                rows: [{
                    id: this.generateId('idve_row'),
                    settings: {
                        backgroundColor: '',
                        padding: {top:0,right:0,bottom:0,left:0},
                        margin: {top:0,right:0,bottom:0,left:0},
                        border: {width:{top:0,right:0,bottom:0,left:0},color:'#000000',style:'solid',radius:{topLeft:0,topRight:0,bottomRight:0,bottomLeft:0}},
                        equalHeight: false,
                        gap: ''
                    },
                    columns: columns
                }]
            };
            IDVE.state.tree.sections.push(section);
            this.renderCanvas();
            this.markDirty();
        },

        // ── Add Row to Section (Preset Picker) ──
        showPresetPickerForSection: function(sectionId) {
            var self = this;
            var overlay = document.createElement('div');
            overlay.className = 'idve-modal-overlay';
            var html = '<div class="idve-modal"><div class="idve-modal-header"><h3>Choose a Row Layout</h3><button type="button" class="idve-modal-close">&times;</button></div><div class="idve-modal-body"><div class="idve-preset-picker">';

            for (var i = 0; i < PRESETS.length; i++) {
                var p = PRESETS[i];
                html += '<div class="idve-preset-item" data-preset="' + i + '">';
                html += '<div class="idve-preset-visual">';
                for (var j = 0; j < p.columns.length; j++) {
                    var w = WIDTH_MAP[p.columns[j]] || 100;
                    html += '<div class="idve-preset-col" style="flex:0 0 ' + w + '%"></div>';
                }
                html += '</div><div class="idve-preset-label">' + p.label + '</div></div>';
            }

            html += '</div></div></div>';
            overlay.innerHTML = html;
            document.body.appendChild(overlay);

            overlay.querySelector('.idve-modal-close').addEventListener('click', function() {
                document.body.removeChild(overlay);
            });
            overlay.addEventListener('click', function(e) {
                if (e.target === overlay) document.body.removeChild(overlay);
                var item = e.target.closest('.idve-preset-item');
                if (item) {
                    var idx = parseInt(item.getAttribute('data-preset'));
                    self.addRowToSection(sectionId, PRESETS[idx].columns);
                    document.body.removeChild(overlay);
                }
            });
        },

        addRowToSection: function(sectionId, columnWidths) {
            var found = this.findElement(sectionId);
            if (!found || found.type !== 'section') return;

            IDVE.History.push();
            var columns = [];
            for (var i = 0; i < columnWidths.length; i++) {
                columns.push({
                    id: this.generateId('idve_col'),
                    width: columnWidths[i],
                    settings: { padding: {top:0,right:0,bottom:0,left:0}, margin: {top:0,right:0,bottom:0,left:0}, backgroundColor: '', verticalAlign: 'top', border: {width:{top:0,right:0,bottom:0,left:0},color:'#000000',style:'solid',radius:{topLeft:0,topRight:0,bottomRight:0,bottomLeft:0}} },
                    blocks: []
                });
            }
            var row = {
                id: this.generateId('idve_row'),
                settings: {
                    backgroundColor: '',
                    padding: {top:0,right:0,bottom:0,left:0},
                    margin: {top:0,right:0,bottom:0,left:0},
                    border: {width:{top:0,right:0,bottom:0,left:0},color:'#000000',style:'solid',radius:{topLeft:0,topRight:0,bottomRight:0,bottomLeft:0}},
                    equalHeight: false,
                    gap: ''
                },
                columns: columns
            };
            if (!found.element.rows) found.element.rows = [];
            found.element.rows.push(row);
            this.renderCanvas();
            this.markDirty();
        },

        // ── Block Picker ──
        showBlockPicker: function(columnId) {
            var self = this;
            var overlay = document.createElement('div');
            overlay.className = 'idve-modal-overlay';
            var allBlocks = IDVE.Blocks.getAll();

            // Group blocks by category
            var coreOrder = ['content', 'media', 'layout'];
            var categories = {};
            for (var type in allBlocks) {
                if (!allBlocks.hasOwnProperty(type)) continue;
                var cat = allBlocks[type].category || 'content';
                if (!categories[cat]) categories[cat] = [];
                categories[cat].push({ type: type, config: allBlocks[type] });
            }

            // Build ordered list: core categories first, then others
            var orderedCats = [];
            for (var i = 0; i < coreOrder.length; i++) {
                if (categories[coreOrder[i]]) {
                    orderedCats.push(coreOrder[i]);
                }
            }
            for (var cat2 in categories) {
                if (categories.hasOwnProperty(cat2) && coreOrder.indexOf(cat2) === -1) {
                    orderedCats.push(cat2);
                }
            }

            var html = '<div class="idve-modal"><div class="idve-modal-header"><h3>Add a Block</h3><button type="button" class="idve-modal-close">&times;</button></div><div class="idve-modal-body">';

            for (var c = 0; c < orderedCats.length; c++) {
                var catName = orderedCats[c];
                var catLabel = catName.charAt(0).toUpperCase() + catName.slice(1);
                var blocks = categories[catName];

                html += '<div class="idve-block-category">';
                html += '<div class="idve-block-category-label">' + catLabel + '</div>';
                html += '<div class="idve-block-picker">';
                for (var b = 0; b < blocks.length; b++) {
                    html += '<div class="idve-block-picker-item" data-type="' + blocks[b].type + '">';
                    html += '<span class="dashicons ' + blocks[b].config.icon + '"></span>';
                    html += '<span>' + blocks[b].config.label + '</span>';
                    html += '</div>';
                }
                html += '</div></div>';
            }

            html += '</div></div>';
            overlay.innerHTML = html;
            document.body.appendChild(overlay);

            overlay.querySelector('.idve-modal-close').addEventListener('click', function() {
                document.body.removeChild(overlay);
            });
            overlay.addEventListener('click', function(e) {
                if (e.target === overlay) document.body.removeChild(overlay);
                var item = e.target.closest('.idve-block-picker-item');
                if (item) {
                    var blockType = item.getAttribute('data-type');
                    self.addBlock(columnId, blockType);
                    document.body.removeChild(overlay);
                }
            });
        },

        addBlock: function(containerId, blockType) {
            IDVE.History.push();
            var found = this.findElement(containerId);
            if (!found) return;

            // Accept columns and group blocks as containers
            var isColumn = found.type === 'column';
            var isGroup = found.type === 'block' && found.element.type === 'group';
            if (!isColumn && !isGroup) return;

            var block = {
                id: this.generateId('idve_blk'),
                type: blockType,
                data: IDVE.Blocks.getDefaultData(blockType),
                settings: IDVE.Blocks.getDefaultSettings()
            };

            // Initialize blocks array if missing (for groups)
            if (!found.element.blocks) found.element.blocks = [];
            found.element.blocks.push(block);
            this.renderCanvas();
            this.markDirty();
            this.selectElement(block.id, 'block');
        },

        // ── Global Styles Editor ──
        showGlobalStylesEditor: function() {
            var overlay = document.createElement('div');
            overlay.className = 'idve-modal-overlay';

            var html = '<div class="idve-modal idve-global-styles-modal">';
            html += '<div class="idve-modal-header">';
            html += '<h3>Global Stylesheet</h3>';
            html += '<button type="button" class="idve-modal-close">&times;</button>';
            html += '</div>';
            html += '<div class="idve-modal-body">';
            html += '<textarea id="idve-global-css-editor"></textarea>';
            html += '</div>';
            html += '<div class="idve-modal-footer">';
            html += '<button type="button" class="idve-btn idve-gs-cancel">Cancel</button>';
            html += '<button type="button" class="idve-btn idve-btn-primary idve-gs-save">Save</button>';
            html += '</div>';
            html += '</div>';

            overlay.innerHTML = html;
            document.body.appendChild(overlay);

            var cmInstance = null;
            var textarea = document.getElementById('idve-global-css-editor');

            // Load existing CSS
            fetch(idveData.restUrl + 'global-styles', {
                headers: { 'X-WP-Nonce': idveData.nonce }
            })
            .then(function(res) { return res.json(); })
            .then(function(data) {
                if (data.success && data.css) {
                    textarea.value = data.css;
                }
                // Initialize CodeMirror
                if (window.wp && wp.codeEditor && window.idveCodeEditor) {
                    cmInstance = wp.codeEditor.initialize('idve-global-css-editor', idveCodeEditor);
                }
            })
            .catch(function() {
                if (window.wp && wp.codeEditor && window.idveCodeEditor) {
                    cmInstance = wp.codeEditor.initialize('idve-global-css-editor', idveCodeEditor);
                }
            });

            function closeModal() {
                if (cmInstance && cmInstance.codemirror) {
                    cmInstance.codemirror.toTextArea();
                }
                document.body.removeChild(overlay);
            }

            overlay.querySelector('.idve-modal-close').addEventListener('click', closeModal);
            overlay.querySelector('.idve-gs-cancel').addEventListener('click', closeModal);
            overlay.addEventListener('click', function(e) {
                if (e.target === overlay) closeModal();
            });

            overlay.querySelector('.idve-gs-save').addEventListener('click', function() {
                var saveBtn = this;
                var css = cmInstance && cmInstance.codemirror ? cmInstance.codemirror.getValue() : textarea.value;
                saveBtn.textContent = 'Saving...';
                saveBtn.disabled = true;

                fetch(idveData.restUrl + 'global-styles', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-WP-Nonce': idveData.nonce
                    },
                    body: JSON.stringify({ css: css })
                })
                .then(function(res) { return res.json(); })
                .then(function(data) {
                    if (data.success) {
                        saveBtn.textContent = 'Saved';
                        setTimeout(function() { closeModal(); }, 1000);
                    } else {
                        saveBtn.textContent = 'Error';
                        setTimeout(function() { saveBtn.textContent = 'Save'; saveBtn.disabled = false; }, 2000);
                    }
                })
                .catch(function() {
                    saveBtn.textContent = 'Error';
                    setTimeout(function() { saveBtn.textContent = 'Save'; saveBtn.disabled = false; }, 2000);
                });
            });
        },

        // ── Save/Load ──
        save: function(onSuccess) {
            var self = this;
            var btn = document.getElementById('idve-save');
            var warning = document.getElementById('idve-unsaved-warning');
            btn.textContent = 'Saving...';
            btn.disabled = true;

            fetch(idveData.restUrl + 'save/' + idveData.postId, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': idveData.nonce
                },
                body: JSON.stringify({ tree: IDVE.state.tree })
            })
            .then(function(res) { return res.json(); })
            .then(function(data) {
                if (data.success) {
                    btn.textContent = 'Saved';
                    IDVE.state.dirty = false;
                    if (warning) warning.style.display = 'none';
                    if (data.css) {
                        console.log('[IDVE] Generated CSS:', data.css);
                    } else {
                        console.warn('[IDVE] No CSS was generated. Check element settings.');
                    }
                    if (typeof onSuccess === 'function') onSuccess();
                } else {
                    btn.textContent = 'Error';
                }
                setTimeout(function() { btn.textContent = 'Save'; btn.disabled = false; }, 2000);
            })
            .catch(function() {
                btn.textContent = 'Error';
                setTimeout(function() { btn.textContent = 'Save'; btn.disabled = false; }, 2000);
            });
        },

        // ── Publish / Update ──
        publish: function() {
            var self = this;
            var wpPublishBtn = document.getElementById('publish');
            if (!wpPublishBtn) return;

            function doPublish() {
                wpPublishBtn.click();
            }

            if (IDVE.state.dirty) {
                // Save IDVE changes first, then trigger WP publish
                self.save(doPublish);
            } else {
                doPublish();
            }
        },

        load: function(forceImport) {
            var self = this;
            var url = idveData.restUrl + 'load/' + idveData.postId;
            if (forceImport) url += '?force_import=1';

            fetch(url, {
                headers: { 'X-WP-Nonce': idveData.nonce }
            })
            .then(function(res) { return res.json(); })
            .then(function(data) {
                if (data.success && data.tree) {
                    IDVE.state.tree = data.tree;
                } else {
                    IDVE.state.tree = { sections: [] };
                }
                self.renderCanvas();
                IDVE.History.clear();

                if (forceImport) {
                    self.markDirty();
                } else if (data.hasDrift) {
                    self.showDriftWarning();
                }
            })
            .catch(function() {
                IDVE.state.tree = { sections: [] };
                self.renderCanvas();
            });
        },

        // ── Drift Warning Modal ──
        showDriftWarning: function() {
            var self = this;
            var overlay = document.createElement('div');
            overlay.className = 'idve-modal-overlay idve-drift-overlay';

            var html = '<div class="idve-modal idve-drift-modal">';
            html += '<div class="idve-modal-header">';
            html += '<h3>External Changes Detected</h3>';
            html += '</div>';
            html += '<div class="idve-modal-body">';
            html += '<p>The page content was modified outside of the visual editor since your last IDVE save. What would you like to do?</p>';
            html += '</div>';
            html += '<div class="idve-modal-footer">';
            html += '<button type="button" class="idve-btn idve-drift-keep">Keep IDVE Version</button>';
            html += '<button type="button" class="idve-btn idve-btn-primary idve-drift-import">Import Current Content</button>';
            html += '</div>';
            html += '</div>';

            overlay.innerHTML = html;
            document.body.appendChild(overlay);

            overlay.querySelector('.idve-drift-keep').addEventListener('click', function() {
                document.body.removeChild(overlay);
                // post_content is out of sync with the JSON tree — mark dirty so the user
                // saves (regenerating post_content and updating the content hash).
                self.markDirty();
            });

            overlay.querySelector('.idve-drift-import').addEventListener('click', function() {
                document.body.removeChild(overlay);
                self.load(true);
            });
        },

        // ── Autosave ──
        startAutosave: function() {
            var self = this;
            this.autosaveTimer = setInterval(function() {
                if (!IDVE.state.dirty) return;
                fetch(idveData.restUrl + 'autosave/' + idveData.postId, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-WP-Nonce': idveData.nonce
                    },
                    body: JSON.stringify({ tree: IDVE.state.tree })
                }).catch(function() {});
            }, 60000);
        },

        // ── Keyboard shortcuts ──
        bindKeyboard: function() {
            var self = this;
            document.addEventListener('keydown', function(e) {
                // Only handle when editor is visible
                if (!self.container || !self.container.offsetParent) return;

                if ((e.ctrlKey || e.metaKey) && e.key === 's') {
                    e.preventDefault();
                    self.save();
                }
                if ((e.ctrlKey || e.metaKey) && !e.shiftKey && e.key === 'z') {
                    e.preventDefault();
                    IDVE.History.undo();
                }
                if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'z') {
                    e.preventDefault();
                    IDVE.History.redo();
                }
                if (e.key === 'Delete' && IDVE.state.selectedId) {
                    // Don't delete if user is editing text
                    if (document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA' || document.activeElement.isContentEditable)) return;
                    e.preventDefault();
                    self.handleAction('delete', IDVE.state.selectedId);
                }
                if (e.key === 'Escape' && IDVE.Panel.isOpen) {
                    IDVE.Panel.close();
                }
            });
        }
    };

    // ── Boot ──
    document.addEventListener('DOMContentLoaded', function() {
        IDVE.Editor.init();
    });
})();
