/**
 * Fusion PDF Field Position Editor
 *
 * Features:
 *   - Drag field types from sidebar palette onto PDF to create new fields
 *   - Drag existing fields to reposition them
 *   - Resize handles on each field (bottom-right corner)
 *   - Click to select and edit properties in right panel
 *   - Percentage-based positions (0.0-1.0), same as Odoo Sign module
 *   - Auto-save on every drag/resize
 */

document.addEventListener('DOMContentLoaded', function () {
    'use strict';

    var editor = document.getElementById('pdf_field_editor');
    if (!editor) return;

    var templateId = parseInt(editor.dataset.templateId);
    var pageCount = parseInt(editor.dataset.pageCount) || 1;
    var templateCategory = editor.dataset.category || 'other';
    var currentPage = 1;
    var fields = {};
    var selectedFieldId = null;
    var fieldCounter = 0;
    var container = document.getElementById('pdf_canvas_container');
    var pageImage = document.getElementById('pdf_page_image');

    // ================================================================
    // Colors per field type
    // ================================================================

    // ================================================================
    // Available data keys, organized by template category
    // ================================================================

    var COMMON_KEYS = [
        { group: 'Client Info', keys: [
            { key: 'client_last_name',           label: 'Last Name' },
            { key: 'client_first_name',          label: 'First Name' },
            { key: 'client_middle_name',         label: 'Middle Name' },
            { key: 'client_name',                label: 'Full Name' },
            { key: 'client_street',              label: 'Street' },
            { key: 'client_unit',                label: 'Unit/Apt' },
            { key: 'client_city',                label: 'City' },
            { key: 'client_state',               label: 'Province' },
            { key: 'client_postal_code',         label: 'Postal Code' },
            { key: 'client_phone',               label: 'Phone' },
            { key: 'client_email',               label: 'Email' },
        ]},
    ];

    var CATEGORY_KEYS = {
        adp: [
            { group: 'ADP - Client Details', keys: [
                { key: 'client_health_card',         label: 'Health Card Number' },
                { key: 'client_health_card_version', label: 'Health Card Version' },
                { key: 'client_weight',              label: 'Weight (lbs)' },
            ]},
            { group: 'ADP - Client Type', keys: [
                { key: 'client_type_reg',  label: 'REG Checkbox' },
                { key: 'client_type_ods',  label: 'ODS Checkbox' },
                { key: 'client_type_acs',  label: 'ACS Checkbox' },
                { key: 'client_type_owp',  label: 'OWP Checkbox' },
            ]},
            { group: 'ADP - Consent', keys: [
                { key: 'consent_applicant',    label: 'Applicant Checkbox' },
                { key: 'consent_agent',        label: 'Agent Checkbox' },
                { key: 'consent_date',         label: 'Consent Date' },
            ]},
            { group: 'ADP - Agent Relationship', keys: [
                { key: 'agent_rel_spouse',   label: 'Spouse Checkbox' },
                { key: 'agent_rel_parent',   label: 'Parent Checkbox' },
                { key: 'agent_rel_child',    label: 'Child Checkbox' },
                { key: 'agent_rel_poa',      label: 'POA Checkbox' },
                { key: 'agent_rel_guardian', label: 'Guardian Checkbox' },
            ]},
            { group: 'ADP - Agent Info', keys: [
                { key: 'agent_last_name',       label: 'Agent Last Name' },
                { key: 'agent_first_name',      label: 'Agent First Name' },
                { key: 'agent_middle_initial',  label: 'Agent Middle Initial' },
                { key: 'agent_unit',            label: 'Agent Unit' },
                { key: 'agent_street_number',   label: 'Agent Street No.' },
                { key: 'agent_street_name',     label: 'Agent Street Name' },
                { key: 'agent_city',            label: 'Agent City' },
                { key: 'agent_province',        label: 'Agent Province' },
                { key: 'agent_postal_code',     label: 'Agent Postal Code' },
                { key: 'agent_home_phone',      label: 'Agent Home Phone' },
                { key: 'agent_business_phone',  label: 'Agent Business Phone' },
                { key: 'agent_phone_ext',       label: 'Agent Phone Ext' },
            ]},
            { group: 'ADP - Equipment', keys: [
                { key: 'equipment_type',       label: 'Equipment Type' },
                { key: 'seat_width',           label: 'Seat Width' },
                { key: 'seat_depth',           label: 'Seat Depth' },
                { key: 'seat_to_floor_height', label: 'Seat to Floor Height' },
                { key: 'back_height',          label: 'Back Height' },
                { key: 'legrest_length',       label: 'Legrest Length' },
                { key: 'cane_height',          label: 'Cane Height' },
            ]},
            { group: 'ADP - Dates', keys: [
                { key: 'assessment_start_date',    label: 'Assessment Start Date' },
                { key: 'assessment_end_date',      label: 'Assessment End Date' },
                { key: 'claim_authorization_date', label: 'Authorization Date' },
            ]},
            { group: 'ADP - Authorizer', keys: [
                { key: 'authorizer_name',  label: 'Authorizer Name' },
                { key: 'authorizer_phone', label: 'Authorizer Phone' },
                { key: 'authorizer_email', label: 'Authorizer Email' },
            ]},
            { group: 'ADP - Signatures', keys: [
                { key: 'signature_page_11', label: 'Page 11 Signature' },
                { key: 'signature_page_12', label: 'Page 12 Signature' },
            ]},
            { group: 'ADP - Other', keys: [
                { key: 'reference',               label: 'Assessment Reference' },
                { key: 'reason_for_application',  label: 'Reason for Application' },
            ]},
        ],

        odsp: [
            { group: 'ODSP - Signing Fields', keys: [
                { key: 'sa_client_name', label: 'Client Name (signing)' },
                { key: 'sa_sign_date',   label: 'Signing Date' },
                { key: 'sa_signature',   label: 'Client Signature' },
            ]},
            { group: 'ODSP - Client Details', keys: [
                { key: 'client_health_card',         label: 'Health Card Number' },
                { key: 'client_health_card_version', label: 'Health Card Version' },
                { key: 'client_weight',              label: 'Weight (lbs)' },
            ]},
            { group: 'ODSP - Dates', keys: [
                { key: 'assessment_start_date',    label: 'Assessment Start Date' },
                { key: 'assessment_end_date',      label: 'Assessment End Date' },
            ]},
            { group: 'ODSP - Authorizer', keys: [
                { key: 'authorizer_name',  label: 'Authorizer Name' },
                { key: 'authorizer_phone', label: 'Authorizer Phone' },
                { key: 'authorizer_email', label: 'Authorizer Email' },
            ]},
        ],

        mod: [
            { group: 'MOD - Dates', keys: [
                { key: 'assessment_start_date',    label: 'Assessment Start Date' },
                { key: 'assessment_end_date',      label: 'Assessment End Date' },
            ]},
            { group: 'MOD - Authorizer', keys: [
                { key: 'authorizer_name',  label: 'Authorizer Name' },
                { key: 'authorizer_phone', label: 'Authorizer Phone' },
                { key: 'authorizer_email', label: 'Authorizer Email' },
            ]},
        ],

        hardship: [
            { group: 'Hardship - Dates', keys: [
                { key: 'assessment_start_date',    label: 'Assessment Start Date' },
                { key: 'assessment_end_date',      label: 'Assessment End Date' },
            ]},
            { group: 'Hardship - Authorizer', keys: [
                { key: 'authorizer_name',  label: 'Authorizer Name' },
                { key: 'authorizer_phone', label: 'Authorizer Phone' },
                { key: 'authorizer_email', label: 'Authorizer Email' },
            ]},
        ],
    };

    var DATA_KEYS = COMMON_KEYS.concat(CATEGORY_KEYS[templateCategory] || []);

    // Build a flat lookup: key -> label
    var KEY_LABELS = {};
    DATA_KEYS.forEach(function (g) {
        g.keys.forEach(function (k) { KEY_LABELS[k.key] = k.label; });
    });

    // Build <option> HTML for the data key dropdown
    function buildDataKeyOptions(selectedKey) {
        var html = '<option value="">(custom / none)</option>';
        DATA_KEYS.forEach(function (g) {
            html += '<optgroup label="' + g.group + '">';
            g.keys.forEach(function (k) {
                html += '<option value="' + k.key + '"'
                      + (k.key === selectedKey ? ' selected' : '')
                      + '>' + k.label + ' (' + k.key + ')</option>';
            });
            html += '</optgroup>';
        });
        return html;
    }

    var COLORS = {
        text:      { bg: 'rgba(52,152,219,0.25)',  border: '#3498db' },
        checkbox:  { bg: 'rgba(46,204,113,0.25)',  border: '#2ecc71' },
        date:      { bg: 'rgba(230,126,34,0.25)',  border: '#e67e22' },
        signature: { bg: 'rgba(155,89,182,0.25)',  border: '#9b59b6' },
    };

    var DEFAULT_SIZES = {
        text:      { w: 0.150, h: 0.018 },
        checkbox:  { w: 0.018, h: 0.018 },
        date:      { w: 0.120, h: 0.018 },
        signature: { w: 0.200, h: 0.050 },
    };

    // ================================================================
    // JSONRPC helper
    // ================================================================

    function jsonrpc(url, params) {
        return fetch(url, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ jsonrpc: '2.0', method: 'call', id: 1, params: params || {} })
        }).then(function (r) { return r.json(); })
          .then(function (d) {
              if (d.error) { console.error('RPC error', d.error); return null; }
              return d.result;
          });
    }

    // ================================================================
    // Init
    // ================================================================

    function init() {
        loadFields();
        setupPageNavigation();
        setupPaletteDrag();
        setupContainerDrop();
        setupPreviewButton();
        buildDataKeysSidebar();

        // Prevent the image from intercepting drag events
        if (pageImage) {
            pageImage.style.pointerEvents = 'none';
        }
        // Also prevent any child (except field markers) from blocking drops
        container.querySelectorAll('#no_preview_placeholder').forEach(function (el) {
            el.style.pointerEvents = 'none';
        });
    }

    function buildDataKeysSidebar() {
        var list = document.getElementById('dataKeysList');
        if (!list) return;
        var html = '';
        DATA_KEYS.forEach(function (g) {
            html += '<div class="mb-1 mt-2"><strong>' + g.group + ':</strong></div>';
            g.keys.forEach(function (k) {
                html += '<code class="d-block">' + k.key + '</code>';
            });
        });
        list.innerHTML = html;
    }

    // ================================================================
    // Load fields
    // ================================================================

    function loadFields() {
        jsonrpc('/fusion/pdf-editor/fields', { template_id: templateId }).then(function (result) {
            if (!result) return;
            fields = {};
            result.forEach(function (f) { fields[f.id] = f; fieldCounter++; });
            renderFieldsForPage(currentPage);
        });
    }

    // ================================================================
    // Render fields on current page
    // ================================================================

    function renderFieldsForPage(page) {
        container.querySelectorAll('.pdf-field-marker').forEach(function (el) { el.remove(); });
        Object.values(fields).forEach(function (f) {
            if (f.page === page) renderFieldMarker(f);
        });
        updateFieldCount();
    }

    function renderFieldMarker(field) {
        var c = COLORS[field.field_type] || COLORS.text;

        var marker = document.createElement('div');
        marker.className = 'pdf-field-marker';
        marker.dataset.fieldId = field.id;
        marker.setAttribute('draggable', 'true');

        Object.assign(marker.style, {
            position: 'absolute',
            left: (field.pos_x * 100) + '%',
            top: (field.pos_y * 100) + '%',
            width: (field.width * 100) + '%',
            height: Math.max(field.height * 100, 1.5) + '%',
            backgroundColor: c.bg,
            border: '2px solid ' + c.border,
            borderRadius: '3px',
            cursor: 'move',
            display: 'flex',
            alignItems: 'center',
            fontSize: '10px',
            color: '#333',
            fontWeight: '600',
            overflow: 'hidden',
            whiteSpace: 'nowrap',
            textOverflow: 'ellipsis',
            padding: '0 4px',
            zIndex: 10,
            boxSizing: 'border-box',
            userSelect: 'none',
        });

        // Label text
        var label = document.createElement('span');
        label.style.pointerEvents = 'none';
        label.style.flex = '1';
        label.style.overflow = 'hidden';
        label.style.textOverflow = 'ellipsis';
        label.textContent = field.label || field.name;
        marker.appendChild(label);

        // Resize handle (bottom-right corner)
        var handle = document.createElement('div');
        Object.assign(handle.style, {
            position: 'absolute',
            right: '0',
            bottom: '0',
            width: '10px',
            height: '10px',
            backgroundColor: c.border,
            cursor: 'nwse-resize',
            borderRadius: '2px 0 2px 0',
            opacity: '0.7',
        });
        handle.className = 'resize-handle';
        handle.addEventListener('mousedown', function (e) {
            e.preventDefault();
            e.stopPropagation();
            startResize(field.id, e);
        });
        marker.appendChild(handle);

        // Tooltip
        marker.title = (field.label || field.name) + '\nKey: ' + (field.field_key || 'unmapped') + '\nType: ' + field.field_type;

        // Drag to reposition
        marker.addEventListener('dragstart', function (e) { onFieldDragStart(e, field.id); });
        marker.addEventListener('dragend', function (e) { e.target.style.opacity = ''; });

        // Click to select
        marker.addEventListener('click', function (e) {
            e.stopPropagation();
            selectField(field.id);
        });

        container.appendChild(marker);

        // Highlight if selected
        if (field.id === selectedFieldId) {
            marker.style.boxShadow = '0 0 0 3px #007bff';
            marker.style.zIndex = '20';
        }
    }

    // ================================================================
    // Drag existing fields to reposition
    // ================================================================

    var dragOffsetX = 0, dragOffsetY = 0;
    var dragFieldId = null;
    var dragSource = null; // 'field' or 'palette'
    var dragFieldType = null;

    function onFieldDragStart(e, fieldId) {
        dragSource = 'field';
        dragFieldId = fieldId;
        var rect = e.target.getBoundingClientRect();
        dragOffsetX = e.clientX - rect.left;
        dragOffsetY = e.clientY - rect.top;
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/plain', 'field');
        requestAnimationFrame(function () { e.target.style.opacity = '0.4'; });
    }

    // ================================================================
    // Drag from palette to create new field
    // ================================================================

    function setupPaletteDrag() {
        document.querySelectorAll('.pdf-palette-item').forEach(function (item) {
            item.addEventListener('dragstart', function (e) {
                dragSource = 'palette';
                dragFieldType = e.currentTarget.dataset.fieldType;
                dragFieldId = null;
                e.dataTransfer.effectAllowed = 'copy';
                e.dataTransfer.setData('text/plain', 'palette');
                e.currentTarget.style.opacity = '0.5';
            });
            item.addEventListener('dragend', function (e) {
                e.currentTarget.style.opacity = '';
            });
        });
    }

    // ================================================================
    // Drop handler on PDF container
    // ================================================================

    function setupContainerDrop() {
        // Must preventDefault on dragover for drop to fire
        container.addEventListener('dragover', function (e) {
            e.preventDefault();
            e.stopPropagation();
            e.dataTransfer.dropEffect = (dragSource === 'palette') ? 'copy' : 'move';
        });

        container.addEventListener('dragenter', function (e) {
            e.preventDefault();
            e.stopPropagation();
        });

        container.addEventListener('drop', function (e) {
            e.preventDefault();
            e.stopPropagation();

            // Use the container rect as the reference area
            // (the image has pointer-events:none, so we use the container which matches its size)
            var rect = container.getBoundingClientRect();

            if (dragSource === 'palette' && dragFieldType) {
                // ---- CREATE new field at drop position ----
                var defaults = DEFAULT_SIZES[dragFieldType] || DEFAULT_SIZES.text;
                var posX = (e.clientX - rect.left) / rect.width;
                var posY = (e.clientY - rect.top) / rect.height;
                posX = normalize(posX, defaults.w);
                posY = normalize(posY, defaults.h);
                posX = round3(posX);
                posY = round3(posY);

                fieldCounter++;
                var autoName = dragFieldType + '_' + fieldCounter;

                var newField = {
                    template_id: templateId,
                    name: autoName,
                    label: autoName,
                    field_type: dragFieldType,
                    field_key: autoName,
                    page: currentPage,
                    pos_x: posX,
                    pos_y: posY,
                    width: defaults.w,
                    height: defaults.h,
                    font_size: 10,
                };

                jsonrpc('/fusion/pdf-editor/create-field', newField).then(function (res) {
                    if (res && res.id) {
                        newField.id = res.id;
                        fields[res.id] = newField;
                        renderFieldsForPage(currentPage);
                        selectField(res.id);
                    }
                });

            } else if (dragSource === 'field' && dragFieldId && fields[dragFieldId]) {
                // ---- MOVE existing field ----
                var field = fields[dragFieldId];
                var posX = (e.clientX - rect.left - dragOffsetX) / rect.width;
                var posY = (e.clientY - rect.top - dragOffsetY) / rect.height;
                posX = normalize(posX, field.width);
                posY = normalize(posY, field.height);
                posX = round3(posX);
                posY = round3(posY);

                field.pos_x = posX;
                field.pos_y = posY;
                saveField(field.id, { pos_x: posX, pos_y: posY });
                renderFieldsForPage(currentPage);
                selectField(field.id);
            }

            dragSource = null;
            dragFieldId = null;
            dragFieldType = null;
        });
    }

    // ================================================================
    // Resize handles
    // ================================================================

    function startResize(fieldId, startEvent) {
        var field = fields[fieldId];
        if (!field) return;

        var imgRect = container.getBoundingClientRect();
        var startX = startEvent.clientX;
        var startY = startEvent.clientY;
        var startW = field.width;
        var startH = field.height;
        var marker = container.querySelector('[data-field-id="' + fieldId + '"]');

        function onMove(e) {
            var dx = (e.clientX - startX) / imgRect.width;
            var dy = (e.clientY - startY) / imgRect.height;
            var newW = Math.max(startW + dx, 0.010);
            var newH = Math.max(startH + dy, 0.005);

            // Clamp to page bounds
            if (field.pos_x + newW > 1.0) newW = 1.0 - field.pos_x;
            if (field.pos_y + newH > 1.0) newH = 1.0 - field.pos_y;

            field.width = round3(newW);
            field.height = round3(newH);

            if (marker) {
                marker.style.width = (field.width * 100) + '%';
                marker.style.height = Math.max(field.height * 100, 1.5) + '%';
            }
        }

        function onUp() {
            document.removeEventListener('mousemove', onMove);
            document.removeEventListener('mouseup', onUp);
            saveField(fieldId, { width: field.width, height: field.height });
            renderFieldsForPage(currentPage);
            selectField(fieldId);
        }

        document.addEventListener('mousemove', onMove);
        document.addEventListener('mouseup', onUp);
    }

    // ================================================================
    // Select field and show properties
    // ================================================================

    function selectField(fieldId) {
        selectedFieldId = fieldId;
        var field = fields[fieldId];
        if (!field) return;

        // Re-render to update highlights
        renderFieldsForPage(currentPage);

        var panel = document.getElementById('field_props_body');
        panel.innerHTML = ''
            + '<div class="mb-2">'
            + '  <label class="form-label fw-bold small mb-0">Data Key</label>'
            + '  <select class="form-select form-select-sm" id="prop_field_key">'
            + buildDataKeyOptions(field.field_key || '')
            + '  </select>'
            + '</div>'
            + row('Name', 'text', 'prop_name', field.name || '')
            + row('Label', 'text', 'prop_label', field.label || '')
            + '<div class="mb-2">'
            + '  <label class="form-label fw-bold small mb-0">Type</label>'
            + '  <select class="form-select form-select-sm" id="prop_type">'
            + '    <option value="text"' + sel(field.field_type, 'text') + '>Text</option>'
            + '    <option value="checkbox"' + sel(field.field_type, 'checkbox') + '>Checkbox</option>'
            + '    <option value="signature"' + sel(field.field_type, 'signature') + '>Signature</option>'
            + '    <option value="date"' + sel(field.field_type, 'date') + '>Date</option>'
            + '  </select>'
            + '</div>'
            + '<div class="row mb-2">'
            + '  <div class="col-6">' + row('Font Size', 'number', 'prop_font_size', field.font_size || 10, '0.5') + '</div>'
            + '  <div class="col-6">' + row('Page', 'number', 'prop_page', field.page || 1) + '</div>'
            + '</div>'
            + '<div class="row mb-2">'
            + '  <div class="col-6">' + row('Width', 'number', 'prop_width', field.width || 0.15, '0.005') + '</div>'
            + '  <div class="col-6">' + row('Height', 'number', 'prop_height', field.height || 0.015, '0.005') + '</div>'
            + '</div>'
            + '<div class="row mb-2">'
            + '  <div class="col-6"><label class="form-label fw-bold small mb-0">X</label>'
            + '    <input type="text" class="form-control form-control-sm" value="' + round3(field.pos_x) + '" readonly/></div>'
            + '  <div class="col-6"><label class="form-label fw-bold small mb-0">Y</label>'
            + '    <input type="text" class="form-control form-control-sm" value="' + round3(field.pos_y) + '" readonly/></div>'
            + '</div>'
            + '<div class="mb-2">'
            + '  <label class="form-label fw-bold small mb-0">Text Align</label>'
            + '  <div class="btn-group w-100" role="group">'
            + '    <button type="button" class="btn btn-sm btn-outline-secondary' + (field.text_align === 'left' || !field.text_align ? ' active' : '') + '" data-align="left"><i class="fa fa-align-left"></i></button>'
            + '    <button type="button" class="btn btn-sm btn-outline-secondary' + (field.text_align === 'center' ? ' active' : '') + '" data-align="center"><i class="fa fa-align-center"></i></button>'
            + '    <button type="button" class="btn btn-sm btn-outline-secondary' + (field.text_align === 'right' ? ' active' : '') + '" data-align="right"><i class="fa fa-align-right"></i></button>'
            + '  </div>'
            + '</div>'
            + '<div class="d-flex gap-2 mt-3">'
            + '  <button type="button" class="btn btn-primary btn-sm flex-grow-1" id="btn_save_props">'
            + '    <i class="fa fa-save me-1"></i>Save</button>'
            + '  <button type="button" class="btn btn-outline-danger btn-sm" id="btn_delete_field">'
            + '    <i class="fa fa-trash me-1"></i>Delete</button>'
            + '</div>';

        // Auto-fill name and label when data key is selected
        document.getElementById('prop_field_key').addEventListener('change', function () {
            var selectedKey = this.value;
            if (selectedKey && KEY_LABELS[selectedKey]) {
                document.getElementById('prop_name').value = selectedKey;
                document.getElementById('prop_label').value = KEY_LABELS[selectedKey];
            }
        });

        var alignBtns = panel.querySelectorAll('[data-align]');
        alignBtns.forEach(function (btn) {
            btn.addEventListener('click', function () {
                alignBtns.forEach(function (b) { b.classList.remove('active'); });
                btn.classList.add('active');
            });
        });

        document.getElementById('btn_save_props').addEventListener('click', function () {
            var keySelect = document.getElementById('prop_field_key');
            var selectedKey = keySelect ? keySelect.value : '';
            var activeAlign = panel.querySelector('[data-align].active');
            var vals = {
                name: val('prop_name'),
                label: val('prop_label'),
                field_key: selectedKey,
                field_type: val('prop_type'),
                font_size: parseFloat(val('prop_font_size')) || 10,
                page: parseInt(val('prop_page')) || 1,
                width: parseFloat(val('prop_width')) || 0.15,
                height: parseFloat(val('prop_height')) || 0.015,
                text_align: activeAlign ? activeAlign.dataset.align : 'left',
            };
            Object.assign(field, vals);
            saveField(fieldId, vals);
            renderFieldsForPage(currentPage);
            selectField(fieldId);
        });

        document.getElementById('btn_delete_field').addEventListener('click', function () {
            if (!confirm('Delete "' + (field.label || field.name) + '"?')) return;
            jsonrpc('/fusion/pdf-editor/delete-field', { field_id: fieldId }).then(function () {
                delete fields[fieldId];
                selectedFieldId = null;
                renderFieldsForPage(currentPage);
                panel.innerHTML = '<p class="text-muted small">Field deleted.</p>';
            });
        });
    }

    // ================================================================
    // Save field to server
    // ================================================================

    function saveField(fieldId, values) {
        jsonrpc('/fusion/pdf-editor/update-field', { field_id: fieldId, values: values });
    }

    // ================================================================
    // Page navigation
    // ================================================================

    function setupPageNavigation() {
        var prev = document.getElementById('btn_prev_page');
        var next = document.getElementById('btn_next_page');
        if (prev) prev.addEventListener('click', function () { if (currentPage > 1) switchPage(--currentPage); });
        if (next) next.addEventListener('click', function () { if (currentPage < pageCount) switchPage(++currentPage); });
    }

    function switchPage(page) {
        currentPage = page;
        var d = document.getElementById('current_page_display');
        if (d) d.textContent = page;
        jsonrpc('/fusion/pdf-editor/page-image', { template_id: templateId, page: page }).then(function (r) {
            if (r && r.image_url && pageImage) pageImage.src = r.image_url;
            renderFieldsForPage(page);
        });
    }

    // ================================================================
    // Preview
    // ================================================================

    function setupPreviewButton() {
        var btn = document.getElementById('btn_preview');
        if (btn) btn.addEventListener('click', function () {
            window.open('/fusion/pdf-editor/preview/' + templateId, '_blank');
        });
    }

    // ================================================================
    // Helpers
    // ================================================================

    function normalize(pos, dim) {
        if (pos < 0) return 0;
        if (pos + dim > 1.0) return 1.0 - dim;
        return pos;
    }

    function round3(n) { return Math.round((n || 0) * 1000) / 1000; }

    function val(id) { var el = document.getElementById(id); return el ? el.value : ''; }

    function sel(current, option) { return current === option ? ' selected' : ''; }

    function row(label, type, id, value, step) {
        return '<div class="mb-2"><label class="form-label fw-bold small mb-0">' + label + '</label>'
             + '<input type="' + type + '" class="form-control form-control-sm" id="' + id + '"'
             + ' value="' + value + '"' + (step ? ' step="' + step + '"' : '') + '/></div>';
    }

    function updateFieldCount() {
        var el = document.getElementById('field_count');
        if (el) el.textContent = Object.keys(fields).length;
    }

    // ================================================================
    // Start
    // ================================================================

    init();
});
