// client.js
// UI: Buttons, Anzeige von Result als JSON + Baum, Fallback für Commands

function appendLog(line) {
  const el = document.getElementById("log");
  if (!el) return;

  const now = new Date().toISOString();
  el.value += `[${now}] ${line}\n`;
  el.scrollTop = el.scrollHeight;
}

function clearTextarea(id) {
  const el = document.getElementById(id);
  if (el) el.value = "";
}

function clearElement(id) {
  const el = document.getElementById(id);
  if (el) el.innerHTML = "";
}

function formatScalar(value) {
  if (value === null) return "null";
  if (value === undefined) return "undefined";
  if (typeof value === "string") return JSON.stringify(value);
  if (typeof value === "number" && Number.isFinite(value)) return String(value);
  if (typeof value === "boolean") return String(value);
  return String(value);
}

function renderTree(container, value, key = "result", open = true) {
  if (!container) return;

  container.innerHTML = "";
  container.appendChild(renderNode(key, value, open));
}

function renderNode(key, value, open = false) {
  const isObject = value !== null && typeof value === "object";

  if (!isObject) {
    const leaf = document.createElement("div");
    leaf.className = "tree-leaf";
    leaf.textContent = `${key}: ${formatScalar(value)}`;
    return leaf;
  }

  const details = document.createElement("details");
  details.open = open;

  const summary = document.createElement("summary");
  summary.textContent = Array.isArray(value)
    ? `${key} [${value.length}]`
    : key;

  details.appendChild(summary);

  const body = document.createElement("div");
  body.style.marginLeft = "16px";

  if (Array.isArray(value)) {
    value.forEach((item, idx) => {
      body.appendChild(renderNode(String(idx), item, false));
    });
  } else {
    Object.entries(value).forEach(([childKey, childVal]) => {
      body.appendChild(renderNode(childKey, childVal, false));
    });
  }

  details.appendChild(body);
  return details;
}

function renderResult(result) {
  const jsonEl = document.getElementById("result-json");
  const treeEl = document.getElementById("result-tree");

  if (jsonEl) {
    jsonEl.value = JSON.stringify(result, null, 2);
  }

  renderTree(treeEl, result, "result", true);
}

async function fetchCSV() {
  const res = await fetch("/api/latest-snapshot");
  if (!res.ok) throw new Error("Fehler beim Laden des Snapshots");

  let data;
  if (res.headers.get("content-type")?.includes("application/json")) {
    data = await res.json();
  } else {
    const csvData = await res.text();
    data = {
      filename: "latest.csv",
      mtime: new Date().toISOString(),
      content: csvData
    };
  }

  const lines = data.content.trim().split(/\r?\n/).filter(Boolean);
  if (lines.length < 2) {
    throw new Error("Keine oder unvollständige Daten");
  }

  const headers = lines[0].split(",").map(h => h.trim());

  const rows = lines.slice(1).map(line => {
    const cells = line.split(",");
    const obj = {};
    headers.forEach((h, i) => {
      const raw = (cells[i] ?? "").trim();
      const numeric = Number(raw);
      obj[h] = raw !== "" && Number.isFinite(numeric) ? numeric : raw;
    });
    return obj;
  });

  return { data, headers, rows };
}

async function renderSnapshot() {
  const table = document.getElementById("snapshot-table");
  const pictureEl = document.getElementById("snapshot-info-picture");
  if (!table) return;

  try {
    const { data, headers, rows } = await fetchCSV();

    // Info anzeigen
    const infoEl = document.getElementById("snapshot-info");
    if (infoEl) {
      infoEl.textContent = `Datei: ${data.filename}, Geändert: ${new Date(data.mtime).toLocaleString()}, Zeilen: ${rows.length}`;
    }

    // Bild anzeigen, falls vorhanden
    if (pictureEl) {
      let imagesHtml = '';
      if (data.imageFile) {
        imagesHtml += `<img src="data:${data.imageFile.mimeType};base64,${data.imageFile.contentBase64}" alt="${data.imageFile.filename}" style="max-width: calc(50% - 2.5px); height: auto;">`;
      }
      if (data.image2) {
        imagesHtml += `<img src="data:${data.image2.mimeType};base64,${data.image2.contentBase64}" alt="${data.image2.filename}" style="max-width: calc(50% - 2.5px); height: auto;">`;
      }
      if (imagesHtml) {
        pictureEl.innerHTML = `<div style="display: flex; gap: 5px;">${imagesHtml}</div>`;
      } else {
        pictureEl.innerHTML = "";
      }
    }

    // Tabelle leeren
    table.innerHTML = "";

    // Header
    const thead = document.createElement("thead");
    const headerRow = document.createElement("tr");
    headers.forEach(h => {
      const th = document.createElement("th");
      th.textContent = h;
      headerRow.appendChild(th);
    });
    thead.appendChild(headerRow);
    table.appendChild(thead);

    // Body
    const tbody = document.createElement("tbody");
    rows.forEach(row => {
      const tr = document.createElement("tr");
      headers.forEach(h => {
        const td = document.createElement("td");
        let value = row[h];
        if (typeof value === 'number') {
          if (h === 'id' || h === 'seen_by') {
            value = Math.round(value);
          } else {
            value = value.toFixed(1);
          }
        }
        td.textContent = value;
        tr.appendChild(td);
      });
      tbody.appendChild(tr);
    });
    table.appendChild(tbody);
  } catch (err) {
    console.error("Fehler beim Rendern des Snapshots:", err);
  }
}

async function onCalculateClick() {
  clearTextarea("analysis-log");
  clearTextarea("result-json");
  clearElement("result-tree");
  clearElement("snapshot-table");

  appendLog("Starte Berechnung...");

  try {
    const result = await window.calculate();
    renderResult(result);
    await renderSnapshot();
    appendLog("Result angezeigt.");
  } catch (err) {
    appendLog(`Fehler: ${err.message}`);
  }
}

async function onCommandClick(btn) {
  const cmd = btn.dataset.cmd;
  const payloadSelector = btn.dataset.payload;
  const payload = payloadSelector
    ? document.querySelector(payloadSelector)?.value ?? ""
    : "";

  if (typeof window.sendCommand === "function") {
    try {
      await window.sendCommand(cmd, payload);
      appendLog(`Command gesendet: ${cmd}${payload ? " " + payload : ""}`);
    } catch (err) {
      appendLog(`Command-Fehler: ${err.message}`);
    }
    return;
  }

  appendLog(`Command (kein Transport definiert): ${cmd}${payload ? " " + payload : ""}`);
}

function setupUi() {
  const calculateBtn = document.getElementById("btn-calculate");
  if (calculateBtn) {
    calculateBtn.addEventListener("click", onCalculateClick);
  }

  document.querySelectorAll("button[data-cmd]").forEach(btn => {
    if (btn.id === "btn-calculate") return;
    btn.addEventListener("click", () => onCommandClick(btn));
  });

  // ===== SECTION COLLAPSE/EXPAND =====
  document.querySelectorAll(".section h2").forEach(heading => {
    heading.addEventListener("click", () => {
      const section = heading.closest(".section");
      if (section) {
        section.classList.toggle("collapsed");
      }
    });
    heading.style.cursor = "pointer";
  });

  // Auto-expand when content is written to a collapsed section
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.type === "childList" || mutation.type === "characterData") {
        let el = mutation.target;
        while (el && el !== document.body) {
          const section = el.closest(".section");
          if (section && section.classList.contains("collapsed")) {
            section.classList.remove("collapsed");
            break;
          }
          el = el.parentElement;
        }
      }
    });
  });

  // Observer auf alle Elemente in Sections anwenden
  document.querySelectorAll(".section").forEach(section => {
    observer.observe(section, {
      childList: true,
      subtree: true,
      characterData: true,
      characterDataOldValue: false
    });
  });
}

window.addEventListener("DOMContentLoaded", setupUi);