// models.js — "Modelle"-Ansicht: Schnelltest-Chat, Modell-Tabelle & Konfiguration.

import { api } from "../core/api.js";
import { $, badge, esc, toast, icon } from "../core/ui.js";

let ALL_MODELS = [];

function refreshSoon() { document.dispatchEvent(new Event("mc:refresh")); }

function mount() {

  $("#m-chat").innerHTML = `
    <div class="card-h"><h3>Schnelltest</h3></div>
    <label>Modell</label>
    <select id="chat-model"></select>
    <label>Nachricht</label>
    <textarea id="chat-msg" placeholder="Schreib was, um ein Modell zu wecken…"></textarea>
    <button class="primary" id="chat-btn" title="Sendet eine Chat-Anfrage an das Modell (weckt es auf, falls es schläft)">Senden</button>
    <div id="chat-reply" class="reply" style="display:none"></div>`;

  $("#m-table").innerHTML = `
    <div class="card-h"><h3>Modelle &amp; Ports</h3><span class="meta" id="m-count"></span></div>
    <div class="hint mb-4">
      💡 <b>Modelle werden automatisch geladen</b>, sobald eine Chat-Anfrage an sie gestellt wird. Du musst sie nicht manuell starten.
    </div>
    <table>
      <thead><tr><th>Modell</th><th>Fähigkeiten</th><th>Details</th><th>Status</th><th>Port</th><th style="text-align:right">Aktionen</th></tr></thead>
      <tbody id="models"></tbody>
    </table>
    <div id="models-empty" class="empty" style="display:none">Noch keine Modelle konfiguriert — zieh dir oben eins rein. 👇</div>
    
    <!-- Config Modal -->
    <div id="cfg-modal" style="display:none; position:fixed; top:0; left:0; right:0; bottom:0; background:rgba(0,0,0,0.8); z-index:100; align-items:center; justify-content:center;">
      <div class="card" style="width:100%; max-width:400px; position:relative">
        <button id="cfg-close" class="ghost" style="position:absolute; top:12px; right:12px;">Schließen</button>
        <h2 style="margin-top:0">Modell konfigurieren</h2>
        <p class="meta" id="cfg-model-name"></p>
        
        <div class="mt-6">
          <label>Context-Size (Tokens)</label>
          <input id="cfg-ctx" type="number" class="tokin" value="8192">
          <div class="meta text-xs mt-2">Höhere Werte erlauben längere Dokumente, brauchen aber mehr VRAM.</div>
        </div>

        <button class="primary mt-6" id="cfg-save" style="width:100%; padding:var(--sp-3)">Speichern</button>
      </div>
    </div>
  `;

  $("#chat-btn").addEventListener("click", sendChat);
  $("#cfg-close").addEventListener("click", () => $("#cfg-modal").style.display = "none");
  $("#cfg-save").addEventListener("click", saveConfig);
}

function onStatus(s) {
  ALL_MODELS = s?.models || [];
  const tb = $("#models");
  if (!tb) return;
  tb.innerHTML = "";
  $("#models-empty").style.display = ALL_MODELS.length ? "none" : "block";
  $("#m-count").textContent = ALL_MODELS.length ? ALL_MODELS.length + " konfiguriert" : "";

  const sel = $("#chat-model");
  const cur = sel.value;
  sel.innerHTML = "";
  for (const m of ALL_MODELS) {
    const tr = document.createElement("tr");
    
    let capsHtml = "–";
    if (m.meta && m.meta.caps) {
      capsHtml = m.meta.caps.map(c => {
         if (c === "Text") return `<span class="meta" title="Text" style="display:inline-block;width:18px">${icon("compass")}</span>`;
         if (c === "Code") return `<strong style="color:var(--blue);display:inline-block;width:18px" title="Code">{ }</strong>`;
         if (c === "Bild") return `<strong style="color:var(--purple);display:inline-block;width:18px" title="Vision">👁</strong>`;
         return "";
      }).join(" ");
    }
    
    let detailsHtml = "–";
    if (m.meta) {
      const q = m.meta.quant || "?";
      const c = m.meta.ctx ? (m.meta.ctx / 1024).toFixed(0) + "K" : "?";
      const s = m.meta.size_bytes ? (m.meta.size_bytes / 1024 / 1024 / 1024).toFixed(1) + " GB" : "?";
      detailsHtml = `<span class="meta" style="font-size:0.9em">${q} · ${c} · ${s}</span>`;
    }

    const perfHtml = m.state === "running" ? `<br><small class="meta" style="font-size:0.75em">n/a t/s</small>` : "";

    const filenameHtml = m.meta?.filename ? `<br><small class="meta" style="font-size:0.8em">${esc(m.meta.filename)}</small>` : "";

    tr.innerHTML = `<td class="mid" style="font-weight:500">${esc(m.name)}${filenameHtml}</td>
      <td>${capsHtml}</td>
      <td>${detailsHtml}</td>
      <td>${badge(m.state)}${perfHtml}</td>
      <td class="port">${m.port ?? "auto"}</td>
      <td style="text-align:right">
        <button class="ghost" data-cfg="${esc(m.name)}" title="Context-Size anpassen">Konfigurieren</button>
        <button class="ghost" data-unload="${esc(m.name)}" title="Beendet das Modell sofort und gibt den VRAM wieder frei">Aus VRAM entfernen</button>
      </td>`;
    tb.appendChild(tr);
    sel.insertAdjacentHTML("beforeend", `<option>${esc(m.name)}</option>`);
  }
  if (cur) sel.value = cur;
  
  tb.querySelectorAll("[data-unload]").forEach(b =>
    b.addEventListener("click", () => unloadOne(b.getAttribute("data-unload")))
  );
  tb.querySelectorAll("[data-cfg]").forEach(b =>
    b.addEventListener("click", () => openConfig(b.getAttribute("data-cfg")))
  );
}

function openConfig(alias) {
  const m = ALL_MODELS.find(x => x.name === alias);
  if (!m) return;
  $("#cfg-model-name").textContent = m.name;
  $("#cfg-ctx").value = m.meta?.ctx || 8192;
  $("#cfg-modal").style.display = "flex";
}

async function saveConfig() {
  const alias = $("#cfg-model-name").textContent;
  const ctx = parseInt($("#cfg-ctx").value) || 8192;
  
  $("#cfg-save").disabled = true;
  try {
    await api("/api/update_model", { method: "POST", body: JSON.stringify({ alias, ctx }) });
    toast("Gespeichert! Änderungen werden beim nächsten Modell-Start aktiv.");
    $("#cfg-modal").style.display = "none";
    refreshSoon();
  } catch (e) {
    toast(e.message, true);
  }
  $("#cfg-save").disabled = false;
}

async function unloadOne(m) {
  try {
    await api("/api/unload?model=" + encodeURIComponent(m), { method: "POST" });
    toast("Entladen: " + m);
    setTimeout(refreshSoon, 600);
  } catch (e) { toast(e.message, true); }
}

async function sendChat() {
  const model = $("#chat-model").value, message = $("#chat-msg").value.trim();
  if (!model) return toast("Kein Modell vorhanden.", true);
  if (!message) return;
  const btn = $("#chat-btn"); btn.disabled = true; btn.textContent = "…";
  const box = $("#chat-reply"); box.style.display = "block";
  box.textContent = "(wecke Modell, kann beim Swap kurz dauern…)";
  try {
    const r = await api("/api/chat", { method: "POST", body: JSON.stringify({ model, message }) });
    box.textContent = r.reply;
  } catch (e) { box.textContent = "Fehler: " + e.message; }
  btn.disabled = false; btn.textContent = "Senden";
  refreshSoon();
}

export default { id: "models", mount, onStatus };
