/* Werkstatt, Teil 3: die Konsole in der unteren Leiste - nur in der Desktop-App
   (S.me.befehle). Ein Befehl ist ein Auftrag der Art „befehl“; seine Zeilen
   kommen über das Live-Thema job:<id>, wie im Agenten-Hub. */
"use strict";

S.konsole = { job: null, zeilen: [], verlauf: [], stelle: -1, laeuft: false };

const KONSOLE_KEY = () => `minerva.konsole.${S.pid || 0}`;

function konsoleVerlaufLaden() {
  try { S.konsole.verlauf = JSON.parse(localStorage.getItem(KONSOLE_KEY()) || "[]"); } catch (e) { S.konsole.verlauf = []; }
}

function konsoleZeile(text) {
  S.konsole.zeilen.push(text);
  if (S.konsole.zeilen.length > 2000) S.konsole.zeilen.splice(0, S.konsole.zeilen.length - 2000);
  const log = $("#konsole-log");
  if (log) {
    log.append(document.createTextNode(text + "\n"));
    log.scrollTop = log.scrollHeight;
  }
}

async function befehlAusfuehren(cmd) {
  if (!S.pid || !cmd.trim()) return;
  S.konsole.verlauf = [cmd, ...S.konsole.verlauf.filter((x) => x !== cmd)].slice(0, 50);
  S.konsole.stelle = -1;
  try { localStorage.setItem(KONSOLE_KEY(), JSON.stringify(S.konsole.verlauf)); } catch (e) { /* egal */ }
  try {
    const j = await jsonRuf(`/api/projects/${S.pid}/befehle`, "POST", { cmd });
    S.konsole.job = j.id;
    S.konsole.laeuft = true;
    abonnieren(`job:${j.id}`);
    konsoleKnoepfe();
    // Erstabruf nach dem Abo: ein schneller Befehl kann fertig sein, bevor das Abo steht.
    const stand = await api(`/api/jobs/${j.id}`);
    const log = $("#konsole-log");
    if (log) { log.textContent = ""; S.konsole.zeilen = []; }
    (stand.log || "").split("\n").filter(Boolean).forEach(konsoleZeile);
    if (["done", "failed", "cancelled"].includes(stand.status)) konsoleEnde(stand.status, stand.result);
  } catch (e) {
    meldung(e.message, true);
  }
}

function konsoleEnde(status, result) {
  S.konsole.laeuft = false;
  const rc = result && result.exit;
  konsoleZeile(`— ${status}${rc !== undefined && rc !== null ? ` (exit ${rc})` : ""}`
    + (result && result.gekuerzt ? " · Ausgabe gekürzt" : ""));
  konsoleKnoepfe();
}

function konsoleKnoepfe() {
  const stopp = $("#konsole-stopp");
  if (stopp) stopp.disabled = !S.konsole.laeuft;
}

document.addEventListener("live", (e) => {
  const d = e.detail;
  if (!d || d.job !== S.konsole.job) return;
  if (d.log !== undefined) konsoleZeile(d.log);
  if (d.status && ["done", "failed", "cancelled"].includes(d.status)) konsoleEnde(d.status, d.result);
});

UNTEN_ZEICHNER.konsole = {
  titel: "Konsole", symbol: "terminal", nur_desktop: true,
  zeichne(ziel) {
    const rahmen = el("div", "konsole");
    const log = el("pre", "konsole__log");
    log.id = "konsole-log";
    log.textContent = S.konsole.zeilen.join("\n") + (S.konsole.zeilen.length ? "\n" : "");
    const zeile = el("div", "konsole__zeile");
    const ordner = el("span", "konsole__ordner", S.daten ? S.daten.project.name + " ›" : "Kein Projekt ›");
    const feld = el("input");
    feld.type = "text";
    feld.id = "konsole-eingabe";
    feld.placeholder = S.pid ? "Befehl im Arbeitsordner, z. B. ls -la" : "Zuerst ein Projekt wählen";
    feld.disabled = !S.pid;
    feld.autocomplete = "off";
    konsoleVerlaufLaden();
    feld.onkeydown = (ev) => {
      if (ev.key === "Enter") { const cmd = feld.value; feld.value = ""; befehlAusfuehren(cmd); }
      else if (ev.key === "ArrowUp" || ev.key === "ArrowDown") {
        ev.preventDefault();
        const n = S.konsole.verlauf.length;
        if (!n) return;
        S.konsole.stelle = ev.key === "ArrowUp" ? Math.min(S.konsole.stelle + 1, n - 1) : Math.max(S.konsole.stelle - 1, -1);
        feld.value = S.konsole.stelle < 0 ? "" : S.konsole.verlauf[S.konsole.stelle];
      }
    };
    const stopp = knopf("btn", "stop", "Stopp");
    stopp.id = "konsole-stopp";
    stopp.disabled = !S.konsole.laeuft;
    stopp.onclick = async () => {
      if (!S.konsole.job) return;
      try { await api(`/api/jobs/${S.konsole.job}/abbrechen`, { method: "POST" }); }
      catch (e) { meldung(e.message, true); }
    };
    const leeren = knopf("btn btn--ghost", "broom", "");
    leeren.title = "Ausgabe leeren";
    leeren.onclick = () => { S.konsole.zeilen = []; log.textContent = ""; };
    zeile.append(ordner, feld, stopp, leeren);
    rahmen.append(log, zeile);
    ziel.append(rahmen);
    log.scrollTop = log.scrollHeight;
    if (S.pid) feld.focus();
  },
};

BEFEHLE["werkstatt.befehl"] = () => {
  if (!(S.me && S.me.befehle)) { meldung("Befehle gibt es nur in der Desktop-App", true); return; }
  untenUmschalten(true, "konsole");
  const feld = $("#konsole-eingabe");
  if (feld) feld.focus();
};

document.addEventListener("projekt-geladen", () => {
  S.konsole.job = null;
  S.konsole.zeilen = [];
  S.konsole.laeuft = false;
  if (S.schale.unten.tab === "konsole" && !$("#unten").hidden) untenTab("konsole");
});
