<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>DocuSign Template Builder</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
    <style>
        /* ------------------------------
   General Reset
------------------------------ */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background: #f3f4f6;
            overflow: hidden;
            font-family: Arial, sans-serif;
        }

        /* ------------------------------
   Layout
------------------------------ */
        .main-container {
            display: flex;
            height: 100vh;
        }

        .left-tools {
            width: 250px;
            background: #fff;
            padding: 15px;
            border-right: 1px solid #ddd;
            overflow-y: auto;
            flex-shrink: 0;
        }

        .field-btn {
            width: 100%;
            margin-bottom: 10px;
            border: 2px dashed #1d4ed8;
            background: #e0ecff;
            cursor: grab;
            transition: all 0.2s;
        }

        .field-btn:active {
            cursor: grabbing;
        }

        .field-btn:hover {
            background: #c7d2fe;
            border-color: #1e40af;
        }

        .canvas-area {
            flex: 1;
            padding: 20px;
            background: #e5e7eb;
            height: 100vh;
            overflow-y: auto;
            display: flex;
            justify-content: center;
        }

        #pdfPages {
            width: 100%;
            max-width: 850px;
        }

        .pdf-page {
            position: relative;
            margin: 0 auto 20px;
            background: #fff;
            box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.1);
            width: 100%;
        }

        .pdf-canvas {
            width: 100%;
            height: auto;
            display: block;
        }

        /* ------------------------------
   Field Overlay (labels & draggable)
------------------------------ */
        .field-overlay {
            position: absolute;
            border: 2px solid #2563eb;
            /* main border */
            background: rgba(37, 99, 235, 0.1);
            /* light transparent background */
            padding: 2px 6px;
            cursor: move;
            font-size: 12px;
            font-weight: 600;
            border-radius: 4px;
            color: #1e40af;
            user-select: none;
            min-width: 80px;
            min-height: 25px;
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: visible;
            /* ensure text isn’t clipped */
            white-space: nowrap;
            /* prevent text wrapping */
            text-align: center;
        }

        .field-overlay:hover {
            background: rgba(37, 99, 235, 0.2);
            border-color: #1e40af;
        }

        /* Remove button */
        .field-overlay .remove-btn {
            position: absolute;
            top: -8px;
            right: -8px;
            width: 20px;
            height: 20px;
            background: #ef4444;
            color: white;
            border: none;
            border-radius: 50%;
            cursor: pointer;
            font-size: 14px;
            line-height: 1;
            display: none;
        }

        .field-overlay:hover .remove-btn {
            display: block;
        }

        /* Static label inside field (non-editable) */
        .field-label {
            display: inline-block;
            text-overflow: ellipsis;
            overflow: hidden;
            max-width: 100%;
        }


        /* Editable text field inside overlay */
        .field-overlay .editable-label {
            pointer-events: auto;
            /* allow typing */
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        /* Synced fields highlight */
        .synced-field {
            background-color: rgba(208, 211, 214, 0.15);
            border: 1px dashed #007bff;
            color: #007bff;
        }


        /* ------------------------------
   Zoom Controls
------------------------------ */
        .zoom-controls {
            position: fixed;
            right: 20px;
            top: 20px;
            background: white;
            padding: 10px 16px;
            border-radius: 8px;
            box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.15);
            display: flex;
            gap: 12px;
            align-items: center;
            z-index: 1000;
        }

        .zoom-controls button {
            width: 32px;
            height: 32px;
            padding: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        #zoomLevel {
            min-width: 50px;
            text-align: center;
            font-weight: 600;
        }

        /* ------------------------------
   Field Counter / Info
------------------------------ */
        .field-count {
            background: #eff6ff;
            border: 1px solid #bfdbfe;
            border-radius: 6px;
            padding: 8px;
            margin-top: 10px;
            font-size: 13px;
            color: #1e40af;
        }

        .pdf-page {
            position: relative;
        }

        .field {
            position: absolute;
        }
    </style>
</head>

<body>
    <div class="main-container">
        <div class="left-tools">
            <h5 class="mb-3">📋 Field Types</h5>
            <button class="btn field-btn" draggable="true" ondragstart="dragField(event,'Signature')">✍️ Signature</button>
            <button class="btn field-btn" draggable="true" ondragstart="dragField(event,'Full Name')">🧑 Full Name</button>
            <button class="btn field-btn" draggable="true" ondragstart="dragField(event,'Email')">📧 Email</button>
            <button class="btn field-btn" draggable="true" ondragstart="dragField(event,'Date')">📅 Date</button>
            <button class="btn field-btn" draggable="true" ondragstart="dragField(event,'Text')">📝 Text</button>
            <button class="btn field-btn" draggable="true" ondragstart="dragField(event,'Checkbox')">☑️ Checkbox</button>
            <hr class="my-3">
            <div class="mb-3">
                <label class="form-label small">Template ID</label>
                <!-- template_id comes from backend PHP -->
            </div>
            <!-- <button class="btn btn-primary w-100 mb-2" id="loadBtn">📄 Load Document</button> -->
            <!-- <button class="btn btn-info w-100 mb-2" id="syncBtn">🔄 Sync Existing Fields</button> -->
            <button class="btn btn-success w-100" id="saveFieldsBtn">💾 Save Fields</button>
            <div class="field-count mt-3" id="fieldCount">
                <strong>Fields Added:</strong> <span id="fieldCountNum">0</span>
            </div>
        </div>
        <div class="canvas-area" id="pdfWrapper">
            <div id="pdfPages"></div>
        </div>
    </div>

    <div class="zoom-controls">
        <button class="btn btn-outline-dark btn-sm" id="zoomOut">➖</button>
        <span id="zoomLevel">100%</span>
        <button class="btn btn-outline-dark btn-sm" id="zoomIn">➕</button>
    </div>

    <script>
        // ------------------------------
        // Directly get values from PHP
        // ------------------------------
        // const BASE_URL = "http://192.168.18.106:8000";
        const BASE_URL = "<?= base_url(); ?>";
        console.log("BASE_URL:", BASE_URL);

        const templateId = "<?= $template_id ?>";
        const docId = "<?= $doc_id ?>";

        console.log("Template ID:", templateId);
        // console.log("Doc ID:", docId);

        let pdfDoc = null;
        let scale = 1.5;
        let fields = [];
        let lastPdfBase64 = null;
        let fieldCounter = 0;

        // --- DRAG & DROP ---
        function dragField(e, type) {
            e.dataTransfer.setData("fieldType", type);
            e.dataTransfer.effectAllowed = "copy";
        }

        document.getElementById("pdfWrapper").addEventListener("dragover", (e) => e.preventDefault());
        document.getElementById("pdfWrapper").addEventListener("drop", async (e) => {
            e.preventDefault();
            const fieldType = e.dataTransfer.getData("fieldType");
            if (!fieldType) return;
            const pageDiv = e.target.closest(".pdf-page");
            if (!pageDiv) return;
            const pageNum = Number(pageDiv.getAttribute("data-page"));
            const rect = pageDiv.getBoundingClientRect();
            const xPx = e.clientX - rect.left;
            const yPx = e.clientY - rect.top;
            const pdfPage = await pdfDoc.getPage(pageNum);
            const viewport = pdfPage.getViewport({
                scale: 1
            });
            addFieldToCanvas(fieldType, xPx, yPx, pageNum, rect.width, rect.height, viewport.width, viewport.height);
        });

        // --- FIELD HANDLERS ---
        function addFieldToCanvas(fieldType, xPx, yPx, pageNum, pageWidth, pageHeight, pdfWidth, pdfHeight, isSynced = false, label = null) {
            const page = document.querySelector(`.pdf-page[data-page="${pageNum}"]`);
            if (!page) return;

            const fieldId = `field_${++fieldCounter}`;

            let field = document.createElement("div");
            field.className = isSynced ? "field-overlay synced-field" : "field-overlay";
            field.id = fieldId;

            // Display label
            let displayLabel = label || fieldType;
            const labelSpan = document.createElement("span");
            labelSpan.textContent = displayLabel;
            labelSpan.className = "field-label";

            if (fieldType === "Text") {
                labelSpan.contentEditable = "true";
                labelSpan.setAttribute("role", "textbox");
                labelSpan.setAttribute("aria-label", "Edit field label");
                labelSpan.addEventListener("input", () => {
                    // update fields array live while typing
                    const f = fields.find(f => f.id === fieldId);
                    if (f) f.label = labelSpan.textContent;
                    // optional: mark as modified (could be used visually)
                    element.classList.add('label-editing');
                });

                // on blur, ensure final value is saved and remove editing class
                labelSpan.addEventListener("blur", () => {
                    const f = fields.find(f => f.id === fieldId);
                    if (f) f.label = labelSpan.textContent.trim() || fieldType;
                    element.classList.remove('label-editing');
                });

                // allow Enter to finish editing (prevent newline)
                labelSpan.addEventListener("keydown", (ev) => {
                    if (ev.key === "Enter") {
                        ev.preventDefault();
                        labelSpan.blur();
                    }
                });
            }


            field.appendChild(labelSpan);

            // **Set canvas coordinates directly**
            field.style.left = xPx + "px";
            field.style.top = yPx + "px";

            const removeBtn = document.createElement("button");
            removeBtn.className = "remove-btn";
            removeBtn.textContent = "×";
            removeBtn.onclick = () => removeField(fieldId);
            field.appendChild(removeBtn);

            page.appendChild(field);

            makeDraggable(field, page, pdfWidth, pdfHeight);

            const fieldWidthPx = 120; // your overlay width in px
            const fieldHeightPx = 30; // your overlay height in px

            // Convert canvas pixels to PDF points
            const x = Math.round((xPx / pageWidth) * pdfWidth);
            const y = Math.round(pdfHeight - ((yPx + fieldHeightPx) / pageHeight) * pdfHeight);
            const width = Math.round((fieldWidthPx / pageWidth) * pdfWidth);
            const height = Math.round((fieldHeightPx / pageHeight) * pdfHeight);

            fields.push({
                id: fieldId,
                fieldType,
                label: displayLabel,
                x, // PDF points
                y, // PDF points (bottom-left origin)
                pageNum,
                xPx,
                yPx,
                originalWidth: pageWidth,
                originalHeight: pageHeight,
                pdfWidth,
                pdfHeight,
                width, // PDF points
                height // PDF points
            });


            updateFieldCount();
        }

        function makeDraggable(element, container, originalWidth, originalHeight) {
            let isDragging = false,
                startX, startY, initialLeft, initialTop;

            const startDrag = (x, y) => {
                isDragging = true;
                startX = x;
                startY = y;
                initialLeft = element.offsetLeft;
                initialTop = element.offsetTop;
                element.style.cursor = "grabbing";
                element.style.zIndex = 1000;
            };
            const dragMove = (x, y) => {
                if (!isDragging) return;
                const dx = x - startX,
                    dy = y - startY;
                const newLeft = Math.max(0, Math.min(initialLeft + dx, container.clientWidth - element.offsetWidth));
                const newTop = Math.max(0, Math.min(initialTop + dy, container.clientHeight - element.offsetHeight));
                element.style.left = newLeft + "px";
                element.style.top = newTop + "px";
                const fieldData = fields.find(f => f.id === element.id);
                if (fieldData) {
                    fieldData.xPx = newLeft;
                    fieldData.yPx = newTop;
                    fieldData.x = Math.round((newLeft / container.clientWidth) * originalWidth);
                    fieldData.y = Math.round((newTop / container.clientHeight) * originalHeight);
                }
            };
            const endDrag = () => {
                if (!isDragging) return;
                isDragging = false;
                element.style.cursor = "move";
                element.style.zIndex = "";
            };
            element.addEventListener("mousedown", e => {
                // Ignore clicks on remove button or editable label span
                if (e.target.classList.contains("remove-btn") || e.target.classList.contains("field-label")) return;
                startDrag(e.clientX, e.clientY);
                e.preventDefault();
            });

            document.addEventListener("mousemove", e => dragMove(e.clientX, e.clientY));
            document.addEventListener("mouseup", endDrag);

            element.addEventListener("touchstart", e => {
                if (e.target.classList.contains("remove-btn") || e.target.classList.contains("field-label")) return;
                const touch = e.touches[0];
                startDrag(touch.clientX, touch.clientY);
                e.stopPropagation();
            }, {
                passive: true
            });

            element.addEventListener("touchmove", e => {
                if (!isDragging) return;
                const touch = e.touches[0];
                dragMove(touch.clientX, touch.clientY);
                e.preventDefault();
            }, {
                passive: false
            });
            element.addEventListener("touchend", endDrag);
            element.addEventListener("touchcancel", endDrag);
        }

        function removeField(fieldId) {
            fields = fields.filter(f => f.id !== fieldId);
            document.getElementById(fieldId)?.remove();
            updateFieldCount();
        }

        function updateFieldCount() {
            document.getElementById("fieldCountNum").textContent = fields.length;
        }

        function getFieldDisplayNameFromTabType(tabType) {
            const map = {
                signHereTabs: "Signature",
                fullNameTabs: "Full Name",
                emailTabs: "Email",
                dateSignedTabs: "Date",
                textTabs: "Text",
                checkboxTabs: "Checkbox"
            };
            console.log(map);
            return map[tabType] || tabType;
        }

        async function loadDocument(templateId) {
            if (!templateId) return;

            Swal.fire({
                title: "Loading PDF...",
                allowOutsideClick: false,
                didOpen: () => Swal.showLoading()
            });

            try {
                const res = await axios.post(`${BASE_URL}docusign/getTemplateWithFields`, {
                    template_id: templateId
                });

                console.log(res.data);


                if (!res.data.success) return Swal.fire("Error", res.data.message, "error");

                lastPdfBase64 = res.data.fileBase64;

                // Render PDF pages
                await renderPDF(lastPdfBase64);

                // Wait until all pages are ready
                await new Promise((resolve) => {
                    const checkPages = () => {
                        const allReady = Array.from(document.querySelectorAll(".pdf-page"))
                            .every(page => page.getBoundingClientRect().width > 0);
                        if (allReady) resolve();
                        else setTimeout(checkPages, 10);
                    };
                    checkPages();
                });

                // Load and position the fields
                for (const f of res.data.fields) {
                    const pageNum = parseInt(f.pageNumber);
                    const pageDiv = document.querySelector(`.pdf-page[data-page="${pageNum}"]`);
                    if (!pageDiv) continue;

                    const rect = pageDiv.getBoundingClientRect();
                    const pdfPage = await pdfDoc.getPage(pageNum);
                    const viewport = pdfPage.getViewport({
                        scale: 1
                    });

                    const pdfWidth = viewport.width;
                    const pdfHeight = viewport.height;
                    console.log("rect.height:", rect.height, "pdfHeight:", pdfHeight);

                    // --- SCALE FACTORS ---
                    const scaleX = rect.width / pdfWidth;
                    const scaleY = rect.height / pdfHeight;

                    // --- COORDINATE CONVERSION ---
                    // DocuSign: bottom-left origin
                    // Canvas: top-left origin
                    const xPx = f.xPosition * scaleX;
                    const yPx = f.yPosition * scaleY;

                    console.log('xpy: ', xPx);
                    console.log('ypx: ', yPx)
                    const label = f.value || f.label || getFieldDisplayNameFromTabType(f.type);

                    addFieldToCanvas(
                        getFieldDisplayNameFromTabType(f.type),
                        xPx,
                        yPx,
                        pageNum,
                        rect.width,
                        rect.height,
                        pdfWidth,
                        pdfHeight,
                        true,
                        f.label,
                        label
                    );
                }


                Swal.close();
            } catch (err) {
                Swal.fire("Error", err.message, "error");
            }
        }

        async function renderPDF(base64pdf) {
            const container = document.getElementById("pdfPages");
            container.innerHTML = "";
            fields = [];
            fieldCounter = 0;
            updateFieldCount();
            try {
                const pdfData = atob(base64pdf);
                pdfDoc = await pdfjsLib.getDocument({
                    data: pdfData
                }).promise;

                // Wait for all pages to render
                const pagePromises = [];
                for (let i = 1; i <= pdfDoc.numPages; i++) {
                    pagePromises.push(renderPage(i));
                }
                await Promise.all(pagePromises); // <-- ensures all pages exist before proceeding
            } catch (err) {
                Swal.fire("Error", "Failed to render PDF", "error");
            }
        }

        async function renderPage(num) {
            const page = await pdfDoc.getPage(num);
            const viewport = page.getViewport({
                scale
            });
            const pageDiv = document.createElement("div");
            pageDiv.className = "pdf-page";
            pageDiv.setAttribute("data-page", num);
            const canvas = document.createElement("canvas");
            canvas.className = "pdf-canvas";
            canvas.height = viewport.height;
            canvas.width = viewport.width;
            pageDiv.appendChild(canvas);
            document.getElementById("pdfPages").appendChild(pageDiv);
            await page.render({
                canvasContext: canvas.getContext("2d"),
                viewport
            });
        }

        // --- INIT ---
        document.addEventListener("DOMContentLoaded", async () => {
            if (templateId) await loadDocument(templateId);
            // document.getElementById("saveFieldsBtn").setAttribute("disabled", true);
            document.getElementById("saveFieldsBtn").classList.add("btn-secondary");

        });

        document.getElementById("zoomIn").addEventListener("click", () => changeZoom(0.2));
        document.getElementById("zoomOut").addEventListener("click", () => changeZoom(-0.2));

        function changeZoom(delta) {
            scale = Math.min(Math.max(scale + delta, 0.8), 3);
            document.getElementById("zoomLevel").textContent = Math.round(scale * 100) + "%";
            if (lastPdfBase64) renderPDF(lastPdfBase64);
        }

        // --- SAVE FIELDS ---
        function convertFieldType(type) {
            const map = {
                "Signature": "signHere",
                "Full Name": "fullName",
                "Email": "email",
                "Date": "dateSigned",
                "Text": "text",
                "Checkbox": "checkbox"
            };
            return map[type] || "text";
        }

        //  Required Fields Validation (Signature must exist)
        function validateRequiredFields() {
            const saveBtn = document.getElementById("saveFieldsBtn");

            const hasSignature = fields.some(f => f.fieldType === "Signature");

            if (hasSignature) {
                saveBtn.removeAttribute("disabled");
                saveBtn.classList.remove("btn-secondary");
                saveBtn.classList.add("btn-success");
            } else {
                saveBtn.setAttribute("disabled", true);
                saveBtn.classList.remove("btn-success");
                saveBtn.classList.add("btn-secondary");
            }
        }

        //  Trigger validation on change
        function updateFieldCount() {
            document.getElementById("fieldCountNum").textContent = fields.length;
            validateRequiredFields();
        }

        async function saveFields() {
            const payload = {
                template_id: templateId,
                fileName: "loaded-document.pdf",
                documentBase64: lastPdfBase64,
                doc_id: docId,
                fields: fields.map(f => {
                    // Calculate normalized positions (0-1 range)
                    const normalizedX = f.xPx / f.originalWidth;
                    const normalizedY = f.yPx / f.originalHeight;
                    const normalizedWidth = 120 / f.originalWidth; // 120px is your field width
                    const normalizedHeight = 30 / f.originalHeight; // 30px is your field height

                    // Apply the SAME scaling as View 1 (multiply by 500 and 700)
                    const docusignX = Math.round(normalizedX * 500);
                    const docusignY = Math.round(normalizedY * 700);
                    const docusignWidth = Math.round(normalizedWidth * 500);
                    const docusignHeight = Math.round(normalizedHeight * 700);

                    return {
                        id: f.id,
                        label: f.label || f.fieldType || f.id,
                        value: f.label,
                        type: convertFieldType(f.fieldType),
                        pageNumber: f.pageNum,
                        x: docusignX,
                        y: docusignY,
                        width: docusignWidth,
                        height: docusignHeight
                    };
                })
            };

            Swal.fire({
                title: "Saving Fields...",
                allowOutsideClick: false,
                didOpen: () => Swal.showLoading()
            });

            try {
                const res = await axios.post(`${BASE_URL}docusign/add-fields`, payload);

                if (res.data?.success === 1) {
                    Swal.fire({
                        icon: "success",
                        title: "Template Created!",
                        html: `<div class="text-start">
                    <p><strong>Fields Added:</strong> ${res.data.fieldsCount}</p>
                    <p><strong>Template ID:</strong><br><code>${res.data.templateId}</code></p>
                </div>`,
                        showConfirmButton: true
                    });
                } else Swal.fire("⚠ Error", res.data.message || "Something went wrong!", "warning");
            } catch (err) {
                Swal.fire("Error", err.response?.data?.message || err.message, "error");
            }
        }
        document.getElementById("saveFieldsBtn").addEventListener("click", saveFields);
    </script>
</body>


</html>