let baseUrl = "http://127.0.0.1:5000";
let printersCache = [];
let selectedPrinterIndex = -1;

async function api(path, opts = {}) {
  const headers = { "Content-Type": "application/json", ...(opts.headers || {}) };
  const res = await fetch(`${baseUrl}${path}`, { ...opts, headers });
  const text = await res.text();
  let data;
  try {
    data = JSON.parse(text);
  } catch {
    data = text;
  }
  if (!res.ok) throw new Error(typeof data === "object" ? data.error || res.statusText : text);
  return data;
}

async function init() {
  if (window.sirayaPrinter) {
    baseUrl = (await window.sirayaPrinter.getServiceUrl()) || baseUrl;
    window.sirayaPrinter.onSetupProgress((msg) => showBanner(msg));
    const setup = await window.sirayaPrinter.runSetup();
    if (setup?.setupResult && !setup.setupResult.ok) {
      showBanner(`Setup: ${setup.setupResult.error}`, true);
    }
  }

  document.querySelectorAll(".nav").forEach((btn) => {
    btn.addEventListener("click", () => switchTab(btn.dataset.tab));
  });

  document.getElementById("btnTestPrint").onclick = testPrint;
  document.getElementById("btnOpenDesignerDash").onclick = openDesigner;
  document.getElementById("btnStartSvc").onclick = () => svcAction("start");
  document.getElementById("btnStopSvc").onclick = () => svcAction("stop");
  document.getElementById("btnRestartSvc").onclick = () => svcAction("restart");
  document.getElementById("btnSavePrinter").onclick = savePrinter;
  document.getElementById("btnRescan").onclick = rescanPrinters;
  document.getElementById("btnRefreshLogs").onclick = loadLogs;
  document.getElementById("btnExportDiag").onclick = exportDiag;
  document.getElementById("btnSaveSettings").onclick = saveSettings;
  document.getElementById("btnSaveBusiness").onclick = saveBusiness;
  document.getElementById("btnCopyKey").onclick = copyApiKey;
  document.getElementById("btnRegenKey").onclick = regenApiKey;
  document.getElementById("btnPreviewTemplate").onclick = previewTemplate;
  document.getElementById("btnOpenDesigner").onclick = openDesigner;

  await refreshAll();
  setInterval(refreshDashboard, 15000);
}

function openDesigner() {
  window.open(`${baseUrl}/designer`, "_blank");
}

function switchTab(name) {
  document.querySelectorAll(".nav").forEach((b) => b.classList.toggle("active", b.dataset.tab === name));
  document.querySelectorAll(".tab").forEach((t) => t.classList.toggle("active", t.id === `tab-${name}`));
  if (name === "history") loadHistory();
  if (name === "logs") loadLogs();
  if (name === "templates") loadTemplates();
  if (name === "settings") loadSettings();
  if (name === "business") loadBusiness();
  if (name === "printers") loadPrinters();
}

function showBanner(msg, isErr) {
  const el = document.getElementById("setupBanner");
  el.textContent = msg;
  el.className = isErr ? "banner err" : "banner";
  el.classList.remove("hidden");
}

function formatUptime(sec) {
  if (!sec || sec < 60) return `${sec || 0}s`;
  const m = Math.floor(sec / 60);
  if (m < 60) return `${m}m`;
  const h = Math.floor(m / 60);
  return `${h}h ${m % 60}m`;
}

async function refreshAll() {
  await refreshDashboard();
  await loadServiceStatus();
  await loadPrinters();
}

async function refreshDashboard() {
  try {
    const h = await api("/health");
    baseUrl = h.serviceUrl || baseUrl;
    document.getElementById("appVersion").textContent = `v${h.version || "3.0.0"}`;
    const printerLabel = h.printerConnected
      ? h.printer?.name || "Connected"
      : h.printer?.name
        ? `${h.printer.name} (offline)`
        : "None detected";
    document.getElementById("dashboardCards").innerHTML = `
      <div class="card ${h.ok ? "ok" : "err"}"><div class="label">Agent</div><div class="value">${h.ok ? "Online" : "Offline"}</div></div>
      <div class="card"><div class="label">Queue</div><div class="value">${h.queueDepth ?? 0}</div></div>
      <div class="card ${h.printerConnected ? "ok" : "warn"}"><div class="label">Printer</div><div class="value" style="font-size:1rem">${escapeHtml(printerLabel)}</div></div>
      <div class="card"><div class="label">Uptime</div><div class="value">${formatUptime(h.uptimeSec)}</div></div>
    `;
    document.getElementById("setupBanner").classList.add("hidden");
  } catch (e) {
    document.getElementById("dashboardCards").innerHTML = `<div class="card err"><div class="label">Agent</div><div class="value">Offline</div></div>`;
    showBanner(`Cannot reach print agent at ${baseUrl}. ${e.message}`, true);
  }
}

function escapeHtml(s) {
  return String(s)
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

async function loadServiceStatus() {
  let scm = { state: "unknown" };
  if (window.sirayaPrinter) scm = await window.sirayaPrinter.getServiceStatus();
  document.getElementById("serviceStatus").textContent = JSON.stringify(scm, null, 2);
}

async function svcAction(action) {
  if (!window.sirayaPrinter) return;
  if (action === "start") await window.sirayaPrinter.startService();
  if (action === "stop") await window.sirayaPrinter.stopService();
  if (action === "restart") await window.sirayaPrinter.restartService();
  await loadServiceStatus();
  await refreshDashboard();
}

function renderPrinterList(list, activeName) {
  const container = document.getElementById("printerList");
  const empty = document.getElementById("printerEmpty");
  container.innerHTML = "";

  if (!list.length) {
    empty.classList.remove("hidden");
    selectedPrinterIndex = -1;
    return;
  }
  empty.classList.add("hidden");

  list.forEach((p, i) => {
    const card = document.createElement("div");
    card.className = "printer-card" + (p.name === activeName ? " selected" : "");
    card.dataset.index = String(i);
    card.innerHTML = `
      <div class="meta">
        <div class="name">${escapeHtml(p.name)}</div>
        <div class="type">${escapeHtml(p.type || "Unknown")}${p.driver ? " · " + escapeHtml(p.driver) : ""}</div>
      </div>
      <span class="badge">${escapeHtml((p.type || "printer").split("/")[0])}</span>
    `;
    card.onclick = () => {
      selectedPrinterIndex = i;
      document.querySelectorAll(".printer-card").forEach((c) => c.classList.remove("selected"));
      card.classList.add("selected");
    };
    container.appendChild(card);
    if (p.name === activeName) selectedPrinterIndex = i;
  });

  if (selectedPrinterIndex < 0 && list.length) {
    selectedPrinterIndex = 0;
    container.querySelector(".printer-card")?.classList.add("selected");
  }
}

async function loadPrinters() {
  try {
    const list = await api("/printers");
    printersCache = list;
    const st = await api("/status");
    const active = st.printer?.name || "";
    renderPrinterList(list, active);
    document.getElementById("printerStatus").textContent = JSON.stringify(st.printer || { status: "No printer selected" }, null, 2);
  } catch (e) {
    document.getElementById("printerStatus").textContent = e.message;
    document.getElementById("printerEmpty").classList.remove("hidden");
    document.getElementById("printerList").innerHTML = "";
  }
}

async function savePrinter() {
  if (selectedPrinterIndex < 0) {
    alert("Select a printer first");
    return;
  }
  await api("/select-printer", { method: "POST", body: JSON.stringify({ index: selectedPrinterIndex }) });
  await loadPrinters();
  await refreshDashboard();
}

async function rescanPrinters() {
  const btn = document.getElementById("btnRescan");
  btn.disabled = true;
  btn.textContent = "Scanning…";
  try {
    const data = await api("/rescan", { method: "POST", body: "{}" });
    printersCache = data.printers || [];
    await loadPrinters();
  } finally {
    btn.disabled = false;
    btn.textContent = "Scan for printers";
  }
}

async function testPrint() {
  await api("/print", {
    method: "POST",
    body: JSON.stringify({
      orderNumber: `TEST-${Date.now()}`,
      orderType: "dine-in",
      items: [{ name: "Test Item", quantity: 1, price: 100, total: 100 }],
      subtotal: 100,
      total: 100,
    }),
  });
  alert("Test print queued");
}

async function loadHistory() {
  const tbody = document.querySelector("#historyTable tbody");
  tbody.innerHTML = "";
  try {
    const data = await api("/print/history?limit=50");
    for (const j of data.jobs || []) {
      const tr = document.createElement("tr");
      tr.innerHTML = `<td>${j.printJobId?.slice(0, 12)}…</td><td>${j.receiptKind || "-"}</td><td>${j.state}</td><td>${j.updatedAt || ""}</td><td><button class="btn" data-id="${j.printJobId}">Retry</button></td>`;
      tr.querySelector("button").onclick = async () => {
        await api(`/print/history/${j.printJobId}/retry`, { method: "POST", body: "{}" });
        loadHistory();
      };
      tbody.appendChild(tr);
    }
  } catch (e) {
    tbody.innerHTML = `<tr><td colspan="5">${e.message}</td></tr>`;
  }
}

async function loadTemplates() {
  try {
    const data = await api("/api/templates");
    const sel = document.getElementById("templateSelect");
    sel.innerHTML = "";
    for (const t of data.manifest?.templates || []) {
      const o = document.createElement("option");
      o.value = t.id;
      o.textContent = t.name;
      sel.appendChild(o);
    }
  } catch (e) {
    document.getElementById("templatePreview").textContent = e.message;
  }
}

async function previewTemplate() {
  const id = document.getElementById("templateSelect").value;
  if (!id) return;
  const data = await api(`/api/templates/${id}/preview`, { method: "POST", body: "{}" });
  document.getElementById("templatePreview").textContent = data.previewText || "";
}

async function loadLogs() {
  try {
    const data = await api("/logs/json");
    let out = "";
    for (const f of data.files || []) out += `=== ${f.name} ===\n${f.content}\n\n`;
    document.getElementById("logsView").textContent = out || "No logs";
  } catch {
    const text = await fetch(`${baseUrl}/logs`).then((r) => r.text());
    document.getElementById("logsView").textContent = text;
  }
}

async function exportDiag() {
  const text = await fetch(`${baseUrl}/support/export`).then((r) => r.text());
  const blob = new Blob([text], { type: "text/plain" });
  const a = document.createElement("a");
  a.href = URL.createObjectURL(blob);
  a.download = `siraya-diagnostics-${Date.now()}.txt`;
  a.click();
}

async function loadBusiness() {
  const s = await api("/settings");
  const b = s.business || {};
  document.getElementById("bizName").value = b.name || "";
  document.getElementById("bizBranch").value = b.branch || "";
  document.getElementById("bizPhone").value = b.phone || "";
  document.getElementById("bizWhatsapp").value = b.whatsapp || "";
  document.getElementById("bizWebsite").value = b.website || "";
  document.getElementById("bizTagline").value = b.tagline || "";
  document.getElementById("bizAddress").value = b.address || "";
  document.getElementById("bizNtn").value = b.ntn || "";
  document.getElementById("bizStrn").value = b.strn || "";
}

async function saveBusiness() {
  const msg = document.getElementById("businessMsg");
  try {
    await api("/settings", {
      method: "PUT",
      body: JSON.stringify({
        business: {
          name: document.getElementById("bizName").value.trim(),
          branch: document.getElementById("bizBranch").value.trim(),
          phone: document.getElementById("bizPhone").value.trim(),
          whatsapp: document.getElementById("bizWhatsapp").value.trim(),
          website: document.getElementById("bizWebsite").value.trim(),
          tagline: document.getElementById("bizTagline").value.trim(),
          address: document.getElementById("bizAddress").value.trim(),
          ntn: document.getElementById("bizNtn").value.trim(),
          strn: document.getElementById("bizStrn").value.trim(),
        },
      }),
    });
    msg.textContent = "Business profile saved.";
    msg.className = "msg ok";
  } catch (e) {
    msg.textContent = e.message;
    msg.className = "msg err";
  }
}

async function loadSettings() {
  const s = await api("/settings");
  baseUrl = s.serviceUrl || baseUrl;
  document.getElementById("settingServiceUrl").value = s.serviceUrl || baseUrl;
  document.getElementById("settingPort").value = s.port || 5000;
  document.getElementById("settingCors").value = (s.corsOrigins || []).join(", ");
  document.getElementById("settingAuthEnforced").checked = Boolean(s.authEnforced);
  try {
    const key = await api("/settings/api-key");
    document.getElementById("settingApiKey").value = key.apiKey || "";
  } catch {
    document.getElementById("settingApiKey").value = s.apiKeyPreview || "";
  }
}

async function saveSettings() {
  const msg = document.getElementById("settingsMsg");
  try {
    await api("/settings", {
      method: "PUT",
      body: JSON.stringify({
        port: parseInt(document.getElementById("settingPort").value, 10),
        corsOrigins: document.getElementById("settingCors").value.split(",").map((s) => s.trim()).filter(Boolean),
        authEnforced: document.getElementById("settingAuthEnforced").checked,
      }),
    });
    msg.textContent = "Settings saved. Restart service if port changed.";
    msg.className = "msg ok";
  } catch (e) {
    msg.textContent = e.message;
    msg.className = "msg err";
  }
}

async function copyApiKey() {
  const key = document.getElementById("settingApiKey").value;
  await navigator.clipboard.writeText(key);
  document.getElementById("settingsMsg").textContent = "API key copied";
}

async function regenApiKey() {
  const data = await api("/settings/regenerate-api-key", { method: "POST", body: "{}" });
  document.getElementById("settingApiKey").value = data.apiKey || "";
}

init();
