(function () {
    function $(s, r) { return (r || document).querySelector(s); }
    function $$(s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); }

    function escapeHtml(s) {
        return String(s == null ? '' : s)
            .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
    }

    /* ===== Persian digit converter ===== */
    function toFarsiNum(str) {
        return String(str).replace(/[0-9]/g, function(d) {
            return '۰۱۲۳۴۵۶۷۸۹'[parseInt(d, 10)];
        });
    }

    function toEnDigits(str) {
        return String(str).replace(/[۰-۹]/g, function(d) {
            return String('۰۱۲۳۴۵۶۷۸۹'.indexOf(d));
        });
    }

    /* ===== Persian number input handling ===== */
    function setupPersianInputs() {
        document.addEventListener('input', function (e) {
            var el = e.target;
            if (!el || !el.getAttribute || !el.getAttribute('data-persian-num')) return;
            var pos = el.selectionStart;
            var converted = el.value.replace(/[0-9]/g, function(d) {
                return '۰۱۲۳۴۵۶۷۸۹'[parseInt(d, 10)];
            });
            if (converted !== el.value) {
                el.value = converted;
                try { el.setSelectionRange(pos, pos); } catch(_) {}
            }
        });

        // Convert Persian digits back to English before form submit
        document.addEventListener('submit', function (e) {
            var form = e.target;
            if (!form) return;
            var inputs = form.querySelectorAll('[data-persian-num]');
            inputs.forEach(function(inp) {
                inp.value = toEnDigits(inp.value);
            });
        });
    }

    /* ===== Mobile sidebar toggle ===== */
    function setupSidebar() {
        var sidebar = $('.app-sidebar');
        var toggle = $('.menu-toggle');
        if (!sidebar || !toggle) return;

        var backdrop = $('.sidebar-backdrop');
        if (!backdrop) {
            backdrop = document.createElement('div');
            backdrop.className = 'sidebar-backdrop';
            document.body.appendChild(backdrop);
        }

        function open() { sidebar.classList.add('open'); backdrop.classList.add('show'); }
        function close() { sidebar.classList.remove('open'); backdrop.classList.remove('show'); }

        toggle.addEventListener('click', function (e) {
            e.preventDefault();
            sidebar.classList.contains('open') ? close() : open();
        });
        backdrop.addEventListener('click', close);
        sidebar.addEventListener('click', function (e) {
            if (e.target.closest('a')) close();
        });
    }

    function setupThemeToggle() {
        var btn = document.getElementById('themeToggleBtn');
        if (!btn) return;
        var root = document.documentElement;
        var key = 'pdf_form_theme_mode';

        function apply(mode) {
            root.setAttribute('data-theme', mode);
            document.body.classList.toggle('theme-dark', mode === 'dark');
            document.body.classList.toggle('theme-light', mode !== 'dark');
            var icon = btn.querySelector('i');
            if (icon) icon.className = mode === 'dark' ? 'bi bi-sun-fill theme-toggle-icon' : 'bi bi-moon-stars-fill theme-toggle-icon';
        }

        var saved = localStorage.getItem(key);
        var current = saved || root.getAttribute('data-theme') || 'light';
        apply(current === 'dark' ? 'dark' : 'light');

        btn.addEventListener('click', function () {
            var next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
            apply(next);
            localStorage.setItem(key, next);
            fetch('/admin/theme/toggle', {method:'POST', headers:{'X-Requested-With':'XMLHttpRequest','Content-Type':'application/x-www-form-urlencoded'}, body:'mode=' + encodeURIComponent(next)});
        });
    }

    /* ===== Multi-page form wizard prev/next ===== */
    function setupWizard() {
        document.addEventListener('click', function (e) {
            var t = e.target;
            if (!t.matches || (!t.matches('.wiz-next') && !t.matches('.wiz-prev'))) return;
            var tabs = $$('#formTabs .nav-link');
            if (!tabs.length || typeof bootstrap === 'undefined') return;
            var active = -1;
            tabs.forEach(function (x, i) { if (x.classList.contains('active')) active = i; });
            var next = t.matches('.wiz-next') ? active + 1 : active - 1;
            if (next >= 0 && next < tabs.length) {
                bootstrap.Tab.getOrCreateInstance(tabs[next]).show();
            }
        });
    }

    /* ===== Admin: dynamic field rows + dynamic pages ===== */
    function buildFieldRow(pageKey, idx, fields) {
        var opts = '<option value="">— انتخاب فیلد —</option>';
        fields.forEach(function (f) {
            opts += '<option value="' + f.id + '">' + escapeHtml(f.label) + ' (' + escapeHtml(f.key) + ')</option>';
        });
        var name = 'field[' + pageKey + '][' + idx + ']';
        var colOpts =
            '<option value="12">کل ردیف (۱۲/۱۲)</option>' +
            '<option value="9">۳/۴ ردیف (۹/۱۲)</option>' +
            '<option value="8">۲/۳ ردیف (۸/۱۲)</option>' +
            '<option value="6" selected>نیمه (۶/۱۲)</option>' +
            '<option value="4">یک‌سوم (۴/۱۲)</option>' +
            '<option value="3">یک‌چهارم (۳/۱۲)</option>';
        return (
            '<div class="d-flex align-items-center gap-1 field-row mb-2 flex-nowrap">' +
                '<input type="hidden" name="' + name + '[sort_order]" class="field-sort-input" value="9999">' +
                '<div class="field-drag-handle flex-shrink-0" style="cursor:grab;color:#888;padding:0 2px" title="جابه‌جایی">' +
                    '<i class="bi bi-grip-vertical fs-5"></i>' +
                '</div>' +
                '<div style="flex:2;min-width:0"><select name="' + name + '[field_id]" class="form-select form-select-sm">' + opts + '</select></div>' +
                '<div style="flex:2;min-width:0"><input class="form-control form-control-sm" name="' + name + '[pdf_field_name]" placeholder="نام فیلد در PDF" dir="ltr"></div>' +
                '<div style="width:130px;flex-shrink:0"><select name="' + name + '[col_width]" class="form-select form-select-sm" title="عرض فیلد در فرم کاربر">' + colOpts + '</select></div>' +
                '<div class="form-check flex-shrink-0 mb-0">' +
                    '<input class="form-check-input" type="checkbox" value="1" name="' + name + '[required]" checked>' +
                    '<label class="form-check-label small">الزامی</label>' +
                '</div>' +
                '<div class="form-check flex-shrink-0 mb-0">' +
                    '<input class="form-check-input" type="checkbox" value="1" name="' + name + '[editable]" checked>' +
                    '<label class="form-check-label small">قابل ویرایش</label>' +
                '</div>' +
                '<button type="button" class="btn btn-sm btn-outline-secondary flex-shrink-0 field-up-btn" title="انتقال به بالا">↑</button>' +
                '<button type="button" class="btn btn-sm btn-outline-secondary flex-shrink-0 field-down-btn" title="انتقال به پایین">↓</button>' +
                '<button type="button" class="btn btn-sm btn-outline-danger flex-shrink-0 remove-field-btn" title="حذف">×</button>' +
            '</div>'
        );
    }

    function getFieldsLib() {
        var holder = document.getElementById('adminPageTabs');
        if (!holder) return [];
        try { return JSON.parse(holder.getAttribute('data-fields') || '[]'); }
        catch (e) { return []; }
    }

    var newPageCounter = 0;

    function addPage() {
        var tabs = document.getElementById('adminPageTabs');
        var panes = document.getElementById('adminPagePanes');
        if (!tabs || !panes) return;

        var pageKey = 'new_' + (newPageCounter++);
        var paneId = 'ap-' + pageKey;
        var defaultTitle = 'صفحهٔ جدید';

        var li = document.createElement('li');
        li.className = 'nav-item';
        li.setAttribute('data-page', pageKey);
        li.innerHTML = '<button type="button" class="nav-link" data-bs-toggle="pill" data-bs-target="#' + paneId + '">' + escapeHtml(defaultTitle) + '</button>';
        tabs.appendChild(li);

        var pane = document.createElement('div');
        pane.className = 'tab-pane fade page-pane';
        pane.id = paneId;
        pane.setAttribute('data-page', pageKey);
        var fieldsJson = JSON.stringify(getFieldsLib()).replace(/'/g, '&#39;');
        pane.innerHTML = (
            '<div class="d-flex gap-2 align-items-end mb-3">' +
                '<div class="flex-grow-1">' +
                    '<label class="form-label">عنوان صفحه</label>' +
                    '<input class="form-control page-title-input" name="page_title[' + pageKey + ']" value="' + escapeHtml(defaultTitle) + '">' +
                '</div>' +
                '<button type="button" class="btn btn-outline-danger remove-page-btn" data-page="' + pageKey + '" title="حذف این صفحه">حذف صفحه</button>' +
            '</div>' +
            '<div class="page-fields" data-page="' + pageKey + '" data-next-index="0" data-fields=\'' + fieldsJson + '\'></div>' +
            '<div class="d-flex gap-2 mt-2">' +
                '<button type="button" class="btn btn-sm btn-outline-secondary add-field-btn" data-page="' + pageKey + '">+ افزودن فیلد</button>' +
                '<button type="button" class="btn btn-sm btn-outline-info add-block-btn" data-page="' + pageKey + '"><i class="bi bi-card-text me-1"></i>+ افزودن توضیحات</button>' +
            '</div>'
        );
        panes.appendChild(pane);

        if (typeof bootstrap !== 'undefined') {
            bootstrap.Tab.getOrCreateInstance(li.querySelector('.nav-link')).show();
        }
    }

    function removePage(pageKey) {
        if (!confirm('این صفحه و همهٔ فیلدهای آن از این فرم حذف می‌شود. ادامه می‌دهید؟')) return;

        var pane = document.querySelector('.page-pane[data-page="' + pageKey + '"]');
        var tabLi = document.querySelector('#adminPageTabs li[data-page="' + pageKey + '"]') ||
                    (function(){
                        var btn = document.querySelector('#adminPageTabs [data-bs-target="#ap-' + pageKey + '"]');
                        return btn ? btn.parentElement : null;
                    })();

        if (/^\d+$/.test(String(pageKey))) {
            var holder = document.getElementById('deletedPagesContainer');
            if (holder) {
                var input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'delete_page[]';
                input.value = pageKey;
                holder.appendChild(input);
            }
        }

        if (pane) pane.remove();
        if (tabLi) tabLi.remove();

        var firstBtn = document.querySelector('#adminPageTabs .nav-link');
        if (firstBtn && typeof bootstrap !== 'undefined') {
            bootstrap.Tab.getOrCreateInstance(firstBtn).show();
        }
    }

    function syncTabTitle(input) {
        var pane = input.closest('.page-pane');
        if (!pane) return;
        var pageKey = pane.getAttribute('data-page');
        var btn = document.querySelector('#adminPageTabs [data-bs-target="#ap-' + pageKey + '"]');
        if (btn) btn.textContent = input.value || 'بدون عنوان';
    }

    /* ===== Drag-and-drop for form field rows ===== */
    function setupFieldRowDragDrop(container) {
        var dragging = null;
        var placeholder = null;

        function createPlaceholder(height) {
            var el = document.createElement('div');
            el.className = 'field-row-placeholder';
            el.style.height = (height || 44) + 'px';
            el.style.border = '2px dashed #6366f1';
            el.style.borderRadius = '6px';
            el.style.marginBottom = '8px';
            el.style.background = 'rgba(99,102,241,0.05)';
            return el;
        }

        // Only enable dragging when the user grabs the handle
        container.addEventListener('mousedown', function (e) {
            var handle = e.target.closest('.field-drag-handle');
            if (!handle) return;
            var row = handle.closest('.field-row');
            if (row) row.setAttribute('draggable', 'true');
        });

        container.addEventListener('mouseup', function () {
            container.querySelectorAll('.field-row[draggable]').forEach(function (r) {
                r.removeAttribute('draggable');
            });
        });

        container.addEventListener('dragstart', function (e) {
            var row = e.target.closest('.field-row[draggable]');
            if (!row) { e.preventDefault(); return; }
            dragging = row;
            dragging.style.opacity = '0.4';
            placeholder = createPlaceholder(row.offsetHeight);
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', '');
        });

        container.addEventListener('dragend', function () {
            if (dragging) {
                dragging.style.opacity = '';
                dragging.removeAttribute('draggable');
            }
            if (placeholder && placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
            dragging = null;
            placeholder = null;
            reindexFieldRows(container);
        });

        container.addEventListener('dragover', function (e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            if (!dragging || !placeholder) return;

            var afterEl = getDragAfterElement(container, e.clientY);
            if (afterEl == null) {
                container.appendChild(placeholder);
            } else if (afterEl !== placeholder) {
                container.insertBefore(placeholder, afterEl);
            }
        });

        container.addEventListener('drop', function (e) {
            e.preventDefault();
            if (!dragging || !placeholder) return;
            if (placeholder.parentNode === container) {
                container.insertBefore(dragging, placeholder);
            }
        });
    }

    function getDragAfterElement(container, y) {
        var rows = Array.prototype.slice.call(
            container.querySelectorAll('.field-row:not(.field-row-placeholder):not([style*="opacity: 0.4"])')
        );
        var result = null;
        var closest = Infinity;
        rows.forEach(function (el) {
            var box = el.getBoundingClientRect();
            var offset = y - box.top - box.height / 2;
            if (offset < 0 && Math.abs(offset) < closest) {
                closest = Math.abs(offset);
                result = el;
            }
        });
        return result;
    }

    function reindexFieldRows(container) {
        var pageKey = container.getAttribute('data-page');
        if (!pageKey) return;
        var rows = container.querySelectorAll('.field-row');
        rows.forEach(function (row, newIdx) {
            row.querySelectorAll('[name]').forEach(function (inp) {
                inp.name = inp.name.replace(
                    /^field\[([^\]]+)\]\[(\d+)\]/,
                    'field[' + pageKey + '][' + newIdx + ']'
                );
            });
        });
        container.setAttribute('data-next-index', String(rows.length));
    }

    function setupFieldEditor() {
        document.addEventListener('click', function (e) {
            var addPageBtn = e.target.closest('.add-page-btn');
            if (addPageBtn) { e.preventDefault(); addPage(); return; }

            var rmPageBtn = e.target.closest('.remove-page-btn');
            if (rmPageBtn) { e.preventDefault(); removePage(rmPageBtn.getAttribute('data-page')); return; }

            var addBtn = e.target.closest('.add-field-btn');
            if (addBtn) {
                e.preventDefault();
                var pageKey = addBtn.getAttribute('data-page');
                var container = document.querySelector('.page-fields[data-page="' + pageKey + '"]');
                if (!container) return;
                var fields = getFieldsLib();
                var idx = parseInt(container.getAttribute('data-next-index') || '0', 10);
                container.insertAdjacentHTML('beforeend', buildFieldRow(pageKey, idx, fields));
                container.setAttribute('data-next-index', String(idx + 1));
                return;
            }

            var rmBtn = e.target.closest('.remove-field-btn');
            if (rmBtn) {
                e.preventDefault();
                var row = rmBtn.closest('.field-row');
                if (row) {
                    var cont = row.closest('.page-fields');
                    row.remove();
                    if (cont) reindexFieldRows(cont);
                }
                return;
            }

            var upFldBtn = e.target.closest('.field-up-btn');
            if (upFldBtn) {
                e.preventDefault();
                var frow = upFldBtn.closest('.field-row');
                if (frow) {
                    var fprev = frow.previousElementSibling;
                    if (fprev) frow.parentNode.insertBefore(frow, fprev);
                }
                return;
            }

            var downFldBtn = e.target.closest('.field-down-btn');
            if (downFldBtn) {
                e.preventDefault();
                var frow2 = downFldBtn.closest('.field-row');
                if (frow2) {
                    var fnext = frow2.nextElementSibling;
                    if (fnext) frow2.parentNode.insertBefore(fnext, frow2);
                }
                return;
            }

            var addBlkBtn = e.target.closest('.add-block-btn');
            if (addBlkBtn) {
                e.preventDefault();
                var blkPid = addBlkBtn.getAttribute('data-page');
                var blkCont = document.querySelector('.page-fields[data-page="' + blkPid + '"]');
                if (!blkCont) return;
                var blkN = blkCont.querySelectorAll('.block-row').length;
                var blkDiv = document.createElement('div');
                blkDiv.className = 'block-row card border mb-2 shadow-none';
                blkDiv.dataset.blockPage = blkPid;
                blkDiv.innerHTML =
                    '<input type="hidden" name="block[' + blkPid + '][' + blkN + '][sort_order]" class="block-sort-input" value="9999">' +
                    '<div class="card-body p-2">' +
                        '<div class="d-flex gap-2 align-items-center mb-2">' +
                            '<span class="text-info flex-shrink-0" title="بلوک توضیحات"><i class="bi bi-card-text"></i></span>' +
                            '<input type="text" class="form-control form-control-sm flex-grow-1 block-title-input"' +
                            ' name="block[' + blkPid + '][' + blkN + '][title]" placeholder="عنوان توضیحات (اختیاری)">' +
                            '<input type="color" class="form-control form-control-color flex-shrink-0 block-color-input"' +
                            ' name="block[' + blkPid + '][' + blkN + '][color]" value="#0d6efd"' +
                            ' title="رنگ بلوک" style="width:38px;height:31px;padding:2px;cursor:pointer">' +
                            '<button type="button" class="btn btn-sm btn-outline-secondary block-up-btn" title="انتقال به بالا">↑</button>' +
                            '<button type="button" class="btn btn-sm btn-outline-secondary block-down-btn" title="انتقال به پایین">↓</button>' +
                            '<button type="button" class="btn btn-sm btn-outline-danger block-rm-btn" title="حذف">×</button>' +
                        '</div>' +
                        '<div class="quill-block-container" style="height:160px;background:#fff"></div>' +
                        '<textarea class="block-content-input" name="block[' + blkPid + '][' + blkN + '][content]" style="display:none"></textarea>' +
                    '</div>';
                blkCont.appendChild(blkDiv);
                if (typeof window._pdfInitQuill === 'function') window._pdfInitQuill(blkDiv);
                return;
            }

            var upBlkBtn = e.target.closest('.block-up-btn');
            if (upBlkBtn) {
                e.preventDefault();
                var blkRow = upBlkBtn.closest('.block-row');
                if (blkRow) {
                    var blkPrev = blkRow.previousElementSibling;
                    if (blkPrev) blkRow.parentNode.insertBefore(blkRow, blkPrev);
                }
                return;
            }

            var downBlkBtn = e.target.closest('.block-down-btn');
            if (downBlkBtn) {
                e.preventDefault();
                var blkRow2 = downBlkBtn.closest('.block-row');
                if (blkRow2) {
                    var blkNext = blkRow2.nextElementSibling;
                    if (blkNext) blkRow2.parentNode.insertBefore(blkNext, blkRow2);
                }
                return;
            }

            var rmBlkBtn = e.target.closest('.block-rm-btn');
            if (rmBlkBtn) {
                e.preventDefault();
                if (confirm('این بلوک توضیحات حذف شود؟')) rmBlkBtn.closest('.block-row').remove();
                return;
            }
        });

        document.addEventListener('input', function (e) {
            if (e.target && e.target.matches('input[name^="page_title["]')) {
                syncTabTitle(e.target);
            }
        });

        // Setup drag-drop on existing page-fields containers
        $$('.page-fields').forEach(function (container) {
            setupFieldRowDragDrop(container);
        });

        // When a new page is added, also setup drag-drop on its container
        var panes = document.getElementById('adminPagePanes');
        if (panes && typeof MutationObserver !== 'undefined') {
            var observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (m) {
                    m.addedNodes.forEach(function (node) {
                        if (node.nodeType !== 1) return;
                        var containers = node.querySelectorAll ? node.querySelectorAll('.page-fields') : [];
                        Array.prototype.forEach.call(containers, function (c) {
                            setupFieldRowDragDrop(c);
                        });
                    });
                });
            });
            observer.observe(panes, { childList: true });
        }
    }

    /* ===== Drag-and-drop for field library table ===== */
    function setupFieldLibraryDragDrop() {
        var tbody = document.getElementById('fieldsSortable');
        if (!tbody) return;

        var dragging = null;
        var placeholder = null;

        function createRowPlaceholder(height) {
            var tr = document.createElement('tr');
            tr.className = 'fields-drag-placeholder';
            tr.style.height = (height || 48) + 'px';
            var td = document.createElement('td');
            td.colSpan = 7;
            td.style.border = '2px dashed #6366f1';
            td.style.background = 'rgba(99,102,241,0.05)';
            td.style.padding = '0';
            tr.appendChild(td);
            return tr;
        }

        tbody.addEventListener('mousedown', function(e) {
            var handle = e.target.closest('.field-drag-handle');
            if (!handle) return;
            var row = handle.closest('tr');
            if (row) row.setAttribute('draggable', 'true');
        });

        tbody.addEventListener('mouseup', function() {
            var rows = tbody.querySelectorAll('tr[draggable]');
            rows.forEach(function(r) { r.removeAttribute('draggable'); });
        });

        tbody.addEventListener('dragstart', function (e) {
            var row = e.target.closest('tr[data-id]');
            if (!row || !row.getAttribute('draggable')) { e.preventDefault(); return; }
            dragging = row;
            dragging.style.opacity = '0.4';
            placeholder = createRowPlaceholder(row.offsetHeight);
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', row.getAttribute('data-id') || '');
        });

        tbody.addEventListener('dragend', function () {
            if (dragging) dragging.style.opacity = '';
            if (placeholder && placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
            dragging = null;
            placeholder = null;
            saveFieldLibraryOrder();
        });

        tbody.addEventListener('dragover', function (e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            if (!dragging || !placeholder) return;

            var afterEl = getRowAfterElement(tbody, e.clientY);
            if (afterEl == null) {
                tbody.appendChild(placeholder);
            } else if (afterEl !== placeholder) {
                tbody.insertBefore(placeholder, afterEl);
            }
        });

        tbody.addEventListener('drop', function (e) {
            e.preventDefault();
            if (!dragging || !placeholder) return;
            if (placeholder.parentNode === tbody) {
                tbody.insertBefore(dragging, placeholder);
            }
        });
    }

    function getRowAfterElement(container, y) {
        var rows = Array.prototype.slice.call(
            container.querySelectorAll('tr[data-id]:not([style*="opacity: 0.4"])')
        );
        var result = null;
        var closest = Infinity;
        rows.forEach(function (el) {
            var box = el.getBoundingClientRect();
            var offset = y - box.top - box.height / 2;
            if (offset < 0 && Math.abs(offset) < closest) {
                closest = Math.abs(offset);
                result = el;
            }
        });
        return result;
    }

    function saveFieldLibraryOrder() {
        var tbody = document.getElementById('fieldsSortable');
        if (!tbody) return;
        var rows = tbody.querySelectorAll('tr[data-id]');
        var ids = [];
        rows.forEach(function (r) {
            var id = r.getAttribute('data-id');
            if (id) ids.push(id);
        });
        var csrfEl = document.getElementById('fieldReorderCsrf');
        var csrf = csrfEl ? csrfEl.value : '';
        fetch('/admin/fields/reorder', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-Token': csrf
            },
            body: JSON.stringify({ ids: ids })
        }).catch(function() {});
    }

    /* ===== Drag-and-drop for forms grid ===== */
    function setupFormsSortable() {
        var container = document.getElementById('formsSortable');
        if (!container) return;

        var dragging = null;
        var placeholder = null;

        function createColPlaceholder(width, height) {
            var col = document.createElement('div');
            col.className = 'form-sort-col form-sort-placeholder col-md-6 col-lg-4';
            col.style.height = (height || 140) + 'px';
            col.innerHTML = '<div style="height:100%;border:2px dashed #6366f1;border-radius:14px;background:rgba(99,102,241,0.05)"></div>';
            return col;
        }

        container.addEventListener('mousedown', function (e) {
            var handle = e.target.closest('.form-sort-handle');
            if (!handle) return;
            var col = handle.closest('.form-sort-col');
            if (col) col.setAttribute('draggable', 'true');
        });

        container.addEventListener('mouseup', function () {
            container.querySelectorAll('.form-sort-col[draggable]').forEach(function (c) {
                c.removeAttribute('draggable');
            });
        });

        container.addEventListener('dragstart', function (e) {
            var col = e.target.closest('.form-sort-col[draggable]');
            if (!col) { e.preventDefault(); return; }
            dragging = col;
            dragging.style.opacity = '0.4';
            placeholder = createColPlaceholder(col.offsetWidth, col.offsetHeight);
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', col.getAttribute('data-id') || '');
        });

        container.addEventListener('dragend', function () {
            if (dragging) {
                dragging.style.opacity = '';
                dragging.removeAttribute('draggable');
            }
            if (placeholder && placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
            dragging = null;
            placeholder = null;
            saveFormsOrder();
        });

        container.addEventListener('dragover', function (e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            if (!dragging || !placeholder) return;

            var cols = Array.prototype.slice.call(
                container.querySelectorAll('.form-sort-col:not(.form-sort-placeholder)')
            ).filter(function (c) { return c !== dragging; });

            var afterEl = null;
            var closest = Infinity;
            cols.forEach(function (el) {
                var box = el.getBoundingClientRect();
                var cx = box.left + box.width / 2;
                var cy = box.top + box.height / 2;
                var dist = Math.hypot(e.clientX - cx, e.clientY - cy);
                if (dist < closest) { closest = dist; afterEl = el; }
            });

            if (afterEl) {
                var box = afterEl.getBoundingClientRect();
                var cx = box.left + box.width / 2;
                if (e.clientX < cx) {
                    container.insertBefore(placeholder, afterEl);
                } else {
                    var next = afterEl.nextSibling;
                    if (next) container.insertBefore(placeholder, next);
                    else container.appendChild(placeholder);
                }
            } else {
                container.appendChild(placeholder);
            }
        });

        container.addEventListener('drop', function (e) {
            e.preventDefault();
            if (!dragging || !placeholder) return;
            if (placeholder.parentNode === container) {
                container.insertBefore(dragging, placeholder);
            }
        });
    }

    function saveFormsOrder() {
        var container = document.getElementById('formsSortable');
        if (!container) return;
        var cols = container.querySelectorAll('.form-sort-col[data-id]');
        var ids = [];
        cols.forEach(function (c) {
            var id = c.getAttribute('data-id');
            if (id) ids.push(id);
        });
        var csrfEl = document.getElementById('formReorderCsrf');
        var csrf = csrfEl ? csrfEl.value : '';
        fetch('/admin/forms/reorder', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-Token': csrf
            },
            body: JSON.stringify({ ids: ids })
        }).catch(function() {});
    }

    /* ===== Drag-and-drop for user MY FORMS grid ===== */
    function setupMyFormsSortable() {
        var container = document.getElementById('myFormsSortable');
        if (!container) return;

        var dragging = null;
        var placeholder = null;

        function createColPlaceholder(height) {
            var col = document.createElement('div');
            col.className = 'form-sort-col form-sort-placeholder col-md-6 col-lg-4';
            col.style.height = (height || 140) + 'px';
            col.innerHTML = '<div style="height:100%;border:2px dashed #6366f1;border-radius:14px;background:rgba(99,102,241,0.05)"></div>';
            return col;
        }

        container.addEventListener('mousedown', function (e) {
            var handle = e.target.closest('.form-sort-handle');
            if (!handle) return;
            var col = handle.closest('.form-sort-col');
            if (col) col.setAttribute('draggable', 'true');
        });

        container.addEventListener('mouseup', function () {
            container.querySelectorAll('.form-sort-col[draggable]').forEach(function (c) {
                c.removeAttribute('draggable');
            });
        });

        container.addEventListener('dragstart', function (e) {
            var col = e.target.closest('.form-sort-col[draggable]');
            if (!col) { e.preventDefault(); return; }
            dragging = col;
            dragging.style.opacity = '0.4';
            placeholder = createColPlaceholder(col.offsetHeight);
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', col.getAttribute('data-id') || '');
        });

        container.addEventListener('dragend', function () {
            if (dragging) { dragging.style.opacity = ''; dragging.removeAttribute('draggable'); }
            if (placeholder && placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
            dragging = null; placeholder = null;
            saveMyFormsOrder();
        });

        container.addEventListener('dragover', function (e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            if (!dragging || !placeholder) return;
            var cols = Array.prototype.slice.call(
                container.querySelectorAll('.form-sort-col:not(.form-sort-placeholder)')
            ).filter(function (c) { return c !== dragging; });
            var afterEl = null; var closest = Infinity;
            cols.forEach(function (el) {
                var box = el.getBoundingClientRect();
                var dist = Math.hypot(e.clientX - (box.left + box.width / 2), e.clientY - (box.top + box.height / 2));
                if (dist < closest) { closest = dist; afterEl = el; }
            });
            if (afterEl) {
                var box = afterEl.getBoundingClientRect();
                if (e.clientX < box.left + box.width / 2) container.insertBefore(placeholder, afterEl);
                else { var next = afterEl.nextSibling; if (next) container.insertBefore(placeholder, next); else container.appendChild(placeholder); }
            } else { container.appendChild(placeholder); }
        });

        container.addEventListener('drop', function (e) {
            e.preventDefault();
            if (!dragging || !placeholder) return;
            if (placeholder.parentNode === container) container.insertBefore(dragging, placeholder);
        });
    }

    function saveMyFormsOrder() {
        var container = document.getElementById('myFormsSortable');
        if (!container) return;
        var ids = [];
        container.querySelectorAll('.form-sort-col[data-id]').forEach(function (c) {
            var id = c.getAttribute('data-id'); if (id) ids.push(id);
        });
        var csrfEl = document.getElementById('myFormReorderCsrf');
        var csrf = csrfEl ? csrfEl.value : '';
        fetch('/my-forms/reorder', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' },
            body: '_csrf=' + encodeURIComponent(csrf) + '&ids=' + ids.join(',')
        }).catch(function () {});
    }

    /* ===== Drag-and-drop for user MY FIELDS table ===== */
    function setupMyFieldsSortable() {
        var tbody = document.getElementById('myFieldsSortable');
        if (!tbody) return;

        var dragging = null;
        var placeholder = null;

        function createRowPlaceholder(height) {
            var tr = document.createElement('tr');
            tr.className = 'fields-drag-placeholder';
            tr.style.height = (height || 48) + 'px';
            var td = document.createElement('td');
            td.colSpan = 6;
            td.style.border = '2px dashed #6366f1';
            td.style.background = 'rgba(99,102,241,0.05)';
            td.style.padding = '0';
            tr.appendChild(td);
            return tr;
        }

        tbody.addEventListener('mousedown', function (e) {
            var handle = e.target.closest('.field-drag-handle');
            if (!handle) return;
            var row = handle.closest('tr');
            if (row) row.setAttribute('draggable', 'true');
        });

        tbody.addEventListener('mouseup', function () {
            tbody.querySelectorAll('tr[draggable]').forEach(function (r) { r.removeAttribute('draggable'); });
        });

        tbody.addEventListener('dragstart', function (e) {
            var row = e.target.closest('tr[data-id]');
            if (!row || !row.getAttribute('draggable')) { e.preventDefault(); return; }
            dragging = row;
            dragging.style.opacity = '0.4';
            placeholder = createRowPlaceholder(row.offsetHeight);
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', row.getAttribute('data-id') || '');
        });

        tbody.addEventListener('dragend', function () {
            if (dragging) dragging.style.opacity = '';
            if (placeholder && placeholder.parentNode) placeholder.parentNode.removeChild(placeholder);
            dragging = null; placeholder = null;
            saveMyFieldsOrder();
        });

        tbody.addEventListener('dragover', function (e) {
            e.preventDefault();
            e.dataTransfer.dropEffect = 'move';
            if (!dragging || !placeholder) return;
            var afterEl = null; var closest = Infinity;
            Array.prototype.slice.call(tbody.querySelectorAll('tr[data-id]'))
                .filter(function (r) { return r !== dragging; })
                .forEach(function (el) {
                    var box = el.getBoundingClientRect();
                    var offset = e.clientY - box.top - box.height / 2;
                    if (offset < 0 && Math.abs(offset) < closest) { closest = Math.abs(offset); afterEl = el; }
                });
            if (afterEl == null) tbody.appendChild(placeholder);
            else if (afterEl !== placeholder) tbody.insertBefore(placeholder, afterEl);
        });

        tbody.addEventListener('drop', function (e) {
            e.preventDefault();
            if (!dragging || !placeholder) return;
            if (placeholder.parentNode === tbody) tbody.insertBefore(dragging, placeholder);
        });
    }

    function saveMyFieldsOrder() {
        var tbody = document.getElementById('myFieldsSortable');
        if (!tbody) return;
        var ids = [];
        tbody.querySelectorAll('tr[data-id]').forEach(function (r) {
            var id = r.getAttribute('data-id'); if (id) ids.push(id);
        });
        var csrfEl = document.getElementById('myFieldReorderCsrf');
        var csrf = csrfEl ? csrfEl.value : '';
        fetch('/my-fields/reorder', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest' },
            body: '_csrf=' + encodeURIComponent(csrf) + '&ids=' + ids.join(',')
        }).catch(function () {});
    }

    /* ===== PDF template upload with Persian numbers ===== */
    function formatBytes(b) {
        if (!b && b !== 0) return '';
        var u = ['بایت', 'KB', 'MB', 'GB'];
        var i = 0;
        while (b >= 1024 && i < u.length - 1) { b /= 1024; i++; }
        return toFarsiNum(i === 0 ? b : b.toFixed(1)) + ' ' + u[i];
    }

    function setupPdfUpload() {
        var form    = document.getElementById('pdfTemplateForm');
        if (!form) return;

        var zone    = document.getElementById('pdfUploadZone');
        var input   = document.getElementById('pdfFileInput');
        var btn     = document.getElementById('pdfUploadBtn');
        var status  = document.getElementById('uploadStatus');
        var bar     = document.getElementById('uploadProgressBar');
        var pctEl   = document.getElementById('uploadPercent');
        var nameEl  = document.getElementById('uploadFileName');
        var sizeEl  = document.getElementById('uploadSize');
        var speedEl = document.getElementById('uploadSpeed');
        var result  = document.getElementById('uploadResult');

        function setResult(html) { result.innerHTML = html; }
        function clearResult() { result.innerHTML = ''; }

        function showFile(file) {
            nameEl.textContent = file.name;
            sizeEl.textContent = toFarsiNum('0') + ' / ' + formatBytes(file.size);
            speedEl.textContent = '';
            pctEl.textContent = toFarsiNum('0') + '%';
            bar.style.width = '0%';
            bar.classList.remove('bg-success', 'bg-danger');
            bar.classList.add('progress-bar-striped', 'progress-bar-animated');
            status.classList.remove('d-none');
            btn.disabled = false;
            clearResult();
        }

        input.addEventListener('change', function () {
            if (input.files && input.files[0]) showFile(input.files[0]);
        });

        ['dragenter', 'dragover'].forEach(function (ev) {
            zone.addEventListener(ev, function (e) {
                e.preventDefault(); e.stopPropagation();
                zone.classList.add('dragover');
            });
        });
        ['dragleave', 'drop'].forEach(function (ev) {
            zone.addEventListener(ev, function (e) {
                e.preventDefault(); e.stopPropagation();
                zone.classList.remove('dragover');
            });
        });
        zone.addEventListener('drop', function (e) {
            var dt = e.dataTransfer;
            if (dt && dt.files && dt.files[0]) {
                input.files = dt.files;
                showFile(dt.files[0]);
            }
        });

        form.addEventListener('submit', function (e) {
            e.preventDefault();
            if (!input.files || !input.files[0]) {
                setResult('<div class="upload-fail"><i class="bi bi-exclamation-triangle"></i> ابتدا یک فایل PDF انتخاب کنید.</div>');
                return;
            }

            var file = input.files[0];
            if (file.type && file.type !== 'application/pdf' &&
                !/\.pdf$/i.test(file.name)) {
                setResult('<div class="upload-fail"><i class="bi bi-exclamation-triangle"></i> فقط فایل PDF مجاز است.</div>');
                return;
            }

            var fd = new FormData(form);
            var xhr = new XMLHttpRequest();
            xhr.open('POST', form.action, true);
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.setRequestHeader('Accept', 'application/json');

            var startTs = Date.now();
            btn.disabled = true;
            btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال بارگذاری...';
            clearResult();

            xhr.upload.addEventListener('progress', function (ev) {
                if (!ev.lengthComputable) return;
                var pct = Math.round((ev.loaded / ev.total) * 100);
                bar.style.width = pct + '%';
                pctEl.textContent = toFarsiNum(pct) + '%';
                sizeEl.textContent = formatBytes(ev.loaded) + ' / ' + formatBytes(ev.total);
                var elapsed = (Date.now() - startTs) / 1000;
                var speed = elapsed > 0 ? ev.loaded / elapsed : 0;
                speedEl.textContent = formatBytes(speed) + '/s';
            });

            xhr.addEventListener('load', function () {
                bar.classList.remove('progress-bar-animated', 'progress-bar-striped');
                btn.disabled = false;
                btn.innerHTML = '<i class="bi bi-cloud-arrow-up"></i> بارگذاری قالب';

                var data = null;
                try { data = JSON.parse(xhr.responseText || '{}'); } catch (_) {}

                if (xhr.status >= 200 && xhr.status < 300 && data && data.ok) {
                    bar.style.width = '100%';
                    pctEl.textContent = toFarsiNum('100') + '%';
                    bar.classList.add('bg-success');
                    setResult(
                        '<div class="upload-done"><i class="bi bi-check-circle-fill"></i> ' +
                        escapeHtml(data.message || 'بارگذاری کامل شد.') +
                        '</div>'
                    );
                    var banner = document.getElementById('currentTemplateBanner');
                    if (banner && data.template) {
                        var fnEl = document.getElementById('currentTemplateFilename');
                        if (fnEl) { fnEl.textContent = data.template; }
                        banner.style.display = '';
                    }

                    var fieldsBody = document.getElementById('detectedFieldsBody');
                    if (fieldsBody && data.fields !== undefined) {
                        var fields = data.fields || [];
                        var inner = '<h6>فیلدهای شناسایی‌شده در PDF</h6>';
                        if (fields.length === 0) {
                            inner += '<p class="small text-muted mb-0">هیچ فیلدی در این PDF شناسایی نشد. ' +
                                     'فایل باید دارای فیلدهای فرم (Form Fields) با فرمت PDF 1.4 باشد.</p>';
                        } else {
                            inner += '<ul class="small mb-3">';
                            fields.forEach(function (f) {
                                inner += '<li><code>' + escapeHtml(f) + '</code></li>';
                            });
                            inner += '</ul>';
                            inner += '<p class="small text-muted">نام دقیق هر فیلد PDF را در ستون «نام فیلد در PDF» قرار دهید.</p>';
                        }
                        fieldsBody.innerHTML = inner;
                    }

                    if (input) { input.value = ''; }
                    setTimeout(function () {
                        status.classList.add('d-none');
                        clearResult();
                    }, 2500);
                } else {
                    bar.classList.add('bg-danger');
                    var msg = (data && data.message) ? data.message :
                              (xhr.status === 419 ? 'توکن امنیتی منقضی شده است. لطفاً صفحه را رفرش کنید.' :
                              ('خطا در بارگذاری (HTTP ' + xhr.status + ')'));
                    setResult('<div class="upload-fail"><i class="bi bi-x-circle-fill"></i> ' + escapeHtml(msg) + '</div>');
                }
            });

            xhr.addEventListener('error', function () {
                bar.classList.remove('progress-bar-animated', 'progress-bar-striped');
                bar.classList.add('bg-danger');
                btn.disabled = false;
                btn.innerHTML = '<i class="bi bi-cloud-arrow-up"></i> بارگذاری قالب';
                setResult('<div class="upload-fail"><i class="bi bi-x-circle-fill"></i> خطای شبکه. لطفاً دوباره تلاش کنید.</div>');
            });

            xhr.addEventListener('abort', function () {
                btn.disabled = false;
                btn.innerHTML = '<i class="bi bi-cloud-arrow-up"></i> بارگذاری قالب';
                setResult('<div class="upload-fail"><i class="bi bi-x-circle-fill"></i> بارگذاری لغو شد.</div>');
            });

            xhr.send(fd);
        });
    }

    /* ===== Dirty-form warning (unsaved changes) ===== */
    function setupDirtyWarning() {
        var forms = document.querySelectorAll('form[data-dirty-warn]');
        forms.forEach(function (form) {
            var dirty = false;

            form.addEventListener('change', function () { dirty = true; });
            form.addEventListener('input',  function () { dirty = true; });

            form.addEventListener('submit', function () { dirty = false; });

            window.addEventListener('beforeunload', function (e) {
                if (!dirty) return;
                var msg = 'تغییراتی ذخیره نشده دارید. آیا می‌خواهید صفحه را ترک کنید؟';
                e.preventDefault();
                e.returnValue = msg;
                return msg;
            });
        });
    }

    /* ===== Announcement bar — persistence & close button ===== */
    var ANN_KEY = 'ann_dismissed_v1';

    function annDismissed() {
        try { return JSON.parse(localStorage.getItem(ANN_KEY) || '[]'); } catch (_) { return []; }
    }
    function annSaveDismissed(list) {
        try { localStorage.setItem(ANN_KEY, JSON.stringify(list.slice(-30))); } catch (_) {}
    }

    function hideAnnBar(bar) {
        bar.style.overflow = 'hidden';
        bar.style.opacity  = '0';
        bar.style.maxHeight = bar.offsetHeight + 'px';
        requestAnimationFrame(function () {
            bar.style.maxHeight    = '0';
            bar.style.paddingTop   = '0';
            bar.style.paddingBottom = '0';
        });
        setTimeout(function () { bar.remove(); }, 350);
    }

    function setupAnnBarClose() {
        var dismissed = annDismissed();
        document.querySelectorAll('[data-ann-key]').forEach(function (bar) {
            var k = bar.getAttribute('data-ann-key');
            if (k && dismissed.indexOf(k) !== -1) {
                bar.style.setProperty('display', 'none', 'important');
            }
        });

        document.addEventListener('click', function (e) {
            var btn = e.target.closest('.ann-close-btn');
            if (!btn) return;
            var bar = btn.closest('[data-ann-key], .ann-bar, .ann-bar-img');
            if (!bar) return;
            e.preventDefault();
            var k = bar.getAttribute('data-ann-key');
            if (k) {
                var d = annDismissed();
                if (d.indexOf(k) === -1) d.push(k);
                annSaveDismissed(d);
            }
            hideAnnBar(bar);
        });
    }

    document.addEventListener('DOMContentLoaded', function () {
        setupSidebar();
        setupThemeToggle();
        setupWizard();
        setupFieldEditor();
        setupFieldLibraryDragDrop();
        setupFormsSortable();
        setupMyFormsSortable();
        setupMyFieldsSortable();
        setupPdfUpload();
        setupDirtyWarning();
        setupAnnBarClose();
        setupPersianInputs();
    });
})();
