/* global marked */

const DOCS = [
  {
    id: "submission",
    title: "Submission Edition (Clean)",
    file: "../DANNY_STOCKER_INFRAFABRIC_DOSSIER_SUBMISSION_EDITION.md",
  },
  {
    id: "submission-full",
    title: "Submission Edition (Clean, Full) v2.0",
    file: "../DANNY_STOCKER_INFRAFABRIC_DOSSIER_SUBMISSION_EDITION_FULL.md",
  },
  {
    id: "data",
    title: "Data‑Driven Technical Report (Microlab)",
    file: "../DANNY_STOCKER_INFRAFABRIC_DOSSIER_DATA_DRIVEN_EDITION.md",
  },
  {
    id: "data-full",
    title: "Data‑Driven Edition (Full) v2.0",
    file: "../DANNY_STOCKER_INFRAFABRIC_DOSSIER_DATA_DRIVEN_EDITION_FULL.md",
  },
  {
    id: "uncut",
    title: "Uncut Dossier (Full)",
    file: "../DANNY_STOCKER_INFRAFABRIC_DOSSIER_UNCUT.md",
  },
];

function slugify(value) {
  return String(value)
    .replace(/<[^>]+>/g, "")
    .trim()
    .toLowerCase()
    .replace(/[^\w\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-");
}

function createSlugger() {
  const seen = new Map();
  return (headingText) => {
    const base = slugify(headingText) || "section";
    const current = seen.get(base) || 0;
    seen.set(base, current + 1);
    return current === 0 ? base : `${base}-${current + 1}`;
  };
}

function setStatus(text) {
  const statusEl = document.getElementById("status");
  statusEl.textContent = text || "";
}

function buildToc() {
  const tocEl = document.getElementById("toc");
  tocEl.innerHTML = "";

  const title = document.createElement("div");
  title.className = "toc-title";
  title.textContent = "On this page";
  tocEl.appendChild(title);

  const headings = Array.from(document.querySelectorAll("#content h1, #content h2, #content h3, #content h4"));
  for (const heading of headings) {
    const level = Number(heading.tagName.slice(1));
    if (!heading.id) continue;

    const a = document.createElement("a");
    a.href = `#${heading.id}`;
    a.textContent = heading.textContent || heading.id;
    a.className = `depth-${level}`;
    tocEl.appendChild(a);
  }
}

function scrollToHash() {
  const id = (location.hash || "").replace(/^#/, "");
  if (!id) return;

  const el = document.getElementById(id);
  if (el) el.scrollIntoView({ block: "start" });
}

function setQueryParam(key, value) {
  const url = new URL(location.href);
  if (value == null) url.searchParams.delete(key);
  else url.searchParams.set(key, value);
  history.replaceState(null, "", url.toString());
}

async function loadDoc(docId) {
  const doc = DOCS.find((d) => d.id === docId) || DOCS[0];
  setQueryParam("doc", doc.id);

  const rawLink = document.getElementById("openRaw");
  rawLink.href = doc.file;

  setStatus(`Loading: ${doc.title}…`);

  const slugger = createSlugger();
  const renderer = new marked.Renderer();
  renderer.heading = (text, level) => {
    const id = slugger(text);
    return `<h${level} id="${id}">${text}</h${level}>`;
  };

  marked.setOptions({
    renderer,
    gfm: true,
    breaks: false,
    mangle: false,
    headerIds: false,
  });

  try {
    const res = await fetch(doc.file, { cache: "no-cache" });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const markdown = await res.text();

    const html = marked.parse(markdown);
    const contentEl = document.getElementById("content");
    contentEl.innerHTML = html;

    buildToc();
    setStatus(`Loaded: ${doc.title}`);
    scrollToHash();
  } catch (err) {
    setStatus(`Failed to load ${doc.title}: ${String(err)}`);
    document.getElementById("content").textContent = "";
  }
}

function init() {
  const select = document.getElementById("docSelect");
  for (const doc of DOCS) {
    const opt = document.createElement("option");
    opt.value = doc.id;
    opt.textContent = doc.title;
    select.appendChild(opt);
  }

  const initial = new URLSearchParams(location.search).get("doc") || DOCS[0].id;
  select.value = DOCS.some((d) => d.id === initial) ? initial : DOCS[0].id;

  select.addEventListener("change", () => {
    location.hash = "";
    loadDoc(select.value);
  });

  window.addEventListener("hashchange", () => scrollToHash());

  loadDoc(select.value);
}

init();
