/* Dokumente als Ablage (DMS): Ordner als Etiketten, Schlagwörter, Freigabe-
   Ablauf, Journal, Suche über Inhalte, Vorlagen je Projektart. Der Kern
   zeichnet die Ansicht „dokumente“ und den Abschnitt „Ordner und Schlagwörter“;
   Fassungen, Vorgangsanhänge und der Upload (dateiHochladen) leben in app.js.
   Lädt nach schale.js, vor den Erweiterungen. */
"use strict";

S.dms = { ordner: "", tag: null, status: "", suche: "", alle: false, treffer: null, typ: "software" };
S.vorlagen = null;
let offenesDokument = null;

// Spiegel von UEBERGAENGE in web/app.py: von -> [nach, mindestens Rolle, Beschriftung]
const DOK_UEBERGAENGE = {
  entwurf: [["pruefung", "member", "Zur Prüfung"], ["archiviert", "manager", "Archivieren"]],
  pruefung: [["entwurf", "member", "Zurück"], ["freigegeben", "manager", "Freigeben"], ["archiviert", "manager", "Archivieren"]],
  freigegeben: [["entwurf", "manager", "Zurück in den Entwurf"], ["archiviert", "manager", "Archivieren"]],
  archiviert: [["entwurf", "manager", "Wieder aufnehmen"]],
};
const DOK_STATUS_TEXT = { entwurf: "Entwurf", pruefung: "In Prüfung", freigegeben: "Freigegeben", archiviert: "Archiviert" };
const RANG = { member: 0, manager: 1, admin: 2 };
const darfRolle = (mindestens) => S.daten && RANG[S.daten.role] >= RANG[mindestens];

async function dokumenteLaden() {
  S.dokumente = S.pid ? await api(`/api/projects/${S.pid}/documents`) : [];
  S.dms.treffer = null;
}

/* -- Ableitungen ------------------------------------------------------------ */
function dmsOrdner() {
  const alle = new Set();
  S.dokumente.forEach((d) => {
    const teile = (d.ordner || "").split("/").filter(Boolean);
    teile.forEach((_, i) => alle.add(teile.slice(0, i + 1).join("/")));
  });
  return [...alle].sort((a, b) => a.localeCompare(b, "de"));
}

function dmsTags() {
  const zaehler = {};
  S.dokumente.forEach((d) => (d.tags || []).forEach((t) => { zaehler[t] = (zaehler[t] || 0) + 1; }));
  return Object.entries(zaehler).sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0], "de"));
}

const imOrdner = (d, ordner) => !ordner || d.ordner === ordner || (d.ordner || "").startsWith(ordner + "/");

function dmsSichtbar() {
  return S.dokumente.filter((d) => imOrdner(d, S.dms.ordner)
    && (!S.dms.tag || (d.tags || []).includes(S.dms.tag))
    && (!S.dms.status || d.status === S.dms.status));
}

/* -- Ansicht ---------------------------------------------------------------- */
function statusPille(d) {
  const pille = el("span", "pill pill--" + d.status, DOK_STATUS_TEXT[d.status] || d.status);
  if (d.status === "freigegeben" && d.freigegeben_von) {
    pille.title = `Freigegeben von ${d.freigegeben_von.name}${d.freigegeben_am ? " am " + kurzDatum(d.freigegeben_am) : ""}`;
  }
  return pille;
}

function statusKnoepfe(d) {
  const box = el("span", "dms__aktionen");
  (DOK_UEBERGAENGE[d.status] || []).forEach(([nach, rolle, text]) => {
    if (!darfRolle(rolle)) return;
    const k = knopf("btn btn--ghost", nach === "freigegeben" ? "check" : nach === "archiviert" ? "box-archive" : "arrow-right", text);
    k.onclick = (e) => { e.stopPropagation(); dmsStatus(d, nach); };
    box.append(k);
  });
  return box;
}

async function dmsStatus(d, nach) {
  try {
    await jsonRuf(`/api/documents/${d.id}/status`, "PATCH", { status: nach });
    meldung(`„${d.title}“: ${DOK_STATUS_TEXT[nach]}`);
    await dokumenteLaden();
    zeichnen();
  } catch (e) { meldung(e.message, true); }
}

function krumen() {
  const zeile = el("div", "dms__crumb");
  const teile = S.dms.ordner ? S.dms.ordner.split("/") : [];
  const alle = el("a", "", "Alle Dokumente");
  alle.href = "#";
  alle.onclick = (e) => { e.preventDefault(); S.dms.ordner = ""; S.dms.treffer = null; zeichnen(); };
  zeile.append(alle);
  teile.forEach((t, i) => {
    zeile.append(el("span", "muted", " › "));
    const a = el("a", "", t);
    a.href = "#";
    a.onclick = (e) => { e.preventDefault(); S.dms.ordner = teile.slice(0, i + 1).join("/"); S.dms.treffer = null; zeichnen(); };
    zeile.append(a);
  });
  return zeile;
}

function zeichneDokumente(ziel) {
  const leiste = el("div", "toolbar");
  const suche = el("input");
  suche.type = "search";
  suche.id = "dms-suche";
  suche.placeholder = "Inhalte durchsuchen … (Enter)";
  suche.value = S.dms.suche;
  suche.style.width = "220px";
  suche.onkeydown = (e) => { if (e.key === "Enter") { S.dms.suche = suche.value.trim(); dmsSuchen(); } };
  const alleBox = el("label", "dms__alle");
  const alle = el("input");
  alle.type = "checkbox";
  alle.checked = S.dms.alle;
  alle.onchange = () => { S.dms.alle = alle.checked; if (S.dms.suche) dmsSuchen(); };
  alleBox.append(alle, document.createTextNode(" alle Projekte"));
  const status = el("select");
  status.style.width = "auto";
  [["", "Alle Status"], ...Object.entries(DOK_STATUS_TEXT)].forEach(([w, t]) => {
    const o = el("option", "", t);
    o.value = w;
    status.append(o);
  });
  status.value = S.dms.status;
  status.onchange = () => { S.dms.status = status.value; zeichnen(); };
  const vorlagen = knopf("btn", "file-lines", "Vorlagen");
  vorlagen.onclick = () => oeffneVorlagen("dokumente");
  const ordner = knopf("btn", "folder-plus", "Neuer Ordner");
  ordner.onclick = async () => {
    const name = await nameAbfragen("Neuer Ordner", "", S.dms.ordner ? `in ${S.dms.ordner}/` : "Ordner entstehen mit dem ersten Dokument darin");
    if (name) { S.dms.ordner = S.dms.ordner ? `${S.dms.ordner}/${name}` : name; S.dms.treffer = null; zeichnen(); }
  };
  const neu = knopf("btn btn--primary", "file-arrow-up", "Dokument");
  neu.onclick = () => oeffneDokument(null);
  leiste.append(el("h2", "", "Dokumente"),
    el("span", "muted", `${S.dokumente.length} Dokument(e) · ${bytes(S.dokumente.reduce((s, d) => s + d.size, 0))}`),
    el("div", "spacer"), suche, alleBox, status, vorlagen, ordner, neu);
  ziel.append(leiste, krumen());
  if (S.dms.tag) {
    const filter = el("div", "muted");
    filter.append(document.createTextNode("Schlagwort: "), el("span", "pill", S.dms.tag));
    const weg = knopf("btn btn--ghost", "xmark", "");
    weg.onclick = () => { S.dms.tag = null; zeichnen(); };
    filter.append(weg);
    ziel.append(filter);
  }

  if (S.dms.treffer) { zeichneTreffer(ziel); return; }

  const zone = el("div", "dropzone");
  zone.append(ico("cloud-arrow-up", "solid", "gross"), document.createTextNode(
    `Datei hierher ziehen oder oben auf „Dokument“ klicken${S.dms.ordner ? " – landet in „" + S.dms.ordner + "“" : ""}. `
    + "Gleichnamige Dateien werden als neue Fassung geführt."));
  zone.ondragover = (e) => { e.preventDefault(); zone.classList.add("is-over"); };
  zone.ondragleave = () => zone.classList.remove("is-over");
  zone.ondrop = async (e) => {
    e.preventDefault();
    zone.classList.remove("is-over");
    for (const datei of e.dataTransfer.files) await dateiHochladen(datei, null, S.dms.ordner);
    await dokumenteLaden();
    zeichnen();
  };
  ziel.append(zone);

  const liste = dmsSichtbar();
  const unterordner = dmsOrdner().filter((o) => {
    const eltern = o.split("/").slice(0, -1).join("/");
    return eltern === S.dms.ordner && !S.dms.tag && !S.dms.status;
  });
  if (!liste.length && !unterordner.length) {
    const leer = el("div", "empty");
    leer.append(ico("folder-open", "solid", "gross"), document.createTextNode(
      S.dokumente.length ? "Hier ist nichts – Filter oder Ordner ändern." : "Noch keine Dokumente in diesem Projekt."));
    ziel.append(leer);
    return;
  }
  const tabelle = el("table", "grid");
  tabelle.innerHTML = `<thead><tr><th>Dokument</th><th>Ordner</th><th>Status</th><th>Vorgang</th>
    <th class="num">Fassung</th><th class="num">Größe</th><th>Zuletzt</th><th></th></tr></thead>`;
  const koerper = el("tbody");
  unterordner.forEach((o) => {
    const tr = el("tr", "dms__ordnerzeile");
    const name = el("td");
    name.append(ico("folder", "solid", "datei"), document.createTextNode(o.split("/").pop()));
    const anzahl = S.dokumente.filter((d) => imOrdner(d, o)).length;
    tr.append(name, el("td", "muted", `${anzahl} Dokument(e)`), el("td"), el("td"), el("td"), el("td"), el("td"), el("td"));
    tr.onclick = () => { S.dms.ordner = o; zeichnen(); };
    koerper.append(tr);
  });
  liste.forEach((d) => koerper.append(dokumentZeile(d)));
  tabelle.append(koerper);
  ziel.append(tabelle);
}

function dokumentZeile(d, mitProjekt = false) {
  const tr = el("tr");
  const name = el("td");
  name.append(ico(dateiSymbol(d.content_type, d.filename), "solid", "datei"), document.createTextNode(d.title));
  const tags = el("span", "dms__tags");
  (d.tags || []).forEach((t) => {
    const p = el("span", "pill", t);
    p.onclick = (e) => { e.stopPropagation(); S.dms.tag = t; S.dms.treffer = null; zeichnen(); };
    tags.append(p);
  });
  name.append(tags);
  if (mitProjekt && d.project) name.append(el("div", "muted", d.project.name));
  const status = el("td");
  status.append(statusPille(d), statusKnoepfe(d));
  tr.append(name, el("td", "muted", d.ordner || "–"), status, el("td", "", d.task_key || "–"),
    el("td", "num", String(d.version)), el("td", "num", bytes(d.size)),
    el("td", "", `${kurzDatum(d.updated_at)}${d.uploaded_by ? " · " + d.uploaded_by.name : ""}`));
  const aktion = el("td", "dms__aktionen");
  const laden = el("a", "btn btn--ghost");
  laden.append(ico("download"), document.createTextNode(" Öffnen"));
  laden.href = `/api/documents/${d.id}/download`;
  laden.onclick = (e) => e.stopPropagation();
  aktion.append(laden);
  if (istText(d) && S.me.module.werkstatt && typeof oeffneDatei === "function" && !mitProjekt) {
    const werk = knopf("btn btn--ghost", "code", "In den Arbeitsordner");
    werk.onclick = (e) => { e.stopPropagation(); dmsInArbeitsordner(d); };
    aktion.append(werk);
  }
  tr.append(aktion);
  tr.onclick = () => oeffneDokument(d);
  return tr;
}

const istText = (d) => (d.content_type || "").startsWith("text/")
  || /\.(md|markdown|txt|csv|json|yaml|yml|xml|html|py|js|ts|css|sql|sh|toml|ini)$/i.test(d.filename || "");

function zeichneTreffer(ziel) {
  const liste = S.dms.treffer;
  const kopf = el("div", "muted");
  kopf.append(document.createTextNode(`${liste.length} Treffer für „${S.dms.suche}“${S.dms.alle ? " in allen Projekten" : ""} `));
  const weg = knopf("btn btn--ghost", "xmark", "Suche beenden");
  weg.onclick = () => { S.dms.suche = ""; S.dms.treffer = null; zeichnen(); };
  kopf.append(weg);
  ziel.append(kopf);
  if (!liste.length) { ziel.append(el("div", "empty", "Nichts gefunden.")); return; }
  const tabelle = el("table", "grid");
  tabelle.innerHTML = `<thead><tr><th>Dokument</th><th>Ordner</th><th>Status</th><th>Fundstelle</th><th>Ausschnitt</th><th></th></tr></thead>`;
  const koerper = el("tbody");
  liste.forEach((t) => {
    const tr = el("tr");
    const name = el("td");
    name.append(ico(dateiSymbol(t.content_type, t.filename), "solid", "datei"), document.createTextNode(t.title));
    if (S.dms.alle && t.project) name.append(el("div", "muted", t.project.name));
    const stelle = el("td", "muted", { titel: "Titel", beschreibung: "Beschreibung", tags: "Schlagwörter", datei: "Dateiname", text: `Text (Fassung ${t.fassung})` }[t.fundstelle] || t.fundstelle);
    const ausschnitt = el("td", "dms__ausschnitt");
    ausschnitt.append(...markiert(t.ausschnitt || "", S.dms.suche));
    const aktion = el("td");
    const laden = el("a", "btn btn--ghost");
    laden.append(ico("download"), document.createTextNode(" Öffnen"));
    laden.href = `/api/documents/${t.id}/download${t.fundstelle === "text" && t.fassung !== t.version ? "?version=" + t.fassung : ""}`;
    laden.onclick = (e) => e.stopPropagation();
    aktion.append(laden);
    tr.append(name, el("td", "muted", t.ordner || "–"), (() => { const td = el("td"); td.append(statusPille(t)); return td; })(), stelle, ausschnitt, aktion);
    tr.onclick = async () => {
      if (t.project_id !== S.pid) { await waehleProjekt(t.project_id); await wechsle("dokumente"); }
      const d = S.dokumente.find((x) => x.id === t.id);
      if (d) oeffneDokument(d);
    };
    koerper.append(tr);
  });
  tabelle.append(koerper);
  ziel.append(tabelle);
}

/** Text mit <mark> um jede Fundstelle - über Knoten, nie über innerHTML. */
function markiert(text, frage) {
  const teile = [];
  const f = frage.toLowerCase();
  let rest = text;
  while (f && rest.toLowerCase().includes(f)) {
    const i = rest.toLowerCase().indexOf(f);
    teile.push(document.createTextNode(rest.slice(0, i)), el("mark", "", rest.slice(i, i + f.length)));
    rest = rest.slice(i + f.length);
  }
  teile.push(document.createTextNode(rest));
  return teile;
}

async function dmsSuchen() {
  if (!S.dms.suche || S.dms.suche.length < 2) { S.dms.treffer = null; zeichnen(); return; }
  try {
    const url = S.dms.alle ? "/api/documents/suche" : `/api/projects/${S.pid}/documents/suche`;
    S.dms.treffer = await api(`${url}?q=${encodeURIComponent(S.dms.suche)}${S.dms.status ? "&status=" + S.dms.status : ""}`);
    zeichnen();
  } catch (e) { meldung(e.message, true); }
}

/** Fassung als Datei in den Arbeitsordner (Ordner „Ablage“) und im Editor öffnen. */
async function dmsInArbeitsordner(d) {
  try {
    const text = await (await fetch(`/api/documents/${d.id}/download`)).text();
    try { await jsonRuf(`/api/projects/${S.pid}/dateien/ordner`, "POST", { pfad: "Ablage" }); }
    catch (e) { if (e.status !== 409) throw e; }
    const pfad = "Ablage/" + d.filename;
    try {
      await jsonRuf(`/api/projects/${S.pid}/dateien/inhalt`, "PUT", { pfad, inhalt: text, basis_sha: null });
    } catch (e) {
      if (e.status !== 409 || !e.daten || !e.daten.sha) throw e;
      if (!confirm(`„${pfad}“ gibt es im Arbeitsordner schon – überschreiben?`)) return;
      await jsonRuf(`/api/projects/${S.pid}/dateien/inhalt`, "PUT", { pfad, inhalt: text, basis_sha: e.daten.sha });
    }
    oeffneDatei(pfad);
  } catch (e) { meldung(e.message, true); }
}

/* -- Dialog ------------------------------------------------------------------ */
function oeffneDokument(d) {
  offenesDokument = d;
  titelSetzen("#dok-titel", d ? dateiSymbol(d.content_type, d.filename) : "file-arrow-up",
              d ? d.title : "Dokument hochladen");
  $("#dok-sub").textContent = d
    ? `Fassung ${d.version} · ${bytes(d.size)} · ${d.filename}`
    : "Neue Fassungen ersetzen nichts – alte bleiben abrufbar.";
  $("#dk-title").value = d ? d.title : "";
  $("#dk-note").value = "";
  $("#dk-datei").value = "";
  $("#dk-datei-label").textContent = d ? "Neue Fassung (optional)" : "Datei";
  $("#dk-ordner").value = d ? d.ordner : S.dms.ordner;
  $("#dk-tags").value = d ? (d.tags || []).join(", ") : (S.dms.tag || "");
  const liste = $("#dk-ordner-liste");
  liste.replaceChildren(...dmsOrdner().map((o) => { const opt = el("option"); opt.value = o; return opt; }));
  fuelleAuswahl($("#dk-task"), [["", "— ohne Vorgang —"]].concat(
    (S.daten ? S.daten.tasks : []).filter((t) => !t.summary)
      .map((t) => [String(t.id), `${t.key} ${t.title}`])),
    d && d.task_id ? String(d.task_id) : "");
  const status = $("#dk-status");
  status.replaceChildren();
  if (d) {
    status.append(el("label", "", "Status"), statusPille(d), statusKnoepfe(d));
    if (d.freigegeben_von) status.append(el("span", "muted", ` freigegeben von ${d.freigegeben_von.name}${d.freigegeben_am ? " am " + kurzDatum(d.freigegeben_am) : ""}`));
  }
  const hist = $("#dk-historie");
  hist.replaceChildren();
  if (d && d.history.length > 1) {
    hist.append(el("label", "", "Fassungen"));
    d.history.forEach((v) => {
      const z = el("div", "anhang__item");
      const a = el("a", "", `v${v.version} · ${kurzDatum(v.at)} · ${bytes(v.size)}`
        + (v.by ? " · " + v.by.name : "") + (v.note ? " · " + v.note : ""));
      a.href = `/api/documents/${d.id}/download?version=${v.version}`;
      z.append(a);
      hist.append(z);
    });
  }
  const verlauf = $("#dk-verlauf");
  verlauf.replaceChildren();
  if (d) {
    api(`/api/documents/${d.id}/journal`).then((eintraege) => {
      if (offenesDokument !== d || !eintraege.length) return;
      verlauf.append(el("label", "", "Verlauf"));
      eintraege.slice(0, 12).forEach((e) => {
        verlauf.append(el("div", "muted dms__verlauf", `${kurzDatum(e.at)} · ${e.by ? e.by.name : "–"} · ${journalText(e)}`));
      });
    }).catch(() => {});
  }
  $("#dk-delete").hidden = !d;
  $("#dlg-dok").showModal();
}

function journalText(e) {
  const d = e.details || {};
  return { angelegt: "angelegt" + (d.ordner ? ` in „${d.ordner}“` : ""),
           fassung: `Fassung ${d.version}` + (d.zurueckgesetzt ? " (Freigabe zurückgesetzt)" : ""),
           status: `${DOK_STATUS_TEXT[d.von] || d.von} → ${DOK_STATUS_TEXT[d.nach] || d.nach}`,
           umbenannt: `umbenannt: „${d.von}“ → „${d.nach}“`,
           verschoben: `verschoben: „${d.von || "–"}“ → „${d.nach || "–"}“`,
           getaggt: `Schlagwörter: ${(d.tags || []).join(", ") || "–"}` }[e.art] || e.art;
}

/* -- Vorlagen ---------------------------------------------------------------- */
async function oeffneVorlagen(ziel) {
  if (!S.pid) { meldung("Zuerst ein Projekt wählen.", true); return; }
  try { if (!S.vorlagen) S.vorlagen = await api("/api/vorlagen"); } catch (e) { meldung(e.message, true); return; }
  const dlg = $("#dlg-vorlagen");
  const typ = $("#vl-typ");
  fuelleAuswahl(typ, S.vorlagen.map((k) => [k.id, k.titel]), S.dms.typ);
  const liste = $("#vl-liste");
  const zeichneListe = () => {
    S.dms.typ = typ.value;
    liste.replaceChildren();
    const k = S.vorlagen.find((x) => x.id === typ.value);
    (k ? k.vorlagen : []).forEach((v) => {
      const z = el("label", "vorlage");
      const box = el("input");
      box.type = "checkbox";
      box.value = v.name;
      z.append(box, el("b", "", v.titel), el("div", "muted", v.beschreibung));
      liste.append(z);
    });
  };
  typ.onchange = zeichneListe;
  zeichneListe();
  $("#vl-arbeitsordner").disabled = !(S.me.module.werkstatt && typeof oeffneDatei === "function");
  $("#vl-ablage").checked = ziel !== "arbeitsordner" || $("#vl-arbeitsordner").disabled;
  $("#vl-arbeitsordner").checked = !$("#vl-ablage").checked;
  $("#vl-alle").hidden = !darfRolle("manager");
  dlg.showModal();
}

async function vorlagenAnlegen(alle) {
  const typ = $("#vl-typ").value;
  const namen = alle ? [] : [...document.querySelectorAll("#vl-liste input:checked")].map((b) => b.value);
  if (!alle && !namen.length) { meldung("Bitte mindestens eine Vorlage wählen.", true); return; }
  const inArbeitsordner = $("#vl-arbeitsordner").checked;
  try {
    if (alle) {
      const r = await api(`/api/projects/${S.pid}/vorlagen/${typ}`, { method: "POST" });
      meldung(`${r.dokumente} Dokument(e) und ${r.vorgaenge} Vorgänge angelegt`);
      await projektLaden();
    } else if (inArbeitsordner) {
      try { await jsonRuf(`/api/projects/${S.pid}/dateien/ordner`, "POST", { pfad: "Dokumentation" }); }
      catch (e) { if (e.status !== 409) throw e; }
      let letzter = null;
      for (const name of namen) {
        const v = await api(`/api/projects/${S.pid}/vorlagen/${typ}/${name}`);
        const pfad = "Dokumentation/" + v.dateiname;
        try { await jsonRuf(`/api/projects/${S.pid}/dateien/inhalt`, "PUT", { pfad, inhalt: v.markdown, basis_sha: null }); }
        catch (e) { if (e.status !== 409) throw e; meldung(`„${pfad}“ gibt es schon – nicht überschrieben`, true); continue; }
        letzter = pfad;
      }
      if (letzter) oeffneDatei(letzter);
    } else {
      for (const name of namen) await jsonRuf(`/api/projects/${S.pid}/vorlagen/${typ}/${name}`, "POST", { ordner: S.dms.ordner || null });
      meldung(`${namen.length} Dokument(e) aus Vorlagen angelegt`);
    }
    $("#dlg-vorlagen").close();
    await dokumenteLaden();
    zeichnen();
    abschnittZeichnen("dokumente.ordner");
  } catch (e) { meldung(e.message, true); }
}

/* -- Seitenleiste: Ordner und Schlagwörter ----------------------------------- */
ABSCHNITT_ZEICHNER["dokumente.ordner"] = (ziel, aktionen) => {
  if (!S.pid) { ziel.append(el("div", "explorer__hinweis", "Kein Projekt gewählt.")); return; }
  const k = (symbol, titel, fn) => { const b = el("button"); b.type = "button"; b.title = titel; b.append(ico(symbol)); b.onclick = fn; return b; };
  aktionen.append(k("file-lines", "Aus Vorlage anlegen", () => oeffneVorlagen("dokumente")),
                  k("rotate", "Aktualisieren", async () => { await dokumenteLaden(); abschnittZeichnen("dokumente.ordner"); if (S.ansicht === "dokumente") zeichnen(); }));
  const baum = el("div", "tree");
  const zeile = (text, symbol, tiefe, aktiv, fn, zahl) => {
    const z = el("div", "tree__row" + (aktiv ? " is-active" : ""));
    z.style.paddingLeft = 10 + tiefe * 12 + "px";
    z.append(el("span", "kind"), el("span", "", text));
    z.firstChild.append(ico(symbol));
    if (zahl) z.append(el("span", "nav__zahl", String(zahl)));
    z.onclick = () => { fn(); if (ANSICHTEN.includes("dokumente")) wechsle("dokumente"); };
    baum.append(bedienbar(z, text));
  };
  zeile("Alle Dokumente", "folder-open", 0, !S.dms.ordner && !S.dms.tag, () => { S.dms.ordner = ""; S.dms.tag = null; S.dms.treffer = null; }, S.dokumente.length);
  dmsOrdner().forEach((o) => zeile(o.split("/").pop(), "folder", o.split("/").length, S.dms.ordner === o,
    () => { S.dms.ordner = o; S.dms.tag = null; S.dms.treffer = null; }, S.dokumente.filter((d) => imOrdner(d, o)).length));
  ziel.append(baum);
  const tags = dmsTags();
  if (tags.length) {
    ziel.append(el("div", "panel__titel", "Schlagwörter"));
    const wolke = el("div", "dms__wolke");
    tags.forEach(([t, n]) => {
      const p = el("span", "pill" + (S.dms.tag === t ? " pill--aktiv" : ""), `${t} ${n}`);
      p.onclick = () => { S.dms.tag = S.dms.tag === t ? null : t; S.dms.treffer = null; abschnittZeichnen("dokumente.ordner"); if (ANSICHTEN.includes("dokumente")) wechsle("dokumente"); };
      wolke.append(bedienbar(p, t));
    });
    ziel.append(wolke);
  }
  const zaehler = {};
  S.dokumente.forEach((d) => { zaehler[d.status] = (zaehler[d.status] || 0) + 1; });
  const status = el("div", "dms__status muted");
  Object.entries(DOK_STATUS_TEXT).forEach(([w, t]) => { if (zaehler[w]) status.append(el("span", "", `${t}: ${zaehler[w]}`)); });
  ziel.append(status);
  abonnieren(`projekt:${S.pid}`);
};

BEFEHLE["dokumente.suchen"] = () => {
  if (ANSICHTEN.includes("dokumente")) wechsle("dokumente").then(() => { const f = $("#dms-suche"); if (f) { f.focus(); f.select(); } });
};
BEFEHLE["dokumente.vorlage"] = () => oeffneVorlagen("dokumente");
BEFEHLE["dokumente.hochladen"] = () => { if (S.pid) oeffneDokument(null); };

document.addEventListener("projekt-geladen", async () => {
  S.dms.ordner = ""; S.dms.tag = null; S.dms.treffer = null;
  try { await dokumenteLaden(); } catch (e) { S.dokumente = []; }
  abschnittZeichnen("dokumente.ordner");
});
document.addEventListener("live", async (e) => {
  const d = e.detail;
  if (!d || d.projekt !== S.pid || d.art !== "dokument") return;
  try { await dokumenteLaden(); } catch (err) { return; }
  abschnittZeichnen("dokumente.ordner");
  if (S.ansicht === "dokumente" && !S.dms.treffer) zeichnen();
});

document.addEventListener("DOMContentLoaded", () => {
  $("#dlg-dok form").onsubmit = async (e) => {
    e.preventDefault();
    const datei = $("#dk-datei").files[0];
    const ordner = $("#dk-ordner").value.trim();
    const tags = $("#dk-tags").value.split(",").map((t) => t.trim()).filter(Boolean);
    try {
      if (!offenesDokument) {
        if (!datei) { meldung("Bitte eine Datei wählen.", true); return; }
        const daten = new FormData();
        daten.append("datei", datei);
        daten.append("title", $("#dk-title").value.trim());
        daten.append("note", $("#dk-note").value.trim());
        daten.append("ordner", ordner);
        daten.append("tags", tags.join(","));
        if ($("#dk-task").value) daten.append("task_id", $("#dk-task").value);
        await api(`/api/projects/${S.pid}/documents`, { method: "POST", body: daten });
      } else {
        if (datei) {
          const daten = new FormData();
          daten.append("datei", datei);
          daten.append("note", $("#dk-note").value.trim());
          await api(`/api/documents/${offenesDokument.id}/versions`, { method: "POST", body: daten });
        }
        await jsonRuf(`/api/documents/${offenesDokument.id}`, "PATCH", {
          title: $("#dk-title").value.trim(), ordner, tags,
          task_id: $("#dk-task").value ? Number($("#dk-task").value) : null });
      }
      $("#dlg-dok").close();
      await dokumenteLaden();
      zeichnen();
      abschnittZeichnen("dokumente.ordner");
    } catch (err) { meldung(err.message, true); }
  };
  $("#dk-delete").onclick = async () => {
    if (!offenesDokument || !confirm(`„${offenesDokument.title}“ mit allen Fassungen löschen?`)) return;
    try {
      await api(`/api/documents/${offenesDokument.id}`, { method: "DELETE" });
      $("#dlg-dok").close();
      await dokumenteLaden();
      zeichnen();
      abschnittZeichnen("dokumente.ordner");
    } catch (err) { meldung(err.message, true); }
  };
  $("#dlg-vorlagen form").onsubmit = (e) => { e.preventDefault(); vorlagenAnlegen(false); };
  $("#vl-alle").onclick = () => vorlagenAnlegen(true);
});

ZEICHNER.dokumente = zeichneDokumente;
LADER.dokumente = dokumenteLaden;
