/**
 * Configurable Options Editor
 * Handles drag-and-drop option management, clipboard, filtering,
 * AJAX CRUD, and SortableJS integration for the Paradigm theme.
 */
(function() {
    'use strict';

    // ====== Toast Notifications ======
    var toastContainer = null;

    function showToast(type, title, message) {
        if (!toastContainer) {
            toastContainer = document.createElement('div');
            toastContainer.className = 'toast-container position-fixed top-0 end-0 p-3';
            toastContainer.style.zIndex = '1080';
            document.body.appendChild(toastContainer);
        }
        var bgClass = type === 'success' ? 'text-bg-success' :
            type === 'warning' ? 'text-bg-warning' :
            type === 'info' ? 'text-bg-info' :
            'text-bg-danger';
        var toastEl = document.createElement('div');
        toastEl.className = 'toast ' + bgClass;
        toastEl.setAttribute('role', 'alert');
        toastEl.innerHTML = '<div class="d-flex"><div class="toast-body">' + escapeHtml(message || title) + '</div>' +
            '<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button></div>';
        toastContainer.appendChild(toastEl);
        var bsToast = new bootstrap.Toast(toastEl, {
            delay: 4000
        });
        bsToast.show();
        toastEl.addEventListener('hidden.bs.toast', function() {
            toastEl.remove();
        });
    }

    // ====== State ======
    var state = {
        clipboard: JSON.parse(localStorage.getItem('blesta_options_clipboard') || '[]'),
        sortableInstances: {},
        allCollapsed: false,
        reorderTimers: {},
        logicFormDirty: false
    };

    // ====== Initialization ======
    function init() {
        if (typeof blestaOptionsData === 'undefined') return;

        initializeSortable();
        initializeFilters();
        initializeCollapseAll();
        initializeEventDelegation();
        initializeImportModal();
        updateClipboardUI();
    }

    // ====== SortableJS Setup ======
    function initializeSortable() {
        if (typeof Sortable === 'undefined') return;

        var availableList = document.getElementById('availableOptionsList');
        if (availableList) {
            state.sortableInstances['available'] = new Sortable(availableList, {
                group: {
                    name: 'options',
                    pull: 'clone',
                    put: false
                },
                animation: 150,
                sort: false,
                ghostClass: 'sortable-ghost',
                chosenClass: 'sortable-chosen',
                dragClass: 'sortable-drag',
                filter: '.empty-state'
            });
        }

        // Initialize sortable for each group dropzone
        document.querySelectorAll('[data-group-dropzone]').forEach(function(dropzone) {
            var groupId = dropzone.getAttribute('data-group-dropzone');
            state.sortableInstances['group-' + groupId] = new Sortable(dropzone, {
                group: {
                    name: 'options',
                    pull: true,
                    put: true
                },
                animation: 150,
                ghostClass: 'sortable-ghost',
                chosenClass: 'sortable-chosen',
                dragClass: 'sortable-drag',
                filter: '.dropzone-empty-state',
                onAdd: function(evt) {
                    handleOptionDrop(evt, groupId);
                },
                onUpdate: function(evt) {
                    handleOptionReorder(evt, groupId);
                }
            });
        });
    }

    function handleOptionDrop(evt, groupId) {
        var optionId = evt.item.getAttribute('data-option-id');

        // Replace full card with compact card immediately (optimistic update)
        var option = getOptionById(optionId);
        if (!option) {
            evt.item.remove();
            return;
        }

        // Remove empty state if present
        var dropzone = evt.item.closest('[data-group-dropzone]');
        var emptyState = dropzone ? dropzone.querySelector('.dropzone-empty-state') : null;
        if (emptyState) emptyState.remove();

        // Replace cloned full card with compact card
        evt.item.outerHTML = renderCompactCard(option, groupId);

        // AJAX persist
        blestaRequest('POST', blestaOptionsData.baseUri + 'package_options/',
            csrfParam() + '&ajax_action=assign_option&option_id=' + encodeURIComponent(optionId) + '&group_id=' + encodeURIComponent(groupId),
            function(response) {
                var data = parseJsonResponse(response);
                if (data && data.success) {
                    updateGroupCount(groupId);
                    showToast('success', 'Success', data.message);
                } else {
                    console.warn('[OptionsEditor] Drop failed for option ' + optionId + ':', data || response);
                    var addedCard = dropzone.querySelector('[data-option-id="' + optionId + '"]');
                    if (addedCard) addedCard.remove();
                    showToast('warning', 'Warning', (data && data.message) || 'Failed to add option');
                    checkEmptyState(groupId);
                }
            },
            function(error) {
                console.warn('[OptionsEditor] Drop network error for option ' + optionId + ':', error);
                var addedCard = dropzone ? dropzone.querySelector('[data-option-id="' + optionId + '"]') : null;
                if (addedCard) addedCard.remove();
                checkEmptyState(groupId);
            }
        );
    }

    function handleOptionReorder(evt, groupId) {
        // Debounce reorder saves per group
        clearTimeout(state.reorderTimers[groupId]);
        state.reorderTimers[groupId] = setTimeout(function() {
            var dropzone = document.querySelector('[data-group-dropzone="' + groupId + '"]');
            if (!dropzone) return;
            var optionIds = [];
            dropzone.querySelectorAll('[data-option-id]').forEach(function(card) {
                optionIds.push(card.getAttribute('data-option-id'));
            });
            blestaRequest('POST', blestaOptionsData.baseUri + 'package_options/',
                csrfParam() + '&ajax_action=sort_options&group_id=' + encodeURIComponent(groupId) + '&' + optionIds.map(function(id) {
                    return 'options[]=' + encodeURIComponent(id);
                }).join('&'),
                null, null
            );
        }, 300);
    }

    // ====== Rendering Helpers ======
    function renderCompactCard(option, groupId) {
        var icon = blestaOptionsData.typeIcons[option.type] || 'bi-gear';
        return '<div class="option-card-compact" data-option-id="' + escapeHtml(String(option.id)) + '">' +
            '<div class="option-card-compact-left">' +
            '<i class="bi ' + escapeHtml(icon) + ' option-card-compact-icon"></i>' +
            '<div class="option-card-compact-info">' +
            '<div class="option-card-compact-title">' + escapeHtml(option.label) + '</div>' +
            '<div class="option-card-compact-meta"><span>' + escapeHtml(option.type) + '</span></div>' +
            '</div>' +
            '</div>' +
            '<div class="option-card-compact-right">' +
            '<div class="option-card-compact-actions">' +
            '<button class="btn btn-sm btn-outline-secondary btn-edit-option" data-option-id="' + escapeHtml(String(option.id)) + '" title="Edit"><i class="bi bi-pencil"></i></button>' +
            '</div>' +
            '<button class="btn btn-sm border-0 text-secondary btn-remove-from-group" data-option-id="' + escapeHtml(String(option.id)) + '" data-group-id="' + escapeHtml(String(groupId)) + '" title="Remove"><i class="bi bi-x-lg"></i></button>' +
            '</div>' +
            '</div>';
    }

    function getOptionById(id) {
        for (var i = 0; i < blestaOptionsData.options.length; i++) {
            if (String(blestaOptionsData.options[i].id) === String(id)) return blestaOptionsData.options[i];
        }
        return null;
    }

    function escapeHtml(str) {
        var div = document.createElement('div');
        div.appendChild(document.createTextNode(str));
        return div.innerHTML;
    }

    // ====== Filtering ======
    function initializeFilters() {
        var filterOptions = document.getElementById('filterAvailableOptions');
        var filterGroups = document.getElementById('filterGroups');

        if (filterOptions) {
            filterOptions.addEventListener('input', function() {
                var query = this.value.toLowerCase();
                document.querySelectorAll('#availableOptionsList .option-card').forEach(function(card) {
                    var title = card.querySelector('.option-card-title');
                    var matches = title && title.textContent.toLowerCase().indexOf(query) !== -1;
                    card.style.display = matches ? '' : 'none';
                });
            });
        }

        if (filterGroups) {
            filterGroups.addEventListener('input', function() {
                var query = this.value.toLowerCase();
                document.querySelectorAll('.option-group').forEach(function(group) {
                    var name = group.querySelector('.option-group-name');
                    var matches = name && name.textContent.toLowerCase().indexOf(query) !== -1;
                    group.style.display = matches ? '' : 'none';
                });
            });
        }
    }

    // ====== Group Collapse/Expand ======
    function initializeCollapseAll() {
        var btn = document.getElementById('collapseAllGroups');
        if (!btn) return;

        btn.addEventListener('click', function() {
            var headers = document.querySelectorAll('.option-group-header');
            var contents = document.querySelectorAll('.option-group-content');

            if (state.allCollapsed) {
                headers.forEach(function(h) {
                    h.classList.remove('collapsed');
                });
                contents.forEach(function(c) {
                    c.classList.remove('collapsed');
                });
                btn.innerHTML = '<i class="bi bi-arrows-collapse"></i>';
            } else {
                headers.forEach(function(h) {
                    h.classList.add('collapsed');
                });
                contents.forEach(function(c) {
                    c.classList.add('collapsed');
                });
                btn.innerHTML = '<i class="bi bi-arrows-expand"></i>';
            }
            state.allCollapsed = !state.allCollapsed;
        });
    }

    function toggleGroup(groupId) {
        var groupEl = document.querySelector('[data-group-id="' + groupId + '"]');
        if (!groupEl) return;
        var header = groupEl.querySelector('.option-group-header');
        var content = groupEl.querySelector('.option-group-content');
        if (header) header.classList.toggle('collapsed');
        if (content) content.classList.toggle('collapsed');
    }

    // ====== Clipboard ======
    function copyOption(optionId) {
        if (state.clipboard.indexOf(String(optionId)) === -1) {
            state.clipboard.push(String(optionId));
        }
        saveClipboard();
        updateClipboardUI();
        var option = getOptionById(optionId);
        if (option) {
            showToast('info', 'Copied', 'Copied "' + option.label + '" to clipboard');
        }
    }

    function parseJsonResponse(response) {
        if (typeof response === 'object' && response !== null) return response;
        try {
            return JSON.parse(response);
        } catch (e) {
            return null;
        }
    }

    function csrfParam() {
        return '_csrf_token=' + encodeURIComponent(blestaOptionsData.csrfToken || '');
    }

    function pasteToGroup(groupId) {
        if (state.clipboard.length === 0) return;

        var dropzone = document.querySelector('[data-group-dropzone="' + groupId + '"]');
        if (!dropzone) return;

        var pending = state.clipboard.slice();
        var completed = 0;
        var added = 0;
        var skipped = 0;
        var failed = 0;

        pending.forEach(function(optionId) {
            var option = getOptionById(optionId);
            if (!option) {
                completed++;
                failed++;
                checkPasteComplete(completed, pending.length, added, skipped, failed, groupId);
                return;
            }

            // Skip if already in group
            if (dropzone.querySelector('[data-option-id="' + optionId + '"]')) {
                skipped++;
                completed++;
                checkPasteComplete(completed, pending.length, added, skipped, failed, groupId);
                return;
            }

            // Remove empty state if present
            var emptyState = dropzone.querySelector('.dropzone-empty-state');
            if (emptyState) emptyState.remove();

            // Optimistic DOM update
            dropzone.insertAdjacentHTML('beforeend', renderCompactCard(option, groupId));

            // Persist via AJAX
            blestaRequest('POST', blestaOptionsData.baseUri + 'package_options/',
                csrfParam() + '&ajax_action=assign_option&option_id=' + encodeURIComponent(optionId) + '&group_id=' + encodeURIComponent(groupId),
                function(response) {
                    var data = parseJsonResponse(response);
                    if (data && data.success) {
                        added++;
                    } else if (data && data.success === false) {
                        // Server explicitly rejected (e.g. already in group)
                        console.warn('[OptionsEditor] Server rejected paste for option ' + optionId + ':', data.message || data);
                        var card = dropzone.querySelector('.option-card-compact[data-option-id="' + optionId + '"]');
                        if (card) card.remove();
                        skipped++;
                    } else {
                        // Unexpected response (HTML redirect, parse failure, etc.)
                        console.warn('[OptionsEditor] Unexpected response for option ' + optionId + ':', typeof response === 'string' ? response.substring(0, 500) : response);
                        var card = dropzone.querySelector('.option-card-compact[data-option-id="' + optionId + '"]');
                        if (card) card.remove();
                        failed++;
                    }
                    completed++;
                    checkPasteComplete(completed, pending.length, added, skipped, failed, groupId);
                },
                function(error) {
                    // Network error - rollback
                    console.warn('[OptionsEditor] Network error for option ' + optionId + ':', error);
                    var card = dropzone.querySelector('.option-card-compact[data-option-id="' + optionId + '"]');
                    if (card) card.remove();
                    failed++;
                    completed++;
                    checkPasteComplete(completed, pending.length, added, skipped, failed, groupId);
                }
            );
        });
    }

    function checkPasteComplete(completed, total, added, skipped, failed, groupId) {
        if (completed < total) return;

        updateGroupCount(groupId);
        checkEmptyState(groupId);

        if (added > 0) {
            showToast('success', 'Pasted', 'Added ' + added + ' option(s) to group');
        } else if (failed > 0) {
            showToast('error', 'Error', 'Failed to add options. Check the browser console (F12) for details.');
        } else if (skipped > 0) {
            showToast('info', 'Info', 'All options are already in this group');
        } else {
            showToast('warning', 'Warning', 'No options could be added');
        }
    }

    function clearClipboard() {
        state.clipboard = [];
        saveClipboard();
        updateClipboardUI();
    }

    function saveClipboard() {
        localStorage.setItem('blesta_options_clipboard', JSON.stringify(state.clipboard));
    }

    function updateClipboardUI() {
        var count = state.clipboard.length;
        var indicator = document.getElementById('clipboardIndicator');
        var badge = document.getElementById('clipboardBadge');

        if (indicator && badge) {
            if (count > 0) {
                badge.textContent = count;
                indicator.style.display = 'flex';
            } else {
                indicator.style.display = 'none';
            }
        }

        // Enable/disable paste buttons
        document.querySelectorAll('.paste-button').forEach(function(btn) {
            btn.disabled = count === 0;
        });

        // Highlight copied options
        document.querySelectorAll('.option-card[data-option-id]').forEach(function(card) {
            var id = card.getAttribute('data-option-id');
            if (state.clipboard.indexOf(String(id)) !== -1) {
                card.classList.add('option-copied');
            } else {
                card.classList.remove('option-copied');
            }
        });
    }

    // ====== Group Count & Empty State ======
    function updateGroupCount(groupId) {
        var groupEl = document.querySelector('[data-group-id="' + groupId + '"]');
        if (!groupEl) return;
        var dropzone = groupEl.querySelector('[data-group-dropzone]');
        var count = dropzone ? dropzone.querySelectorAll('.option-card-compact').length : 0;
        var countEl = groupEl.querySelector('.option-group-count');
        if (countEl) countEl.textContent = '(' + count + ' options)';
        if (count === 0) {
            groupEl.classList.add('empty');
        } else {
            groupEl.classList.remove('empty');
        }

        // Toggle logic button based on option count
        var logicBtn = groupEl.querySelector('.btn-open-logic');
        if (logicBtn) {
            if (count >= 2) {
                logicBtn.classList.remove('logic-disabled');
                logicBtn.setAttribute('title', 'Option Logic');
            } else {
                logicBtn.classList.add('logic-disabled');
                logicBtn.setAttribute('title', 'Option logic requires at least 2 options in this group');
            }
        }
    }

    function checkEmptyState(groupId) {
        var dropzone = document.querySelector('[data-group-dropzone="' + groupId + '"]');
        if (!dropzone) return;
        var cards = dropzone.querySelectorAll('.option-card-compact');
        if (cards.length === 0 && !dropzone.querySelector('.dropzone-empty-state')) {
            dropzone.innerHTML = '<div class="dropzone-empty-state"><i class="bi bi-inbox"></i><div>Drop options here or click Paste</div></div>';
        }
        updateGroupCount(groupId);
    }

    // ====== AJAX Operations ======
    function removeFromGroup(optionId, groupId) {
        blestaRequest('POST', blestaOptionsData.baseUri + 'package_options/remove/',
            csrfParam() + '&option_id=' + encodeURIComponent(optionId) + '&group_id=' + encodeURIComponent(groupId),
            function(response) {
                var data = parseJsonResponse(response);
                if (data && data.success) {
                    // Remove from DOM
                    var dropzone = document.querySelector('[data-group-dropzone="' + groupId + '"]');
                    if (dropzone) {
                        var card = dropzone.querySelector('[data-option-id="' + optionId + '"]');
                        if (card) card.remove();
                    }
                    checkEmptyState(groupId);
                    showToast('success', 'Removed', data.message);
                }
            }
        );
    }


    // ====== State Refresh ======
    function refreshEditorData() {
        // Full page reload for simplicity - editorData endpoint can be used for partial refresh later
        window.location.reload();
    }

    // ====== Modal Handlers ======

    /**
     * Extract .modal-submit-area from .modal-body and promote it to a
     * proper .modal-footer sibling so it matches the standard Bootstrap
     * modal pattern (header / body / footer).
     */
    function setupModalFooter(modal) {
        var body = modal.querySelector('.modal-body');
        if (!body) return;

        // Remove any footer left over from a previous load
        var existingFooter = modal.querySelector('.modal-content > .modal-footer');
        if (existingFooter) existingFooter.remove();

        var submitArea = body.querySelector('.modal-submit-area');
        if (!submitArea) return;

        // Create a proper modal-footer
        var footer = document.createElement('div');
        footer.className = 'modal-footer';

        // Move children into the footer
        while (submitArea.firstChild) {
            footer.appendChild(submitArea.firstChild);
        }

        // Link the submit button back to its form via the form attribute
        var form = body.querySelector('form[id]');
        var submitBtn = footer.querySelector('[type="submit"]');
        if (form && submitBtn) {
            submitBtn.setAttribute('form', form.id);
        }

        // Remove the now-empty placeholder
        submitArea.remove();

        // Insert footer after modal-body inside modal-content
        body.parentNode.insertBefore(footer, body.nextSibling);
    }

    function loadModalContent(modal, url) {
        var body = modal.querySelector('.modal-body');
        body.innerHTML = '<div class="text-center py-5"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div></div>';

        // Clean up any footer from a previous load
        var oldFooter = modal.querySelector('.modal-content > .modal-footer');
        if (oldFooter) oldFooter.remove();

        blestaRequest('GET', url, null, function(html) {
            body.innerHTML = html;
            // Reset modal forms flag so form submit handler is re-bound to new form elements
            modal._modalFormsInitialized = false;
            // Fix form actions - forms loaded via AJAX have empty action
            body.querySelectorAll('form').forEach(function(form) {
                if (!form.getAttribute('action')) {
                    form.setAttribute('action', url);
                }
            });
            setupModalFooter(modal);
            initializeOptionForm(modal);
            initializeModalForms(modal);
        }, function(error) {
            console.warn('[OptionsEditor] Failed to load modal content from ' + url + ':', error);
            body.innerHTML = '<div class="alert alert-danger m-3">Failed to load content. Please try again.</div>';
        });

        var bsModal = new bootstrap.Modal(modal);
        bsModal.show();
    }

    function openCreateOptionModal() {
        loadModalContent(
            document.getElementById('createOptionModal'),
            blestaOptionsData.baseUri + 'package_options/add/'
        );
    }

    function openEditOptionModal(optionId) {
        loadModalContent(
            document.getElementById('editOptionModal'),
            blestaOptionsData.baseUri + 'package_options/edit/' + encodeURIComponent(optionId) + '/'
        );
    }

    function openCreateGroupModal() {
        loadModalContent(
            document.getElementById('createGroupModal'),
            blestaOptionsData.baseUri + 'package_options/addgroup/'
        );
    }

    function openEditGroupModal(groupId) {
        loadModalContent(
            document.getElementById('editGroupModal'),
            blestaOptionsData.baseUri + 'package_options/editgroup/' + encodeURIComponent(groupId) + '/'
        );
    }


    // ====== Modal Form Initialization ======
    function initializeModalForms(modal) {
        // Guard against duplicate event handler registration (modal reopen)
        if (modal._modalFormsInitialized) return;
        modal._modalFormsInitialized = true;

        // Intercept form submission for AJAX
        modal.querySelectorAll('form').forEach(function(form) {
            form.addEventListener('submit', function(e) {
                e.preventDefault();

                // Create hidden inputs from drag-list items for form submission
                modal.querySelectorAll('.dual-select-panel:first-child .drag-list').forEach(function(list) {
                    var fieldName = list.id === 'assigned_packages' ? 'packages[]' : 'groups[]';
                    list.querySelectorAll('input[type="hidden"]').forEach(function(i) {
                        i.remove();
                    });
                    list.querySelectorAll('.drag-item').forEach(function(item) {
                        var input = document.createElement('input');
                        input.type = 'hidden';
                        input.name = fieldName;
                        input.value = item.dataset.value;
                        list.appendChild(input);
                    });
                });

                var formData = new FormData(form);

                // Include submit button value - FormData doesn't capture it.
                // The button may be in .modal-footer (outside the form) via form attr.
                var submitBtn = form.querySelector('[type="submit"]') ||
                    modal.querySelector('.modal-footer [type="submit"][form="' + form.id + '"]');
                if (submitBtn && submitBtn.name && !formData.has(submitBtn.name)) {
                    formData.append(submitBtn.name, submitBtn.value);
                }

                var action = form.getAttribute('action') || window.location.href;

                blestaRequest('POST', action, formData,
                    function(response) {
                        var data = parseJsonResponse(response);

                        if (!data) {
                            // Non-JSON response (validation error HTML), show in modal
                            modal.querySelector('.modal-body').innerHTML = response;
                            // Reset modal forms flag so form submit handler is re-bound to new form elements
                            modal._modalFormsInitialized = false;
                            setupModalFooter(modal);
                            initializeOptionForm(modal);
                            initializeModalForms(modal);
                            return;
                        }

                        if (data.success) {
                            var bsModal = bootstrap.Modal.getInstance(modal);
                            if (bsModal) bsModal.hide();
                            showToast('success', 'Success', data.message);
                            if (data.warnings && data.warnings.length) {
                                data.warnings.forEach(function(w) {
                                    showToast('warning', 'Warning', w);
                                });
                            }
                            refreshEditorData();
                        } else if (data.errors) {
                            // Show errors in the modal
                            var errorHtml = '<div class="alert alert-danger alert-dismissible fade show d-flex align-items-center" role="alert">' +
                                '<i class="bi-x-circle-fill me-3 fs-5"></i>' +
                                '<div class="flex-grow-1">';
                            for (var field in data.errors) {
                                for (var rule in data.errors[field]) {
                                    errorHtml += '<p class="m-0">' + escapeHtml(data.errors[field][rule]) + '</p>';
                                }
                            }
                            errorHtml += '</div>' +
                                '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>' +
                                '</div>';
                            var existingAlert = modal.querySelector('.alert-danger');
                            if (existingAlert) existingAlert.remove();
                            var body = modal.querySelector('.modal-body');
                            if (body) body.insertAdjacentHTML('afterbegin', errorHtml);
                        }
                    }
                );
            });
        });

        // Initialize dual-select drag and drop within modal
        (function() {
            var draggedItem = null;

            modal.querySelectorAll('.dual-select-container').forEach(function(container) {
                var leftList = container.querySelector('.dual-select-panel:first-child .drag-list');
                var rightList = container.querySelector('.dual-select-panel:last-child .drag-list');
                var moveLeftBtn = container.querySelector('.move-left');
                var moveRightBtn = container.querySelector('.move-right');

                if (!leftList || !rightList) return;

                container.querySelectorAll('.drag-item').forEach(function(item) {
                    item.addEventListener('click', function(e) {
                        e.stopPropagation();
                        if (e.ctrlKey || e.metaKey) {
                            this.classList.toggle('selected');
                        } else {
                            container.querySelectorAll('.drag-item').forEach(function(i) {
                                i.classList.remove('selected');
                            });
                            this.classList.add('selected');
                        }
                    });

                    item.addEventListener('dblclick', function(e) {
                        e.stopPropagation();
                        var currentList = this.closest('.drag-list');
                        var targetList = currentList === leftList ? rightList : leftList;
                        targetList.appendChild(this);
                        this.classList.remove('selected');
                    });

                    item.addEventListener('dragstart', function(e) {
                        draggedItem = this;
                        this.classList.add('dragging');
                        e.dataTransfer.effectAllowed = 'move';
                        e.dataTransfer.setData('text/plain', this.textContent);
                    });

                    item.addEventListener('dragend', function() {
                        this.classList.remove('dragging');
                        container.querySelectorAll('.drag-list').forEach(function(l) {
                            l.classList.remove('drag-over');
                        });
                    });
                });

                [leftList, rightList].forEach(function(list) {
                    list.addEventListener('dragover', function(e) {
                        e.preventDefault();
                        this.classList.add('drag-over');
                    });

                    list.addEventListener('dragleave', function(e) {
                        if (!this.contains(e.relatedTarget)) {
                            this.classList.remove('drag-over');
                        }
                    });

                    list.addEventListener('drop', function(e) {
                        e.preventDefault();
                        this.classList.remove('drag-over');
                        if (draggedItem && draggedItem.parentNode !== this) {
                            this.appendChild(draggedItem);
                            draggedItem.classList.remove('selected');
                            draggedItem = null;
                        }
                    });
                });

                if (moveLeftBtn) {
                    moveLeftBtn.addEventListener('click', function() {
                        rightList.querySelectorAll('.drag-item.selected').forEach(function(item) {
                            leftList.appendChild(item);
                            item.classList.remove('selected');
                        });
                    });
                }

                if (moveRightBtn) {
                    moveRightBtn.addEventListener('click', function() {
                        leftList.querySelectorAll('.drag-item.selected').forEach(function(item) {
                            rightList.appendChild(item);
                            item.classList.remove('selected');
                        });
                    });
                }
            });

            modal.addEventListener('click', function(e) {
                if (!e.target.closest('.drag-item')) {
                    modal.querySelectorAll('.drag-item.selected').forEach(function(item) {
                        item.classList.remove('selected');
                    });
                }
            });
        })();
    }

    // ====== Import Modal ======
    function initializeImportModal() {
        var dropZone = document.getElementById('importDropZone');
        var fileInput = document.getElementById('importFileInput');
        var browseBtn = document.getElementById('btnBrowseImport');
        var confirmBtn = document.getElementById('confirmImportBtn');
        var importModal = document.getElementById('importGroupModal');

        // Reset state when modal is closed
        if (importModal) {
            importModal.addEventListener('hidden.bs.modal', function() {
                importData = null;
                if (fileInput) fileInput.value = '';
                if (confirmBtn) confirmBtn.disabled = true;
                var preview = document.getElementById('importPreview');
                if (preview) preview.style.display = 'none';
                var errorsDiv = document.getElementById('importErrors');
                if (errorsDiv) errorsDiv.style.display = 'none';
            });
        }

        if (browseBtn && fileInput) {
            browseBtn.addEventListener('click', function() {
                fileInput.click();
            });
        }

        if (fileInput) {
            fileInput.addEventListener('change', function() {
                if (this.files[0]) handleImportFile(this.files[0]);
            });
        }

        if (dropZone) {
            dropZone.addEventListener('dragover', function(e) {
                e.preventDefault();
                this.style.borderColor = 'var(--bs-primary)';
            });
            dropZone.addEventListener('dragleave', function(e) {
                e.preventDefault();
                this.style.borderColor = '';
            });
            dropZone.addEventListener('drop', function(e) {
                e.preventDefault();
                this.style.borderColor = '';
                if (e.dataTransfer.files[0]) handleImportFile(e.dataTransfer.files[0]);
            });
        }

        if (confirmBtn) {
            confirmBtn.addEventListener('click', function() {
                var form = document.getElementById('importGroupForm');
                if (!form || !importData) return;

                // Apply any edits the user made to name/description
                var nameEl = document.getElementById('previewGroupName');
                var descEl = document.getElementById('previewDescription');
                if (nameEl) importData.name = nameEl.value;
                if (descEl) importData.description = descEl.value;

                // Build FormData with a Blob file (works for both browse and drag-and-drop)
                var formData = new FormData(form);
                var blob = new Blob([JSON.stringify(importData)], {
                    type: 'application/json'
                });
                formData.set('import_file', blob, 'import.json');

                blestaRequest('POST', blestaOptionsData.baseUri + 'package_options/addgroup/', formData,
                    function(response) {
                        var data = parseJsonResponse(response);

                        if (data && data.success) {
                            var modal = bootstrap.Modal.getInstance(document.getElementById('importGroupModal'));
                            if (modal) modal.hide();
                            showToast('success', 'Imported', data.message);
                            refreshEditorData();
                        } else if (data) {
                            var errorList = document.getElementById('errorList');
                            var errorsDiv = document.getElementById('importErrors');
                            if (errorList && errorsDiv && data.errors) {
                                var html = '';
                                for (var field in data.errors) {
                                    for (var rule in data.errors[field]) {
                                        html += '<li>' + escapeHtml(data.errors[field][rule]) + '</li>';
                                    }
                                }
                                errorList.innerHTML = html;
                                errorsDiv.style.display = 'block';
                            }
                        }
                    }
                );
            });
        }
    }

    // Stores the parsed import JSON so we can rebuild a file Blob on submit
    var importData = null;

    function handleImportFile(file) {
        if (!file.name.endsWith('.json')) {
            showImportErrors(['Only JSON files are supported']);
            return;
        }

        var reader = new FileReader();
        reader.onload = function(e) {
            try {
                var data = JSON.parse(e.target.result);
                importData = data;
                showImportPreview(data);
                var confirmBtn = document.getElementById('confirmImportBtn');
                if (confirmBtn) confirmBtn.disabled = false;
            } catch (err) {
                showImportErrors(['Invalid JSON file format']);
            }
        };
        reader.readAsText(file);
    }

    function showImportPreview(data) {
        var preview = document.getElementById('importPreview');
        var nameEl = document.getElementById('previewGroupName');
        var descEl = document.getElementById('previewDescription');
        var countEl = document.getElementById('previewOptionCount');
        var listEl = document.getElementById('previewOptionsList');

        if (!preview) return;

        if (nameEl) nameEl.value = data.name || '';
        if (descEl) descEl.value = data.description || '';
        if (countEl) countEl.textContent = (data.options || []).length;

        if (listEl) {
            listEl.innerHTML = (data.options || []).map(function(opt) {
                return '<div class="option-card" style="cursor: default;">' +
                    '<div class="option-card-left">' +
                    '<i class="bi ' + escapeHtml(blestaOptionsData.typeIcons[opt.type] || 'bi-gear') + ' option-card-icon"></i>' +
                    '<div class="option-card-info">' +
                    '<div class="option-card-title">' + escapeHtml(opt.label || '') + '</div>' +
                    '<div class="option-card-meta">' +
                    '<span>' + escapeHtml(opt.type || '') + '</span>' +
                    '</div>' +
                    '</div>' +
                    '</div>' +
                    '</div>';
            }).join('');
        }

        preview.style.display = 'block';
        var errorsDiv = document.getElementById('importErrors');
        if (errorsDiv) errorsDiv.style.display = 'none';
    }

    function showImportErrors(errors) {
        var errorList = document.getElementById('errorList');
        var errorsDiv = document.getElementById('importErrors');
        if (errorList && errorsDiv) {
            errorList.innerHTML = errors.map(function(e) {
                return '<li>' + escapeHtml(e) + '</li>';
            }).join('');
            errorsDiv.style.display = 'block';
        }
        var preview = document.getElementById('importPreview');
        if (preview) preview.style.display = 'none';
        var confirmBtn = document.getElementById('confirmImportBtn');
        if (confirmBtn) confirmBtn.disabled = true;
    }

    /**
     * Register delegated event handlers for the option form on a container.
     * These handlers use event delegation so they work with dynamically added
     * content.  They must only be registered ONCE per container element to
     * prevent duplicate actions when a modal is opened/closed multiple times.
     */
    function bindOptionFormDelegates(container) {
        if (container._optionDelegatesBound) return;
        container._optionDelegatesBound = true;

        // --- Period onetime handling (delegation) ---
        container.addEventListener('change', function(e) {
            if (!e.target.matches || !e.target.matches('select.period')) return;
            var row = e.target.closest('.price_row');
            if (!row) return;
            var term = row.querySelector('input.term');
            var rcb = row.querySelector('input.price_enable_renews');
            var rp = row.querySelector('input.price_renews');
            if (e.target.value === 'onetime') {
                if (term) {
                    term.disabled = true;
                    term.value = '';
                }
                if (rcb) {
                    rcb.disabled = true;
                    rcb.checked = false;
                }
                if (rp) {
                    rp.disabled = true;
                    rp.value = '';
                }
            } else {
                if (term) term.disabled = false;
                if (rcb) rcb.disabled = false;
                var price = row.querySelector('input.price');
                if (rp && price) rp.value = price.value;
            }
        });

        // --- Renewal price checkbox (delegation) ---
        container.addEventListener('change', function(e) {
            if (!e.target.matches || !e.target.matches('input.price_enable_renews')) return;
            var rp = e.target.closest('td') ? e.target.closest('td').querySelector('.price_renews') : null;
            if (!rp) return;
            if (e.target.checked) {
                rp.disabled = false;
            } else {
                var row = e.target.closest('.price_row');
                var period = row ? row.querySelector('.period') : null;
                if (period && period.value !== 'onetime') {
                    var price = row.querySelector('input.price');
                    if (price) rp.value = price.value;
                }
                rp.disabled = true;
            }
        });

        // --- Sync renewal price to regular price (delegation) ---
        container.addEventListener('input', function(e) {
            if (!e.target.matches || !e.target.matches('input.price')) return;
            var row = e.target.closest('.price_row');
            if (!row) return;
            var rcb = row.querySelector('.price_enable_renews');
            var rp = row.querySelector('.price_renews');
            var period = row.querySelector('.period');
            if (rcb && !rcb.checked && period && period.value !== 'onetime' && rp) {
                rp.value = e.target.value;
            }
        });

        // --- Add option row (delegation) ---
        container.addEventListener('click', function(e) {
            if (!e.target.closest('.option-row-add')) return;
            e.preventDefault();
            var optionTable = container.querySelector('.option_table');
            if (!optionTable) return;
            var firstRow = optionTable.querySelector('tr.option_row');
            if (!firstRow) return;
            var firstExpand = firstRow.nextElementSibling;
            if (!firstExpand || !firstExpand.classList.contains('collapse')) return;

            var newRow = firstRow.cloneNode(true);
            var newExpand = firstExpand.cloneNode(true);

            // Keep only first price row
            var prows = newExpand.querySelectorAll('tr.price_row');
            for (var p = 1; p < prows.length; p++) prows[p].remove();

            // Clear text inputs, respecting disable_pricing state
            var disablePricingCb = container.querySelector('#disable_pricing');
            var pricingDisabled = disablePricingCb && disablePricingCb.checked;
            newRow.querySelectorAll('input[type="text"]').forEach(function(el) {
                el.value = '';
            });
            newExpand.querySelectorAll('input[type="text"]').forEach(function(el) {
                el.value = '';
                if (pricingDisabled && (el.classList.contains('price') || el.classList.contains('setup_fee') || el.classList.contains('price_renews'))) {
                    el.disabled = true;
                } else {
                    el.disabled = false;
                }
            });

            // Clear IDs (edit form)
            newRow.querySelectorAll('input.option_value_id').forEach(function(el) {
                el.value = '';
            });
            newExpand.querySelectorAll('input.value_price_id').forEach(function(el) {
                el.value = '';
            });

            // Clear image fields for new row
            newRow.querySelectorAll('.option-value-existing-image').forEach(function(el) {
                el.value = '';
            });
            newRow.querySelectorAll('.option-value-remove-image').forEach(function(el) {
                el.value = '0';
            });
            newRow.querySelectorAll('.option-value-image-input').forEach(function(el) {
                el.value = '';
            });
            newRow.querySelectorAll('.option-value-thumb').forEach(function(el) {
                el.remove();
            });
            newRow.querySelectorAll('.option-value-image-remove').forEach(function(el) {
                el.remove();
            });

            // Handle onetime period
            var ps = newExpand.querySelector('select.period');
            if (ps && ps.value === 'onetime') {
                var t = newExpand.querySelector('input.term');
                if (t) t.disabled = true;
                var rc = newExpand.querySelector('input.price_enable_renews');
                if (rc) rc.disabled = true;
            }

            // Disable renewal price
            newExpand.querySelectorAll('input.price_renews').forEach(function(el) {
                el.disabled = true;
            });
            newExpand.querySelectorAll('input.price_enable_renews').forEach(function(el) {
                el.checked = false;
            });

            // Set currency to company default
            newExpand.querySelectorAll('select[name="values[pricing][][currency][]"]').forEach(function(el) {
                el.value = blestaOptionsData.defaultCurrency;
            });

            // Reset expandable-rows guard so new rows get initialized
            newRow.removeAttribute('data-collapse-initialized');
            // Start expanded by default
            newExpand.classList.add('show');
            newRow.setAttribute('aria-expanded', 'true');

            var tbody = optionTable.querySelector('tbody');
            tbody.appendChild(newRow);
            tbody.appendChild(newExpand);

            // Re-initialize expandable rows for the new row
            document.dispatchEvent(new Event('blestaAjaxComplete'));
        });

        // --- Remove option row (delegation) ---
        container.addEventListener('click', function(e) {
            if (!e.target.closest('.option-row-remove')) return;
            e.preventDefault();
            var optionTable = container.querySelector('.option_table');
            if (!optionTable) return;
            // Count only visible option rows to prevent removing the last visible one
            var visibleRows = optionTable.querySelectorAll('tr.option_row:not([style*="display: none"])');
            if (visibleRows.length <= 1) return;

            var row = e.target.closest('tr');
            var expand = row.nextElementSibling;

            // Preserve value ID so it can be deleted on submit (edit form)
            var vid = row.querySelector('input.option_value_id');
            if (vid && vid.value) optionTable.parentNode.appendChild(vid);

            if (expand && expand.classList.contains('collapse')) expand.remove();
            row.remove();
        });

        // --- Add price row (delegation) ---
        container.addEventListener('click', function(e) {
            if (!e.target.closest('.price-row-add')) return;
            e.preventDefault();
            var origRow = e.target.closest('tr.price_row');
            if (!origRow) return;

            var newRow = origRow.cloneNode(true);
            newRow.querySelectorAll('input[type="text"], input[type="hidden"], textarea').forEach(function(el) {
                el.value = '';
            });
            newRow.querySelectorAll('input[type="checkbox"]').forEach(function(el) {
                el.disabled = false;
            });
            newRow.querySelectorAll('input[type="checkbox"], input[type="radio"]').forEach(function(el) {
                el.checked = false;
            });

            // Respect disable_pricing state for new rows
            var disablePricingCb = container.querySelector('#disable_pricing');
            var pricingDisabled = disablePricingCb && disablePricingCb.checked;
            newRow.querySelectorAll('input[type="text"]').forEach(function(el) {
                if (pricingDisabled && (el.classList.contains('price') || el.classList.contains('setup_fee') || el.classList.contains('price_renews'))) {
                    el.disabled = true;
                } else {
                    el.disabled = false;
                }
            });

            // Preserve currency/period from original
            var origCur = origRow.querySelector('select[name="values[pricing][][currency][]"]');
            var newCur = newRow.querySelector('select[name="values[pricing][][currency][]"]');
            if (origCur && newCur) newCur.value = origCur.value;
            var origPer = origRow.querySelector('select[name="values[pricing][][period][]"]');
            var newPer = newRow.querySelector('select[name="values[pricing][][period][]"]');
            if (origPer && newPer) newPer.value = origPer.value;

            // Handle onetime
            if (newPer && newPer.value === 'onetime') {
                var t = newRow.querySelector('input.term');
                if (t) t.disabled = true;
                var rc = newRow.querySelector('input.price_enable_renews');
                if (rc) rc.disabled = true;
            }
            newRow.querySelectorAll('input.price_renews').forEach(function(el) {
                el.disabled = true;
            });

            origRow.parentNode.insertBefore(newRow, origRow.nextSibling);
        });

        // --- Remove price row (delegation) ---
        container.addEventListener('click', function(e) {
            if (!e.target.closest('.price-row-remove')) return;
            e.preventDefault();
            var priceTable = e.target.closest('table.price_table');
            if (!priceTable || priceTable.querySelectorAll('tr.price_row').length <= 1) return;

            var row = e.target.closest('tr.price_row');

            // Preserve pricing ID (edit form)
            var pid = row.querySelector('input.value_price_id');
            if (pid && pid.value) {
                var last = priceTable.querySelector('tbody tr.price_row:last-child');
                if (last && last !== row) last.parentNode.insertBefore(pid, last.nextSibling);
            }
            row.remove();
        });

        // --- File preview on image selection (delegation) ---
        container.addEventListener('change', function(e) {
            if (!e.target.matches || !e.target.matches('.option-value-image-input')) return;
            var td = e.target.closest('td.image');
            if (!td) return;
            var wrapper = td.querySelector('.d-flex');
            if (!wrapper) return;

            // Remove old thumbnail
            var oldThumb = wrapper.querySelector('.option-value-thumb');
            if (oldThumb) oldThumb.remove();

            var file = e.target.files[0];
            if (!file) return;

            // Create preview thumbnail
            var img = document.createElement('img');
            img.className = 'option-value-thumb';
            img.style.cssText = 'width:32px;height:32px;object-fit:cover;border-radius:4px;';
            img.src = URL.createObjectURL(file);
            wrapper.insertBefore(img, wrapper.firstChild);

            // Add remove button if not present
            if (!wrapper.querySelector('.option-value-image-remove')) {
                var rmBtn = document.createElement('button');
                rmBtn.type = 'button';
                rmBtn.className = 'btn btn-sm btn-outline-danger option-value-image-remove';
                rmBtn.title = 'Remove image';
                rmBtn.innerHTML = '<i class="bi bi-x-lg"></i>';
                wrapper.appendChild(rmBtn);
            }

            // Clear the remove flag since we're uploading a new image
            var rmFlag = td.querySelector('.option-value-remove-image');
            if (rmFlag) rmFlag.value = '0';
        });

        // --- Remove image (delegation) ---
        container.addEventListener('click', function(e) {
            if (!e.target.closest('.option-value-image-remove')) return;
            e.preventDefault();
            var td = e.target.closest('td.image');
            if (!td) return;

            // Remove thumbnail
            var thumb = td.querySelector('.option-value-thumb');
            if (thumb) thumb.remove();

            // Clear file input
            var fileInput = td.querySelector('.option-value-image-input');
            if (fileInput) fileInput.value = '';

            // Set remove flag
            var rmFlag = td.querySelector('.option-value-remove-image');
            if (rmFlag) rmFlag.value = '1';

            // Clear existing image hidden field
            var existing = td.querySelector('.option-value-existing-image');
            if (existing) existing.value = '';

            // Remove the remove button itself
            var rmBtn = td.querySelector('.option-value-image-remove');
            if (rmBtn) rmBtn.remove();
        });
    }

    // ====== Option Form Interactivity (add/edit option modals) ======
    function initializeOptionForm(container) {
        var form = container.querySelector('#add_package_option, #edit_package_option');
        if (!form) return;

        var optionTable = container.querySelector('.option_table');
        var typeSelect = container.querySelector('#type');
        if (!optionTable) return;

        // Bind delegated event handlers once per container element
        bindOptionFormDelegates(container);

        // --- Initialize Bootstrap popovers (tooltip icons) ---
        container.querySelectorAll('[data-bs-toggle="popover"]').forEach(function(el) {
            new bootstrap.Popover(el);
        });

        // --- Initialize expandable rows (pricing sections) ---
        // The data-collapse-row pattern is handled by expandable-rows.js.
        // Dispatch blestaAjaxComplete so it initializes rows loaded in the modal.
        document.dispatchEvent(new Event('blestaAjaxComplete'));

        // --- Sortable option rows ---
        // Each option has a pair: tr.option_row + tr.collapse. SortableJS only
        // moves the dragged row, so we capture the pairs before drag and
        // reinsert the collapse rows after the drag ends.
        var optionTbody = optionTable.querySelector('tbody');
        if (optionTbody && typeof Sortable !== 'undefined') {
            var collapseMap = new Map();
            new Sortable(optionTbody, {
                handle: '.bi-grip-vertical',
                draggable: '.option_row',
                animation: 150,
                ghostClass: 'sortable-ghost',
                onStart: function() {
                    // Snapshot each option_row → collapse pairing
                    optionTbody.querySelectorAll('tr.option_row').forEach(function(row) {
                        var collapse = row.nextElementSibling;
                        if (collapse && collapse.classList.contains('collapse')) {
                            collapseMap.set(row, collapse);
                        }
                    });
                },
                onEnd: function() {
                    // Reinsert collapse rows after their paired option_rows
                    optionTbody.querySelectorAll('tr.option_row').forEach(function(row) {
                        var collapse = collapseMap.get(row);
                        if (collapse) {
                            row.after(collapse);
                        }
                    });
                    collapseMap.clear();
                }
            });
        }

        // --- Type switching ---
        var selectTypeMsg = container.querySelector('.select-type-message');
        var tableWrapper = optionTable.closest('.table-responsive');

        function updateTypeVisibility() {
            var type = typeSelect ? typeSelect.value : '';

            // Show message when no type is selected, hide form content
            if (!type) {
                if (selectTypeMsg) selectTypeMsg.style.display = '';
                if (tableWrapper) tableWrapper.style.display = 'none';
                container.querySelectorAll('.option-row-add').forEach(function(el) {
                    el.style.display = 'none';
                });
                return;
            }
            if (selectTypeMsg) selectTypeMsg.style.display = 'none';
            if (tableWrapper) tableWrapper.style.display = '';

            var hideValue = ['quantity', 'text', 'textarea', 'password'];
            var hideDefault = ['text', 'textarea', 'password'];
            var hideStatus = ['checkbox', 'quantity', 'text', 'textarea', 'password'];
            var hideName = ['text', 'textarea', 'password'];
            var hideAddBtn = ['checkbox', 'quantity', 'text', 'textarea', 'password'];
            var hideImage = ['checkbox', 'quantity', 'text', 'textarea', 'password'];

            // Toggle column visibility
            optionTable.querySelectorAll('td.value, th.value').forEach(function(el) {
                el.style.display = hideValue.indexOf(type) !== -1 ? 'none' : '';
            });
            optionTable.querySelectorAll('td.default, th.default').forEach(function(el) {
                el.style.display = hideDefault.indexOf(type) !== -1 ? 'none' : '';
            });
            optionTable.querySelectorAll('td.status, th.status').forEach(function(el) {
                el.style.display = hideStatus.indexOf(type) !== -1 ? 'none' : '';
            });
            optionTable.querySelectorAll('td.image, th.image').forEach(function(el) {
                el.style.display = hideImage.indexOf(type) !== -1 ? 'none' : '';
            });
            optionTable.querySelectorAll('td.min, th.min, td.max, th.max, td.step, th.step').forEach(function(el) {
                el.style.display = type === 'quantity' ? '' : 'none';
            });
            optionTable.querySelectorAll('input.name').forEach(function(el) {
                el.disabled = hideName.indexOf(type) !== -1;
            });
            container.querySelectorAll('.option-row-add').forEach(function(el) {
                el.style.display = hideAddBtn.indexOf(type) !== -1 ? 'none' : '';
            });

            // Convert Default field input type
            optionTable.querySelectorAll('.option_row td.default').forEach(function(td) {
                var input = td.querySelector('input');
                if (!input) return;
                var newType = (type === 'checkbox') ? 'checkbox' :
                    (type === 'quantity') ? 'text' : 'radio';
                if (input.type === newType) return;
                var rep = document.createElement('input');
                rep.type = newType;
                rep.name = input.name;
                if (newType === 'radio' || newType === 'checkbox') {
                    rep.value = '1';
                    rep.checked = input.checked;
                    rep.className = newType === 'checkbox' ? 'form-check-input' : '';
                } else {
                    rep.value = input.value;
                    rep.className = 'form-control form-control-sm';
                }
                input.parentNode.replaceChild(rep, input);
            });

            // Hide extra option rows for single-value types (preserve them for switching back)
            var singleValueType = hideAddBtn.indexOf(type) !== -1;
            var optionRows = optionTable.querySelectorAll('tr.option_row');
            optionRows.forEach(function(row, index) {
                var collapse = row.nextElementSibling;
                var isCollapse = collapse && collapse.classList.contains('collapse');
                if (singleValueType && index > 0) {
                    row.style.display = 'none';
                    if (isCollapse) collapse.style.display = 'none';
                } else {
                    row.style.display = '';
                    if (isCollapse) collapse.style.display = '';
                }
            });
        }

        if (typeSelect) {
            typeSelect.addEventListener('change', updateTypeVisibility);
            updateTypeVisibility();
        }

        // --- disable_pricing checkbox ---
        var disablePricingCb = container.querySelector('#disable_pricing');
        var hideInvContainer = container.querySelector('#hide_on_invoice_container');

        function togglePricingFields() {
            if (!disablePricingCb) return;
            if (disablePricingCb.checked) {
                if (hideInvContainer) hideInvContainer.style.display = '';
                container.querySelectorAll('.price_table input.price, .price_table input.setup_fee, .price_table input.price_renews').forEach(function(el) {
                    el.disabled = true;
                });
            } else {
                if (hideInvContainer) hideInvContainer.style.display = 'none';
                var cb = container.querySelector('#hide_on_invoice');
                if (cb) cb.checked = false;
                container.querySelectorAll('.price_table input.price, .price_table input.setup_fee').forEach(function(el) {
                    el.disabled = false;
                });
                container.querySelectorAll('.price_table input.price_renews').forEach(function(el) {
                    var row = el.closest('.price_row');
                    var rcb = row ? row.querySelector('.price_enable_renews') : null;
                    if (rcb && rcb.checked) el.disabled = false;
                });
            }
        }

        if (disablePricingCb) {
            disablePricingCb.addEventListener('change', togglePricingFields);
            togglePricingFields();
        }

        // --- Initialize renewal price state ---
        container.querySelectorAll('.price_enable_renews').forEach(function(cb) {
            if (cb.checked) return;
            var rp = cb.closest('td') ? cb.closest('td').querySelector('.price_renews') : null;
            if (!rp) return;
            var row = cb.closest('.price_row');
            var period = row ? row.querySelector('.period') : null;
            if (period && period.value !== 'onetime') {
                var price = row.querySelector('input.price');
                if (price) rp.value = price.value;
            } else {
                rp.value = '';
            }
            rp.disabled = true;
        });

        // --- Pre-submit: enable disabled fields and set pricing indices ---
        form.addEventListener('submit', function() {
            // Remove hidden option rows for single-value types so they are not submitted
            var singleValueTypes = ['checkbox', 'quantity', 'text', 'textarea', 'password'];
            var currentType = typeSelect ? typeSelect.value : '';
            if (singleValueTypes.indexOf(currentType) !== -1) {
                optionTable.querySelectorAll('tr.option_row').forEach(function(row, index) {
                    if (index === 0) return;
                    var collapse = row.nextElementSibling;
                    if (collapse && collapse.classList.contains('collapse')) {
                        collapse.remove();
                    }
                    row.remove();
                });
            }

            // Enable fields so they submit
            container.querySelectorAll('input.term').forEach(function(el) {
                el.disabled = false;
            });
            container.querySelectorAll('input.price_renews').forEach(function(el) {
                el.disabled = false;
            });
            container.querySelectorAll('input.price_enable_renews').forEach(function(el) {
                if (!el.checked) {
                    el.value = '0';
                    el.checked = true;
                }
            });

            // Assign pricing indices to match option rows
            var idx = 0;
            optionTable.querySelectorAll('tr.option_row').forEach(function(optRow) {
                optRow.querySelectorAll('input, select').forEach(function(el) {
                    if (el.name) el.name = el.name.replace('[]', '[' + idx + ']');
                });
                // Rename file input to match row index
                var fileInput = optRow.querySelector('.option-value-image-input');
                if (fileInput) fileInput.name = 'values_image_' + idx;
                var exp = optRow.nextElementSibling;
                if (exp && exp.classList.contains('collapse')) {
                    exp.querySelectorAll('input, select').forEach(function(el) {
                        if (el.name) el.name = el.name.replace('values[pricing][]', 'values[pricing][' + idx + ']');
                    });
                }
                idx++;
            });
        });
    }

    // ====== Event Delegation ======
    function initializeEventDelegation() {
        document.addEventListener('click', function(e) {
            var target = e.target.closest('[data-option-id], [data-group-id], [data-group-dropzone], #btnClearClipboard, .option-group-header');

            // Create option button
            if (e.target.closest('.btn-create-option')) {
                e.preventDefault();
                openCreateOptionModal();
                return;
            }

            // Create group button
            if (e.target.closest('.btn-create-group')) {
                e.preventDefault();
                openCreateGroupModal();
                return;
            }

            // Copy button
            if (e.target.closest('.btn-copy-option')) {
                e.preventDefault();
                var btn = e.target.closest('.btn-copy-option');
                copyOption(btn.getAttribute('data-option-id'));
                return;
            }

            // Edit option button
            if (e.target.closest('.btn-edit-option')) {
                e.preventDefault();
                var editBtn = e.target.closest('.btn-edit-option');
                openEditOptionModal(editBtn.getAttribute('data-option-id'));
                return;
            }

            // Edit group button
            if (e.target.closest('.btn-edit-group')) {
                e.preventDefault();
                var editGrp = e.target.closest('.btn-edit-group');
                openEditGroupModal(editGrp.getAttribute('data-group-id'));
                return;
            }

            // Logic button
            if (e.target.closest('.btn-open-logic')) {
                e.preventDefault();
                e.stopPropagation();
                var logicBtn = e.target.closest('.btn-open-logic');
                if (logicBtn.classList.contains('logic-disabled')) return;
                openLogicModal(logicBtn.getAttribute('data-group-id'), logicBtn.getAttribute('data-group-name'));
                return;
            }

            // Remove from group button
            if (e.target.closest('.btn-remove-from-group')) {
                e.preventDefault();
                e.stopPropagation();
                var rmBtn = e.target.closest('.btn-remove-from-group');
                removeFromGroup(rmBtn.getAttribute('data-option-id'), rmBtn.getAttribute('data-group-id'));
                return;
            }

            // Paste button
            if (e.target.closest('.paste-button')) {
                e.preventDefault();
                e.stopPropagation();
                var pasteBtn = e.target.closest('.paste-button');
                pasteToGroup(pasteBtn.getAttribute('data-group-id'));
                return;
            }

            // Clear clipboard
            if (e.target.closest('#btnClearClipboard')) {
                e.preventDefault();
                clearClipboard();
                return;
            }

            // Group header toggle (but not action buttons)
            if (e.target.closest('.option-group-header') && !e.target.closest('.option-group-actions')) {
                var header = e.target.closest('.option-group-header');
                var groupEl = header.closest('.option-group');
                if (groupEl) {
                    toggleGroup(groupEl.getAttribute('data-group-id'));
                }
                return;
            }
        });

        // Keyboard shortcuts
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' && state.clipboard.length > 0) {
                clearClipboard();
            }
        });
    }

    // ====== Logic Modal ======

    function openLogicModal(groupId, groupName) {
        var modal = document.getElementById('logicModal');
        if (!modal) return;

        // Set modal title
        var titleEl = document.getElementById('logicModalTitle');
        if (titleEl) {
            titleEl.textContent = 'Option Logic: ' + groupName;
        }

        loadLogicModalContent(modal, blestaOptionsData.baseUri + 'package_options/logic/' + encodeURIComponent(groupId) + '/');
    }

    function loadLogicModalContent(modal, url) {
        var body = modal.querySelector('.modal-body');
        body.innerHTML = '<div class="text-center py-5"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div></div>';

        // Clean up any footer from a previous load
        var oldFooter = modal.querySelector('.modal-content > .modal-footer');
        if (oldFooter) oldFooter.remove();

        blestaRequest('GET', url, null, function(html) {
            body.innerHTML = html;
            // Fix form actions
            body.querySelectorAll('form').forEach(function(form) {
                if (!form.getAttribute('action')) {
                    form.setAttribute('action', url);
                }
            });
            setupModalFooter(modal);
            state.logicFormDirty = false;
            initializeLogicForm(modal);
        }, function(error) {
            console.warn('[OptionsEditor] Failed to load logic modal content from ' + url + ':', error);
            body.innerHTML = '<div class="alert alert-danger m-3">Failed to load content. Please try again.</div>';
        });

        var bsModal = bootstrap.Modal.getInstance(modal) || new bootstrap.Modal(modal);
        bsModal.show();
    }

    function initializeLogicForm(modal) {
        // Only attach delegated event handlers once per modal element
        if (!modal.hasAttribute('data-logic-handlers-initialized')) {
            modal.setAttribute('data-logic-handlers-initialized', '1');

            // Track dirty state for logic form fields
            modal.addEventListener('input', function(e) {
                if (e.target.closest('#logic_form')) state.logicFormDirty = true;
            });
            modal.addEventListener('change', function(e) {
                if (e.target.closest('#logic_form')) state.logicFormDirty = true;
            });

            // Tab switching via AJAX (delegated)
            modal.addEventListener('click', function(e) {
                var tab = e.target.closest('.logic-option-tab');
                if (!tab || tab.classList.contains('active')) return;
                e.preventDefault();

                var optionId = tab.getAttribute('data-option-id');
                var groupId = tab.getAttribute('data-group-id');
                if (!optionId || !groupId) return;

                // Warn if unsaved changes
                if (state.logicFormDirty && !confirm('You have unsaved changes. Switch tabs without saving?')) {
                    return;
                }

                // Update active tab
                modal.querySelectorAll('.logic-option-tab').forEach(function(t) {
                    t.classList.remove('active');
                });
                tab.classList.add('active');

                // Load the tab content via AJAX
                var tabContent = modal.querySelector('#logicTabContent');
                if (tabContent) {
                    tabContent.innerHTML = '<div class="text-center py-4"><div class="spinner-border spinner-border-sm text-primary" role="status"><span class="visually-hidden">Loading...</span></div></div>';
                }

                // Remove existing footer (will be recreated from new content)
                var existingFooter = modal.querySelector('.modal-content > .modal-footer');
                if (existingFooter) existingFooter.remove();

                var tabUrl = blestaOptionsData.baseUri + 'package_options/logic/' + encodeURIComponent(groupId) + '/' + encodeURIComponent(optionId) + '/';

                blestaRequest('GET', tabUrl, null, function(html) {
                    var body = modal.querySelector('.modal-body');
                    body.innerHTML = html;
                    body.querySelectorAll('form').forEach(function(form) {
                        if (!form.getAttribute('action')) {
                            form.setAttribute('action', tabUrl);
                        }
                    });
                    setupModalFooter(modal);
                    state.logicFormDirty = false;
                    // Re-bind form submit and checkbox (body was replaced)
                    bindLogicFormSubmit(modal);
                    bindHideOptionsCheckbox(modal);
                });
            });

            // Add condition set (delegated)
            modal.addEventListener('click', function(e) {
                if (!e.target.closest('.condition-set-add')) return;
                e.preventDefault();
                cloneConditionSet(modal);
            });

            // Remove condition set (delegated)
            modal.addEventListener('click', function(e) {
                if (!e.target.closest('.condition-set-remove')) return;
                e.preventDefault();
                var card = e.target.closest('.condition-set-card');
                if (card) {
                    card.remove();
                    reindexConditionSets(modal);
                }
            });

            // Add condition row (delegated)
            modal.addEventListener('click', function(e) {
                if (!e.target.closest('.condition-row-add')) return;
                e.preventDefault();
                var setCard = e.target.closest('.condition-set-card');
                if (setCard) cloneConditionRow(setCard);
            });

            // Remove condition row (delegated)
            modal.addEventListener('click', function(e) {
                if (!e.target.closest('.condition-row-remove')) return;
                e.preventDefault();
                var setCard = e.target.closest('.condition-set-card');
                if (!setCard) return;
                var rows = setCard.querySelectorAll('.condition-row');
                if (rows.length > 1) {
                    e.target.closest('.condition-row').remove();
                    reindexConditionRows(setCard);
                }
            });

            // Trigger option change (delegated)
            modal.addEventListener('change', function(e) {
                if (!e.target.matches || !e.target.matches('.trigger-option-id')) return;
                handleTriggerOptionChange(e.target);
            });

            // Comparison operator change (delegated)
            modal.addEventListener('change', function(e) {
                if (!e.target.matches || !e.target.matches('.comparison-operator')) return;
                handleOperatorChange(e.target);
            });
        }

        // These need to bind to the actual form/checkbox elements after each content load
        bindHideOptionsCheckbox(modal);
        bindLogicFormSubmit(modal);
    }

    function bindHideOptionsCheckbox(modal) {
        var hideCheckbox = modal.querySelector('#hide_options');
        if (hideCheckbox && !hideCheckbox.hasAttribute('data-logic-initialized')) {
            hideCheckbox.setAttribute('data-logic-initialized', '1');
            hideCheckbox.addEventListener('change', function() {
                var groupId = this.getAttribute('data-group-id');
                var value = this.checked ? '1' : '0';

                blestaRequest('POST',
                    blestaOptionsData.baseUri + 'package_options/logicsettings/' + encodeURIComponent(groupId) + '/',
                    csrfParam() + '&hide_options=' + value,
                    function(response) {
                        var data = parseJsonResponse(response);
                        if (data && data.success) {
                            showToast('success', 'Saved', data.message);
                        } else if (data && data.errors) {
                            showToast('error', 'Error', 'Failed to save setting');
                        }
                    }
                );
            });
        }
    }

    function cloneConditionSet(modal) {
        var container = modal.querySelector('#conditionSetsContainer');
        if (!container) return;

        // Remove the "no condition sets" message
        var noMsg = container.querySelector('#noConditionSetsMsg');
        if (noMsg) noMsg.remove();

        var existingSets = container.querySelectorAll('.condition-set-card');
        var newSet;

        if (existingSets.length > 0) {
            // Clone last set
            var lastSet = existingSets[existingSets.length - 1];
            newSet = lastSet.cloneNode(true);

            // Remove all condition rows but the first
            var conditionRows = newSet.querySelectorAll('.condition-row');
            for (var i = 1; i < conditionRows.length; i++) {
                conditionRows[i].remove();
            }

            // Remove ID fields (condition set ID and condition IDs)
            newSet.querySelectorAll('.id_field').forEach(function(el) {
                el.remove();
            });

            // Clear condition row input values, but preserve structural hidden fields
            // (option_id, option_group_id, option_value_ids)
            newSet.querySelectorAll('.condition-row').forEach(function(row) {
                row.querySelectorAll("input:not([type='checkbox']):not([type='radio']), select:not([multiple]), textarea").forEach(function(el) {
                    if (!el.classList.contains('value_id')) el.value = '';
                });
                row.querySelectorAll("input[type='checkbox']").forEach(function(el) {
                    el.checked = el.classList.contains('disabled');
                });
            });

            // Deselect enable-values multi-selects (but keep the options)
            newSet.querySelectorAll('select[name*="option_value_ids"] option').forEach(function(opt) {
                opt.selected = false;
            });

            // Show text value field by default
            showValueField(newSet.querySelector('.condition-row'), 'text');
        } else {
            // Build a minimal condition set card from scratch
            newSet = buildEmptyConditionSetCard(modal);
        }

        // Show OR divider
        var divider = newSet.querySelector('.condition-set-divider');
        if (divider) divider.classList.remove('d-none');

        container.appendChild(newSet);
        reindexConditionSets(modal);
    }

    function buildEmptyConditionSetCard(modal) {
        var card = document.createElement('div');
        card.className = 'condition-set-card';
        card.setAttribute('data-set-index', '0');

        // Read option metadata from the container's data attributes
        var container = modal.querySelector('#conditionSetsContainer');
        var optionId = container ? container.getAttribute('data-option-id') : '';
        var groupId = container ? container.getAttribute('data-group-id') : '';
        var optionType = container ? container.getAttribute('data-option-type') : '';
        var firstValueId = container ? container.getAttribute('data-first-value-id') : '';

        // Get operators from the hidden template select rendered by the server
        var operatorOptions = '';
        var opTemplate = modal.querySelector('#logicOperatorsTemplate');
        if (opTemplate) {
            operatorOptions = opTemplate.innerHTML;
        } else {
            operatorOptions = '<option value="">-- Please Select --</option>';
        }

        // Get trigger options from the hidden template select rendered by the server
        var triggerOptions = '';
        var triggerTemplate = modal.querySelector('#logicTriggerOptionsTemplate');
        if (triggerTemplate) {
            triggerOptions = triggerTemplate.innerHTML;
        } else {
            triggerOptions = '<option value="">-- Please Select --</option>';
        }

        // Build enable values HTML based on option type
        var enableValuesHtml = '';
        if (optionType === 'select' || optionType === 'radio') {
            // Multi-select for choosing which option values to enable
            var optionValuesJson = container ? container.getAttribute('data-option-values') : null;
            var optionValues = optionValuesJson ? JSON.parse(optionValuesJson) : {};
            var optionsHtml = '';
            for (var valId in optionValues) {
                if (optionValues.hasOwnProperty(valId)) {
                    optionsHtml += '<option value="' + escapeHtml(valId) + '">' + escapeHtml(optionValues[valId]) + '</option>';
                }
            }
            enableValuesHtml = '<div class="mb-3"><label class="form-label fw-semibold">Enable Option Value:</label>' +
                '<select multiple class="form-select" size="4" name="condition_sets[0][option_value_ids][]">' + optionsHtml + '</select></div>';
        } else {
            // Hidden field with the first option value ID
            enableValuesHtml = '<input type="hidden" name="condition_sets[0][option_value_ids][]" value="' + escapeHtml(firstValueId) + '">';
        }

        card.innerHTML = '<div class="condition-set-divider d-none"><span class="badge bg-secondary">OR</span></div>' +
            '<div class="card mb-3"><div class="card-header d-flex justify-content-between align-items-center py-2">' +
            '<span class="fw-semibold small">Condition Set</span>' +
            '<button type="button" class="btn btn-sm btn-outline-danger condition-set-remove"><i class="bi bi-trash me-1"></i>Remove Condition Set</button>' +
            '</div><div class="card-body">' +
            '<input type="hidden" name="condition_sets[0][option_id]" value="' + escapeHtml(optionId) + '">' +
            '<input type="hidden" name="condition_sets[0][option_group_id]" value="' + escapeHtml(groupId) + '">' +
            enableValuesHtml +
            '<div class="table-responsive"><table class="table table-sm condition-table mb-0"><thead><tr>' +
            '<th class="condition-if-col">IF</th><th>Triggering Option</th><th>Operator</th><th>Value</th><th class="text-end">Actions</th>' +
            '</tr></thead><tbody>' +
            '<tr class="condition-row" data-row-index="0"><td class="condition-if-col"><span class="condition-and-text">AND</span></td>' +
            '<td><select class="form-select form-select-sm trigger-option-id" name="condition_sets[0][conditions][0][trigger_option_id]">' + triggerOptions + '</select></td>' +
            '<td><select class="form-select form-select-sm comparison-operator" name="condition_sets[0][conditions][0][operator]">' + operatorOptions + '</select></td>' +
            '<td>' +
            '<input type="hidden" class="value_text value_id" name="condition_sets[0][conditions][0][value_id]" value="">' +
            '<input type="text" class="form-control form-control-sm value_text" name="condition_sets[0][conditions][0][value]" value="">' +
            '<input type="hidden" class="value_quantity value_id" name="condition_sets[0][conditions][0][value_id]" value="" disabled style="display:none;">' +
            '<input type="number" class="form-control form-control-sm value_quantity" name="condition_sets[0][conditions][0][value]" value="" disabled style="display:none;">' +
            '<select class="form-select form-select-sm value_select" name="condition_sets[0][conditions][0][value_id]" disabled style="display:none;"></select>' +
            '<select multiple class="form-select form-select-sm value_multiselect" name="condition_sets[0][conditions][0][value_id][]" disabled style="display:none;"></select>' +
            '<input type="hidden" class="value_checkbox value_id" name="condition_sets[0][conditions][0][value_id]" value="" disabled style="display:none;">' +
            '<input type="hidden" class="value_checkbox value" name="condition_sets[0][conditions][0][value]" value="" disabled style="display:none;">' +
            '<input type="checkbox" class="form-check-input value_checkbox disabled" disabled style="display:none;" checked>' +
            '</td>' +
            '<td class="text-end text-nowrap">' +
            '<button type="button" class="btn btn-sm btn-outline-secondary condition-row-add" title="Add"><i class="bi bi-plus-lg"></i></button> ' +
            '<button type="button" class="btn btn-sm btn-outline-danger condition-row-remove" title="Remove"><i class="bi bi-trash"></i></button>' +
            '</td></tr></tbody></table></div></div></div>';

        return card;
    }

    function cloneConditionRow(setCard) {
        var tbody = setCard.querySelector('tbody');
        if (!tbody) return;

        var rows = tbody.querySelectorAll('.condition-row');
        var lastRow = rows[rows.length - 1];
        var newRow = lastRow.cloneNode(true);

        // Remove ID fields
        newRow.querySelectorAll('.id_field').forEach(function(el) {
            el.remove();
        });

        // Clear input values
        newRow.querySelectorAll("input:not([type='checkbox']):not([type='radio']), select:not(.trigger-option-id):not(.comparison-operator), textarea").forEach(function(el) {
            if (!el.classList.contains('value_id') && !el.classList.contains('trigger-option-id') && !el.classList.contains('comparison-operator')) {
                el.value = '';
            }
        });
        // Reset trigger and operator selects
        var triggerSel = newRow.querySelector('.trigger-option-id');
        if (triggerSel) triggerSel.value = '';
        var opSel = newRow.querySelector('.comparison-operator');
        if (opSel) opSel.value = '';

        newRow.querySelectorAll("input[type='checkbox']").forEach(function(el) {
            el.checked = el.classList.contains('disabled');
        });

        // Show text value field by default
        showValueField(newRow, 'text');

        tbody.appendChild(newRow);
        reindexConditionRows(setCard);
    }

    function reindexConditionSets(modal) {
        var container = modal.querySelector('#conditionSetsContainer');
        if (!container) return;

        var sets = container.querySelectorAll('.condition-set-card');
        sets.forEach(function(setCard, setIdx) {
            setCard.setAttribute('data-set-index', setIdx);

            // Show/hide OR divider
            var divider = setCard.querySelector('.condition-set-divider');
            if (divider) {
                if (setIdx === 0) {
                    divider.classList.add('d-none');
                } else {
                    divider.classList.remove('d-none');
                }
            }

            // Re-index all fields in this set
            setCard.querySelectorAll('input, select, textarea').forEach(function(el) {
                var name = el.getAttribute('name');
                if (!name) return;
                el.setAttribute('name', name.replace(/condition_sets\[\d+\]/, 'condition_sets[' + setIdx + ']'));
            });

            // Re-index condition rows within this set
            reindexConditionRows(setCard);
        });
    }

    function reindexConditionRows(setCard) {
        var rows = setCard.querySelectorAll('.condition-row');
        var setIdx = setCard.getAttribute('data-set-index');

        rows.forEach(function(row, condIdx) {
            row.setAttribute('data-row-index', condIdx);

            // Re-index field names
            row.querySelectorAll('input, select, textarea').forEach(function(el) {
                var name = el.getAttribute('name');
                if (!name || name.indexOf('conditions[') === -1) return;
                el.setAttribute('name', name.replace(/conditions\[\d+\]/, 'conditions[' + condIdx + ']'));
            });
        });
    }

    function handleTriggerOptionChange(select) {
        var row = select.closest('.condition-row');
        if (!row || !select.value) return;

        blestaRequest('GET', blestaOptionsData.baseUri + 'package_options/getoption/' + encodeURIComponent(select.value) + '/', null,
            function(response) {
                var data = parseJsonResponse(response);
                if (!data) return;

                if (data.type === 'select' || data.type === 'radio') {
                    showValueField(row, 'select');

                    // Get currently selected values to preserve them
                    var selectedValues = [];
                    row.querySelectorAll('.value_select option:checked, .value_multiselect option:checked').forEach(function(opt) {
                        selectedValues.push(opt.value);
                    });

                    // Remove existing options and repopulate
                    row.querySelectorAll('.value_select option, .value_multiselect option').forEach(function(opt) {
                        opt.remove();
                    });

                    (data.values || []).forEach(function(value) {
                        var opt1 = new Option(value.name, value.id);
                        var opt2 = new Option(value.name, value.id);
                        if (selectedValues.indexOf(String(value.id)) !== -1) {
                            opt1.selected = true;
                            opt2.selected = true;
                        }
                        var vs = row.querySelector('.value_select');
                        var vm = row.querySelector('.value_multiselect');
                        if (vs) vs.appendChild(opt1);
                        if (vm) vm.appendChild(opt2);
                    });

                    // Check operator for in/notin
                    handleOperatorChange(row.querySelector('.comparison-operator'));
                } else if (data.type === 'checkbox') {
                    showValueField(row, 'checkbox');
                    var cbValueId = row.querySelectorAll('.value_checkbox.value_id');
                    cbValueId.forEach(function(el) {
                        el.value = data.values[0].id;
                    });
                    var cbValue = row.querySelector('.value_checkbox.value');
                    if (cbValue) cbValue.value = data.values[0].value;
                    row.querySelectorAll("input[type='checkbox']").forEach(function(el) {
                        el.checked = true;
                    });
                } else if (data.type === 'quantity') {
                    showValueField(row, 'quantity');
                    row.querySelectorAll('.value_quantity.value_id').forEach(function(el) {
                        el.value = data.values[0].id;
                    });
                } else {
                    showValueField(row, 'text');
                    row.querySelectorAll('.value_text.value_id').forEach(function(el) {
                        el.value = data.values[0].id;
                    });
                }

                // Update operators based on type
                updateOperatorOptions(row, data.type);
            }
        );
    }

    function handleOperatorChange(select) {
        if (!select) return;
        var row = select.closest('.condition-row');
        if (!row) return;

        var op = select.value;
        var vs = row.querySelector('.value_select');
        var vm = row.querySelector('.value_multiselect');

        if (op === 'in' || op === 'notin') {
            if (vs) {
                vs.disabled = true;
                vs.style.display = 'none';
            }
            if (vm) {
                vm.disabled = false;
                vm.style.display = '';
            }
        } else {
            if (vs) {
                vs.disabled = false;
                vs.style.display = '';
            }
            if (vm) {
                vm.disabled = true;
                vm.style.display = 'none';
            }
        }
    }

    function showValueField(row, showType) {
        if (!row) return;
        var types = ['text', 'checkbox', 'quantity', 'select', 'multiselect'];

        types.forEach(function(type) {
            var fields = row.querySelectorAll('.value_' + type);
            if (type === showType) {
                fields.forEach(function(el) {
                    if (el.type !== 'checkbox') el.disabled = false;
                    el.style.display = '';
                });
            } else {
                fields.forEach(function(el) {
                    el.disabled = true;
                    el.style.display = 'none';
                });
            }
        });
    }

    function updateOperatorOptions(row, optionType) {
        var opSelect = row.querySelector('.comparison-operator');
        if (!opSelect) return;

        var typeOperators = {
            'text': ['=', '!=', 'in', 'notin'],
            'select': ['=', '!=', 'in', 'notin'],
            'radio': ['=', '!=', 'in', 'notin'],
            'quantity': ['>', '<', '=', '!='],
            'checkbox': ['=', '!='],
            'textarea': ['=', '!=', 'in', 'notin'],
            'password': ['=', '!=', 'in', 'notin']
        };

        var allowed = typeOperators[optionType] || ['=', '!=', 'in', 'notin'];
        var currentVal = opSelect.value;

        opSelect.querySelectorAll('option').forEach(function(opt) {
            if (opt.value === '') {
                // Keep the "please select" option
                opt.disabled = false;
                opt.style.display = '';
            } else if (allowed.indexOf(opt.value) !== -1) {
                opt.disabled = false;
                opt.style.display = '';
            } else {
                opt.disabled = true;
                opt.style.display = 'none';
            }
        });

        if (allowed.indexOf(currentVal) === -1) {
            opSelect.value = '=';
        }
    }

    function bindLogicFormSubmit(modal) {
        var form = modal.querySelector('#logic_form');
        if (!form) return;

        form.addEventListener('submit', function(e) {
            e.preventDefault();

            var formData = new FormData(form);

            // Include submit button value
            var submitBtn = form.querySelector('[type="submit"]') ||
                modal.querySelector('.modal-footer [type="submit"][form="logic_form"]');
            if (submitBtn && submitBtn.name && !formData.has(submitBtn.name)) {
                formData.append(submitBtn.name, submitBtn.value);
            }

            var action = form.getAttribute('action') || window.location.href;

            blestaRequest('POST', action, formData,
                function(response) {
                    var data = parseJsonResponse(response);

                    if (!data) {
                        // Non-JSON response (validation error HTML): replace modal body
                        var body = modal.querySelector('.modal-body');
                        body.innerHTML = response;
                        // Fix form actions
                        body.querySelectorAll('form').forEach(function(f) {
                            if (!f.getAttribute('action')) f.setAttribute('action', action);
                        });
                        setupModalFooter(modal);
                        initializeLogicForm(modal);
                        return;
                    }

                    if (data.success) {
                        state.logicFormDirty = false;
                        showToast('success', 'Success', data.message);
                        // Update badge count on active tab
                        var activeTab = modal.querySelector('.logic-option-tab.active');
                        if (activeTab) {
                            var sets = modal.querySelectorAll('.condition-set-card');
                            var badge = activeTab.querySelector('.badge');
                            if (sets.length > 0) {
                                if (badge) {
                                    badge.textContent = sets.length;
                                    badge.style.display = '';
                                } else {
                                    activeTab.insertAdjacentHTML('beforeend', ' <span class="badge bg-secondary ms-1">' + sets.length + '</span>');
                                }
                            } else if (badge) {
                                badge.remove();
                            }
                        }
                    } else if (data.errors) {
                        var errorHtml = '<div class="alert alert-danger"><ul class="mb-0">';
                        for (var field in data.errors) {
                            for (var rule in data.errors[field]) {
                                errorHtml += '<li>' + escapeHtml(data.errors[field][rule]) + '</li>';
                            }
                        }
                        errorHtml += '</ul></div>';
                        var existingAlert = modal.querySelector('.modal-body .alert-danger');
                        if (existingAlert) existingAlert.remove();
                        var body = modal.querySelector('.modal-body');
                        if (body) body.insertAdjacentHTML('afterbegin', errorHtml);
                    }
                }
            );
        });
    }

    // ====== Initialize on DOM Ready ======
    document.addEventListener('DOMContentLoaded', init);
})();