// ---- Configuracao ----
// Troque pelos enderecos reais antes de publicar.
const AGENT_URL = "http://127.0.0.1:8765";
const PUBLIC_API_URL = "https://gestao.cloud2m.com.br/v1/public";
const INSTALLER_URL = "https://gestao.cloud2m.com.br/downloads/AssinadorAgent-Setup.exe";

// ---- Elementos ----
const sections = {
  checking: document.getElementById("state-checking"),
  disconnected: document.getElementById("state-disconnected"),
  ready: document.getElementById("state-ready"),
  done: document.getElementById("state-done"),
};

const machineLabel = document.getElementById("machine-label");
const greeting = document.getElementById("greeting");
const certPickerWrap = document.getElementById("cert-picker-wrap");
const certPicker = document.getElementById("cert-picker");
const dropzone = document.getElementById("dropzone");
const fileInput = document.getElementById("file-input");
const fileList = document.getElementById("file-list");
const signControls = document.getElementById("sign-controls");
const pinInput = document.getElementById("pin-input");
const signButton = document.getElementById("sign-button");
const formError = document.getElementById("form-error");
const retryButton = document.getElementById("retry-connection");
const downloadInstallerLink = document.getElementById("download-installer-link");
const doneHeading = document.getElementById("done-heading");
const doneSub = document.getElementById("done-sub");
const resultList = document.getElementById("result-list");
const signMoreButton = document.getElementById("sign-more");

// Configuração do link do instalador
if (downloadInstallerLink) {
  downloadInstallerLink.href = INSTALLER_URL;
  downloadInstallerLink.setAttribute("download", "AssinadorAgent-Setup.exe");
  downloadInstallerLink.removeAttribute("target"); // Remove a abertura em nova aba que trava o download
}

// ---- Estado ----
let pendingFiles = []; // [{ id, file }]
let certificates = [];

function showState(name) {
  Object.entries(sections).forEach(([key, el]) => {
    if (el) el.hidden = key !== name;
  });
}

function setFormError(message) {
  if (formError) {
    formError.textContent = message || "";
    formError.hidden = !message;
  }
}

// ---- Conexao com o agente ----

async function checkConnection() {
  showState("checking");
  try {
    const identity = await fetchJSON(`${AGENT_URL}/identity`);
    const certsResult = await fetchJSON(`${AGENT_URL}/certificates`);

    certificates = certsResult.certificates || [];
    if (certificates.length === 0) {
      throw new Error("Nenhum certificado encontrado no token conectado.");
    }

    await setupClientGreeting(identity.client_id, identity.machine_id);
    setupCertificatePicker();
    showState("ready");
  } catch (err) {
    console.warn("Nao foi possivel conectar ao assinador:", err.message);
    showState("disconnected");
  }
}

async function setupClientGreeting(clientId, machineId) {
  if (machineLabel) machineLabel.textContent = `Máquina ${machineId.slice(0, 8)}`;
  if (greeting) greeting.textContent = "Bem-vindo.";

  if (!clientId) return;

  try {
    const { name } = await fetchJSON(`${PUBLIC_API_URL}/clients/${clientId}`);
    if (name && greeting) greeting.textContent = `Bem-vindo, ${name}.`;
  } catch (err) {
    console.warn("Nao foi possivel buscar o nome do cliente:", err.message);
  }
}

function setupCertificatePicker() {
  if (!certPickerWrap || !certPicker) return;

  if (certificates.length <= 1) {
    certPickerWrap.hidden = true;
    return;
  }
  certPicker.innerHTML = "";
  certificates.forEach((cert) => {
    const option = document.createElement("option");
    option.value = cert.id;
    option.textContent = cert.label;
    certPicker.appendChild(option);
  });
  certPickerWrap.hidden = false;
}

function selectedCertId() {
  return certificates.length <= 1 ? certificates[0].id : certPicker.value;
}

async function fetchJSON(url, options) {
  const res = await fetch(url, options);
  const body = await res.json().catch(() => ({}));
  if (!res.ok) {
    throw new Error(body.error || `Erro ${res.status} ao chamar ${url}`);
  }
  return body;
}

// ---- Selecao de arquivos ----

let fileIdCounter = 0;

function addFiles(fileArray) {
  const pdfFiles = fileArray.filter((f) => f.type === "application/pdf" || f.name.toLowerCase().endsWith(".pdf"));
  pdfFiles.forEach((file) => {
    pendingFiles.push({ id: `f${fileIdCounter++}`, file, status: "pendente" });
  });
  renderFileList();
}

function removeFile(id) {
  pendingFiles = pendingFiles.filter((f) => f.id !== id);
  renderFileList();
}

function renderFileList() {
  if (!fileList || !signControls) return;

  fileList.hidden = pendingFiles.length === 0;
  signControls.hidden = pendingFiles.length === 0;
  fileList.innerHTML = "";

  pendingFiles.forEach(({ id, file, status }) => {
    const li = document.createElement("li");
    li.className = "file-row";
    li.dataset.fileId = id;

    const name = document.createElement("span");
    name.className = "file-name";
    name.textContent = file.name;

    const statusEl = document.createElement("span");
    statusEl.className = "file-status";
    statusEl.textContent = status;

    const removeBtn = document.createElement("button");
    removeBtn.className = "file-remove";
    removeBtn.setAttribute("aria-label", `Remover ${file.name}`);
    removeBtn.textContent = "×";
    removeBtn.addEventListener("click", () => removeFile(id));

    li.append(name, statusEl, removeBtn);
    fileList.appendChild(li);
  });
}

if (dropzone) {
  dropzone.addEventListener("click", () => fileInput && fileInput.click());
  dropzone.addEventListener("keydown", (e) => {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault();
      if (fileInput) fileInput.click();
    }
  });
}

if (fileInput) {
  fileInput.addEventListener("change", (e) => {
    addFiles(Array.from(e.target.files));
    fileInput.value = "";
  });
}

if (dropzone) {
  ["dragenter", "dragover"].forEach((evt) =>
    dropzone.addEventListener(evt, (e) => {
      e.preventDefault();
      dropzone.classList.add("is-dragover");
    })
  );
  ["dragleave", "drop"].forEach((evt) =>
    dropzone.addEventListener(evt, (e) => {
      e.preventDefault();
      dropzone.classList.remove("is-dragover");
    })
  );
  dropzone.addEventListener("drop", (e) => {
    addFiles(Array.from(e.dataTransfer.files));
  });
}

// ---- Assinatura ----

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result.split(",")[1]);
    reader.onerror = () => reject(new Error(`Falha ao ler ${file.name}`));
    reader.readAsDataURL(file);
  });
}

function updateFileStatus(id, status, className) {
  if (!fileList) return;
  const row = fileList.querySelector(`[data-file-id="${id}"] .file-status`);
  if (!row) return;
  row.textContent = status;
  row.className = `file-status ${className || ""}`.trim();
}

function triggerDownload(blob, filename) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
  setTimeout(() => URL.revokeObjectURL(url), 10000);
}

function signedFilename(originalName) {
  return originalName.replace(/\.pdf$/i, "") + "-assinado.pdf";
}

if (signButton) {
  signButton.addEventListener("click", async () => {
    setFormError(null);
    const pin = pinInput ? pinInput.value : "";
    if (!pin) {
      setFormError("Informe o PIN do certificado.");
      return;
    }
    if (pendingFiles.length === 0) return;

    signButton.disabled = true;
    const results = [];

    for (const entry of pendingFiles) {
      updateFileStatus(entry.id, "assinando", "is-signing");
      try {
        const pdfBase64 = await fileToBase64(entry.file);
        const response = await fetchJSON(`${AGENT_URL}/sign-pdf`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            cert_id: selectedCertId(),
            pin,
            pdf_base64: pdfBase64,
            reason: "Assinatura digital",
          }),
        });

        const signedBytes = Uint8Array.from(atob(response.pdf_base64), (c) => c.charCodeAt(0));
        const blob = new Blob([signedBytes], { type: "application/pdf" });
        const filename = signedFilename(entry.file.name);

        triggerDownload(blob, filename);
        updateFileStatus(entry.id, "concluído", "is-done");
        results.push({ name: entry.file.name, filename, blob, ok: true });
      } catch (err) {
        updateFileStatus(entry.id, "erro", "is-error");
        results.push({ name: entry.file.name, ok: false, error: err.message });
      }
    }

    signButton.disabled = false;
    if (pinInput) pinInput.value = "";
    showResults(results);
  });
}

function showResults(results) {
  const successCount = results.filter((r) => r.ok).length;
  if (doneHeading) {
    doneHeading.textContent = successCount === results.length
      ? "Documentos assinados."
      : `${successCount} de ${results.length} documentos assinados.`;
  }
  if (doneSub) {
    doneSub.textContent = successCount === results.length
      ? "O download começou automaticamente. Use os links abaixo se precisar baixar de novo."
      : "Alguns documentos não puderam ser assinados. Veja os detalhes abaixo.";
  }

  if (resultList) {
    resultList.innerHTML = "";
    results.forEach((r) => {
      const li = document.createElement("li");
      li.className = "file-row";

      const name = document.createElement("span");
      name.className = "file-name";
      name.textContent = r.name;

      if (r.ok) {
        const link = document.createElement("a");
        link.className = "file-download";
        link.textContent = "Baixar novamente";
        link.href = "#";
        link.addEventListener("click", (e) => {
          e.preventDefault();
          triggerDownload(r.blob, r.filename);
        });
        li.append(name, link);
      } else {
        const status = document.createElement("span");
        status.className = "file-status is-error";
        status.textContent = r.error;
        li.append(name, status);
      }

      resultList.appendChild(li);
    });
  }

  showState("done");
}

if (signMoreButton) {
  signMoreButton.addEventListener("click", () => {
    pendingFiles = [];
    renderFileList();
    setFormError(null);
    showState("ready");
  });
}

if (retryButton) {
  retryButton.addEventListener("click", checkConnection);
}

// ---- Inicializacao ----
checkConnection();