// main.js — App-Boot: Panels mounten, Nav starten, Topbar/Alert pflegen, Polling fahren.
// Panel-Vertrag: { id, mount?(), onStatus?(s), onJobs?(jobs) }.

import { api, getToken, setToken } from "./core/api.js";
import { $ } from "./core/ui.js";
import { initNav } from "./core/nav.js";

import overview from "./panels/overview.js";
import models from "./panels/models.js";
import server from "./panels/server.js";
import jobs from "./panels/jobs.js";
import cookbook from "./panels/cookbook.js";
import guides from "./panels/guides.js";

const panels = [overview, models, server, jobs, cookbook, guides];

let lastJobs = [];
let lastSystem = null;

// ---- Topbar / Alert aus dem Status ableiten ----
function applyStatus(s) {
  const dot = $("#swdot"), label = $("#swlabel"), alert = $("#alert");

  if (!s) {
    dot.className = "dot off";
    label.textContent = "Backend nicht erreichbar";
    $("#top-active-text").textContent = "Backend offline";
    showAlert("Backend nicht erreichbar – läuft uvicorn?", false);
  } else {
    const host = s.swap_url.replace(/^https?:\/\//, "");
    dot.className = "dot " + (s.swap_ok ? "on" : "off");
    label.textContent = (s.swap_ok ? "LLM-Engine: Online – " : "LLM-Engine: Offline – ") + host;
    
    const active = (s.models || []).find(m => m.state === "running");
    if (active) {
       $("#top-active-text").innerHTML = `Geladen: <b style="color:var(--teal)">${active.name}</b>`;
    } else {
       $("#top-active-text").innerHTML = "Kein Modell im VRAM";
    }
    
    if (s.swap_ok) hideAlert();
    else showAlert(`LLM-Engine nicht erreichbar unter <b>${host}</b> – läuft der llama-swap Dienst?`, true);
  }
  for (const p of panels) p.onStatus?.(s);
}

function applyJobs(jobs) {
  lastJobs = jobs || [];
  for (const p of panels) p.onJobs?.(lastJobs);
}

function applySystem(sys) {
  lastSystem = sys;
  for (const p of panels) p.onSystem?.(sys);
}

function showAlert(html, warn) {
  const a = $("#alert");
  a.className = "alert" + (warn ? " warn" : "");
  a.innerHTML = `<span class="a-dot"></span><span>${html}</span>`;
  a.style.display = "flex";
}
function hideAlert() { $("#alert").style.display = "none"; }

// ---- Polling ----
async function pollStatus() {
  try { applyStatus(await api("/api/status")); }
  catch { applyStatus(null); }
}
async function pollJobs() {
  try { applyJobs(await api("/api/jobs")); }
  catch { /* still */ }
}

async function pollSystem() {
  try { applySystem(await api("/api/system/status")); }
  catch { /* still */ }
}

// ---- Boot ----
function bootToken() {
  const i = $("#token");
  if (i) {
    i.value = getToken();
    i.addEventListener("change", e => { setToken(e.target.value); pollStatus(); });
  }

  const sbtn = $("#nav-settings");
  const smod = $("#settings-modal");
  const scls = $("#sm-close");
  if (sbtn && smod && scls) {
    sbtn.addEventListener("click", () => smod.style.display = "flex");
    scls.addEventListener("click", () => smod.style.display = "none");
  }
}
function tickClock() {
  const c = $("#clock");
  if (c) c.textContent = new Date().toTimeString().slice(0, 5);
}

for (const p of panels) p.mount?.();
initNav("overview");
bootToken();
tickClock();
document.addEventListener("mc:refresh", pollStatus);

pollStatus();
pollJobs();
pollSystem();
setInterval(tickClock, 1000);
setInterval(pollStatus, 3000);
setInterval(pollJobs, 1500);
setInterval(pollSystem, 2000);
