make this into a pandadoc clone <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Enhanced PDF E-Signature Tool</title>
  <script src="https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/signature_pad/4.1.5/signature_pad.umd.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
      color: #333;
    }

    .container {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }

    .toolbar {
      display: flex;
      padding: 10px;
      justify-content: space-between;
      gap: 10px;
      background-color: #f4f4f8;
      border-bottom: 1px solid #ddd;
    }

    .toolbar button, input[type="file"], select {
      padding: 8px 12px;
      font-size: 14px;
      border: none;
      background: #0071f2;
      color: white;
      border-radius: 5px;
      cursor: pointer;
      transition: background 0.3s;
    }

    .toolbar button:hover, input[type="file"]:hover {
      background: #005bb5;
    }

    #pdfViewer {
      flex: 1;
      display: flex;
      overflow: hidden;
    }

    #pageThumbnails {
      width: 150px;
      overflow-y: auto;
      padding: 10px;
      border-right: 1px solid #ddd;
      background: #fff;
    }

    #pageThumbnails img {
      display: block;
      width: 100%;
      margin-bottom: 10px;
      border: 1px solid transparent;
      cursor: pointer;
    }

    #pageThumbnails img.active {
      border-color: #0071f2;
    }

    .pdfCanvasWrapper {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      background: #e5e5e5;
    }

    canvas {
      border: 1px solid #ccc;
    }

    .field {
      position: absolute;
      border: 1px dashed gray;
      padding: 5px;
      background-color: #fff;
      cursor: move;
      font-size: 14px;
      min-width: 80px;
      box-sizing: border-box;
    }

     .field.highlight {
        border-color: blue;
      }

    .field .resizer {
      position: absolute;
      right: 0;
      bottom: 0;
      width: 10px;
      height: 10px;
      background: #ccc;
      cursor: se-resize;
    }


    .footer {
      text-align: center;
      padding: 10px;
      background-color: #f4f4f8;
      border-top: 1px solid #ddd;
    }

    #modalOverlay {
      display: none;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.5);
    }

    #propertiesModal {
      display: none;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      padding: 20px;
      background: white;
      box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
      border-radius: 8px;
      width: 350px;
      z-index: 2000;
    }

    input[type="text"], input[type="checkbox"], textarea, select {
      width: calc(100% - 20px);
      font-size: 14px;
      padding: 8px;
      margin-bottom: 10px;
      border: 1px solid #ccc;
      border-radius: 4px;
      outline: none;
       box-sizing: border-box;
    }

    input:focus, textarea:focus, select:focus {
      border-color: #0071f2;
    }

    button.modal-btn {
      display: inline-block;
      padding: 8px 16px;
      font-size: 14px;
      border-radius: 5px;
      border: none;
      cursor: pointer;
    }

    button.modal-btn.delete {
      color: red;
      background: #ffebe9;
    }

    button.modal-btn.save {
      color: green;
      background: #e9ffeb;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="toolbar">
      <input type="file" id="fileUpload" accept=".pdf">
      <button id="addTextField">Add Text Field</button>
      <button id="addSignatureField">Add Signature Field</button>
       <button id="addDropdownField">Add Dropdown Field</button>
        <button id="addCheckboxField">Add Checkbox Field</button>
      <button id="previousPage">Previous Page</button>
      <button id="nextPage">Next Page</button>
      <button id="finalizePDF">Finalize PDF</button>
      <button id="saveDraft">Save Draft</button>
      <input type="file" id="loadDraft" accept=".json" style="display:none;"/>
      <label for="loadDraft" style="cursor:pointer">Load Draft</label>
      <button id="zoomIn">Zoom In</button>
      <button id="zoomOut">Zoom Out</button>
      <select id="signerToggle">
          <option value="Signer1">Signer 1</option>
          <option value="Signer2">Signer 2</option>
      </select>
    </div>

    <div id="pdfViewer">
      <div id="pageThumbnails"></div>
      <div class="pdfCanvasWrapper">
        <canvas id="pdfCanvas"></canvas>
      </div>
    </div>

    <div class="footer">
      <span>Certificate ID:</span>
      <span id="certificateId"></span>
    </div>
  </div>

  <div id="modalOverlay"></div>
  <div id="propertiesModal">
    <h3>Field Properties</h3>
    <input type="text" placeholder="Field Name" id="fieldName">
    <textarea placeholder="Field Description (optional)" id="fieldDescription"></textarea>
     <input type="text" placeholder="Field Options (comma-separated)" id="fieldOptions" style="display:none"/>
    <label>Required:
      <input type="checkbox" id="fieldRequired">
    </label>

    <button class="modal-btn save" id="saveProperties">Save Changes</button>
    <button class="modal-btn delete" id="deleteField">Delete Field</button>
  </div>

  <script>
    // PDF Variables
    let pdfDoc = null;
    let canvas = document.getElementById("pdfCanvas");
    let ctx = canvas.getContext("2d");
    let currentPage = 1;
    let scale = 1.5;

    // Certificate
    let certificateId = `CERT-${Math.random().toString(36).substring(2, 10).toUpperCase()}`;
    document.getElementById("certificateId").innerText = certificateId;

    // Load PDF
    document.getElementById("fileUpload").addEventListener("change", async (e) => {
      const file = e.target.files[0];
      if (!file) return;

      const reader = new FileReader();
      reader.onload = async function () {
        const pdfArray = new Uint8Array(reader.result);
        pdfDoc = await PDFLib.PDFDocument.load(pdfArray);
        currentPage = 1;
        renderPDF();
      };
      reader.readAsArrayBuffer(file);
    });

async function renderPDF() {
      const page = pdfDoc.getPages()[currentPage - 1];
      const viewport = { width: page.getWidth() * scale, height: page.getHeight() * scale };

      canvas.width = viewport.width;
      canvas.height = viewport.height;

      const pageImage = await page.render({ scale: scale });
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(pageImage.imageData, 0, 0, viewport.width, viewport.height);

      renderThumbnails();
      renderFields();
    }

    document.getElementById("previousPage").addEventListener("click", () => {
      if (currentPage <= 1) return;
      currentPage--;
      renderPDF();
    });

    document.getElementById("nextPage").addEventListener("click", () => {
      if (currentPage >= pdfDoc.getPageCount()) return;
      currentPage++;
      renderPDF();
    });

async function renderThumbnails() {
      const thumbnailContainer = document.getElementById("pageThumbnails");
      thumbnailContainer.innerHTML = ""; // Clear existing thumbnails

      for (let i = 0; i < pdfDoc.getPageCount(); i++) {
        const page = pdfDoc.getPages()[i];
        const viewport = { width: 100, height: page.getHeight() * (100 / page.getWidth()) };

        const canvas = document.createElement("canvas");
        canvas.width = viewport.width;
        canvas.height = viewport.height;

        const ctx = canvas.getContext("2d");
        const pageImage = await page.render({ scale: 100 / page.getWidth() });
        ctx.drawImage(pageImage.imageData, 0, 0, viewport.width, viewport.height);

        canvas.addEventListener("click", () => {
          currentPage = i + 1;
          renderPDF();
        });

        thumbnailContainer.appendChild(canvas);
        if (i + 1 === currentPage) canvas.classList.add("active");
      }
    }

let fields = [];

    document.getElementById("addTextField").addEventListener("click", () => addField("text"));
    document.getElementById("addSignatureField").addEventListener("click", () => addField("signature"));
     document.getElementById("addDropdownField").addEventListener("click", () => addField("dropdown"));
    document.getElementById("addCheckboxField").addEventListener("click", () => addField("checkbox"));


    function addField(type) {
      const field = {
        id: `field-${Date.now()}`,
        type,
        page: currentPage,
        x: 50,
        y: 50,
        required: false,
           signer: activeSigner,
         options: []
      };

      fields.push(field);
      renderFields();
    }

    function renderFields() {
      const wrapper = document.querySelector(".pdfCanvasWrapper");
      wrapper.querySelectorAll(".field").forEach((field) => field.remove()); // Clear existing fields

      fields.forEach((field) => {
        if (field.page !== currentPage) return;

        const div = document.createElement("div");
        div.className = `field field-${field.type} ${field.signer === activeSigner ? "highlight" : ""}`;
        div.style.top = `${field.y}px`;
        div.style.left = `${field.x}px`;
          if (field.type === "text") {
               div.innerText = field.value || "Text Field";
              } else if (field.type === "dropdown") {
                   const select = document.createElement("select");
                     field.options.forEach(option => {
                            const opt = document.createElement("option");
                            opt.value = option;
                             opt.innerText = option;
                               select.appendChild(opt);
                    });
                     div.appendChild(select);
                } else if (field.type === "checkbox") {
                 const checkbox = document.createElement("input");
                   checkbox.type = "checkbox";
                  div.appendChild(checkbox);
              } else {
                  div.innerHTML = field.type === "text" ? "Text Field" : "Signature Field";
              }


        // Allow dragging
        div.addEventListener("mousedown", (e) => startDragging(e, field, div));

        // Open properties modal on double-click
        div.addEventListener("dblclick", () => openPropertiesModal(field));

         makeResizable(div);

        wrapper.appendChild(div);
      });
    }

    let dragField = null;
    let startX = 0;
    let startY = 0;

    function startDragging(e, field, div) {
      dragField = field;
      startX = e.clientX - parseInt(div.style.left);
      startY = e.clientY - parseInt(div.style.top);

      document.addEventListener("mousemove", dragFieldHandler);
      document.addEventListener("mouseup", stopDragging);
    }

    function dragFieldHandler(e) {
      if (!dragField) return;

      const wrapper = document.querySelector(".pdfCanvasWrapper");
      const parentRect = wrapper.getBoundingClientRect();

      const x = Math.min(Math.max(e.clientX - parentRect.left - startX, 0), parentRect.width - 50);
      const y = Math.min(Math.max(e.clientY - parentRect.top - startY, 0), parentRect.height - 20);

      dragField.x = x;
      dragField.y = y;
      renderFields();
    }

    function stopDragging() {
      dragField = null;
      document.removeEventListener("mousemove", dragFieldHandler);
      document.removeEventListener("mouseup", stopDragging);
    }

const modalOverlay = document.getElementById("modalOverlay");
    const propertiesModal = document.getElementById("propertiesModal");

    function openPropertiesModal(field) {
      propertiesModal.style.display = "block";
      modalOverlay.style.display = "block";
    document.getElementById("fieldOptions").style.display = field.type === 'dropdown' ? 'block' : 'none';

      document.getElementById("fieldName").value = field.name ?? "";
      document.getElementById("fieldDescription").value = field.description ?? "";
      document.getElementById("fieldRequired").checked = field.required;
       document.getElementById("fieldOptions").value = field.options ? field.options.join(',') : "";

      document.getElementById("saveProperties").onclick = () => {
        field.name = document.getElementById("fieldName").value;
        field.description = document.getElementById("fieldDescription").value;
        field.required = document.getElementById("fieldRequired").checked;
          field.options = document.getElementById("fieldOptions").value.split(',').map(option => option.trim()).filter(option => option);


        closePropertiesModal();
          renderFields();
      };

      document.getElementById("deleteField").onclick = () => {
        fields = fields.filter((f) => f !== field);
        closePropertiesModal();
        renderFields();
      };
    }

    function closePropertiesModal() {
      propertiesModal.style.display = "none";
      modalOverlay.style.display = "none";
    }

document.getElementById("finalizePDF").addEventListener("click", async () => {
      if (!validateFields()) {
        alert("Please complete all required fields!");
        return;
      }

      const signedPdfDoc = await PDFLib.PDFDocument.create();
      const pages = pdfDoc.getPages();

      for (let i = 0; i < pages.length; i++) {
        const copiedPage = await signedPdfDoc.copyPages(pdfDoc, [i]);
        const pdfPage = copiedPage[0];

        // Draw all fields as text
        fields
          .filter((field) => field.page === i + 1)
          .forEach((field) => {
              if (field.type === "text" || field.type === "dropdown") {
                pdfPage.drawText(field.value || field.name || (field.type === "text" ? "Text" : "Dropdown"), {
                    x: field.x,
                  y: pdfPage.getHeight() - field.y - 20,
                    size: 12,
                });
            } else if(field.type === 'checkbox'){
                 pdfPage.drawText("[X]", {
                   x: field.x,
                    y: pdfPage.getHeight() - field.y - 20,
                     size: 12,
                });
               } else {
            pdfPage.drawText(field.type === "signature" ? "[Signed]" : "[Field]", {
              x: field.x,
              y: pdfPage.getHeight() - field.y - 20,
              size: 12,
            });
                }
          });

        signedPdfDoc.addPage(pdfPage);
      }

      const pdfBytes = await signedPdfDoc.save();
      const blob = new Blob([pdfBytes], { type: "application/pdf" });
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = `signed-document-${certificateId}.pdf`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    });

    function validateFields() {
      return fields.every((field) => (field.required ? field.name || field.value : true));
    }

document.getElementById("saveDraft").addEventListener("click", () => {
      const draft = JSON.stringify({ fields, currentPage, certificateId });
      const blob = new Blob([draft], { type: "application/json" });
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = "draft.json";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    });

    document.getElementById("loadDraft").addEventListener("click", async (e) => {
      const file = e.target.files[0];
      if (!file) return;

      const reader = new FileReader();
      reader.onload = () => {
        const { fields: loadedFields, currentPage: loadedPage, certificateId: loadedCertificate } = JSON.parse(reader.result);
        fields = loadedFields;
        currentPage = loadedPage;
        certificateId = loadedCertificate;

        document.getElementById("certificateId").innerText = certificateId;
        renderPDF();
        renderFields();
      };
      reader.readAsText(file);
    });


function validateFields() {
  let isValid = true;

  fields.forEach(field => {
    if (field.required) {
        if (field.type === "text" && !field.value) {
            alert(`Field "${field.name}" is required!`);
        isValid = false;
    }
        if (field.type === "dropdown" && !field.value) {
             alert(`Field "${field.name}" is required!`);
        isValid = false;
      }
    }
  });
  return isValid;
}

// Add support for multiple signers
let activeSigner = "Signer1";
const signers = ["Signer1", "Signer2"];

document.getElementById("signerToggle").addEventListener("change", event => {
  activeSigner = event.target.value; // Switch active signer
  renderFields();
});


function makeResizable(fieldElement) {
  const resizer = document.createElement("div");
  resizer.className = "resizer";
  fieldElement.appendChild(resizer);

  resizer.addEventListener("mousedown", e => {
    const startWidth = parseInt(window.getComputedStyle(fieldElement).width, 10);
    const startHeight = parseInt(window.getComputedStyle(fieldElement).height, 10);
    const startX = e.pageX;
    const startY = e.pageY;

    function resize(e) {
      const newWidth = startWidth + e.pageX - startX;
      const newHeight = startHeight + e.pageY - startY;
      fieldElement.style.width = `${Math.max(newWidth, 50)}px`; // Ensure minimum width
      fieldElement.style.height = `${Math.max(newHeight, 20)}px`; // Ensure minimum height
    }

    function stopResize() {
      document.removeEventListener("mousemove", resize);
      document.removeEventListener("mouseup", stopResize);
    }

    document.addEventListener("mousemove", resize);
    document.addEventListener("mouseup", stopResize);
  });
}

document.getElementById("zoomIn").addEventListener("click", () => {
  scale += 0.25;
  renderPDF();
});

document.getElementById("zoomOut").addEventListener("click", () => {
  if (scale > 0.5) {
    scale -= 0.25;
    renderPDF();
  }
});
const gun = Gun();
const docData = gun.get("pdfDocument"); // Shared document data

// Save and sync fields in real-time
fields.forEach(field => {
  docData.set(field); // Synced to other connected clients
});

// Listen for changes made by others in real-time
docData.on(updatedData => {
  fields = updatedData;
  renderFields(); // Update fields on UI
});
  </script>
</body>
</html>