<script lang="ts">
  import { onMount } from 'svelte'
  import { statusStore } from '../stores/status.svelte.js'
  import { systemStore } from '../stores/system.svelte.js'
  import { api } from '@core/api.js'
  import { confirmModal, toast, icon, fmtBytes } from '@core/ui.js'

  const s = $derived(statusStore.value)
  const sys = $derived(systemStore.value)
  const allModels = $derived((s?.models || []) as any[])
  const swapOk = $derived(s?.swap_ok ?? false)
  const LOADED = ['running', 'ready', 'loading', 'starting']
  const activeModel = $derived(allModels.find((m: any) => LOADED.includes(m.state)))
  const configuredModels = $derived(allModels.filter((m: any) => !m.incomplete))

  const heroTitle = $derived(
    !s ? 'Verbinde…'
    : !swapOk ? 'LLM-Engine offline'
    : sys && sys.ram.percent >= 90 ? 'Achtung: Speicher wird knapp.'
    : 'Alles läuft rund.'
  )
  const heroSub = $derived(
    !s ? ''
    : !swapOk ? 'Der llama-swap-Dienst antwortet gerade nicht.'
    : sys && sys.ram.percent >= 90 ? `Arbeitsspeicher bei ${Math.round(sys.ram.percent)} % — eventuell Speicher freigeben.`
    : `${configuredModels.length} ${configuredModels.length === 1 ? 'Modell' : 'Modelle'} konfiguriert · ${activeModel ? `„${activeModel.name}" geladen` : 'keines geladen'} · keine Warnungen.`
  )

  const gpuPct = $derived(() => {
    const g = sys?.gpu
    if (g && (g.vram.total + g.gtt.total) > 0)
      return ((g.vram.used + g.gtt.used) / (g.vram.total + g.gtt.total)) * 100
    return 0
  })

  let news = $state<any[]>([])
  let preloadingModel = $state<string | null>(null)

  onMount(async () => {
    try { news = ((await api('/api/news')).items || []).slice(0, 4) } catch {}
  })

  async function freeMemory() {
    if (!await confirmModal({
      title: 'Speicher freigeben?',
      body: 'Alle aktuell geladenen Modelle werden aus dem Grafikspeicher geworfen. Sie laden beim nächsten Aufruf automatisch neu.',
      confirmLabel: 'Speicher freigeben',
    })) return
    await api('/api/unload', { method: 'POST' })
    refresh()
  }

  async function preload(modelName: string) {
    preloadingModel = modelName
    try { await api('/api/preload?model=' + encodeURIComponent(modelName), { method: 'POST' }) }
    catch (e: any) { toast('Laden fehlgeschlagen: ' + (e.message || 'Engine nicht erreichbar?'), true) }
    preloadingModel = null
    refresh()
  }

  function refresh() { document.dispatchEvent(new Event('mc:refresh')) }
  function go(view: string) {
    document.querySelector(`.nav-item[data-view="${view}"]`)?.dispatchEvent(new MouseEvent('click'))
  }

  function ramColor(pct: number) { return pct >= 90 ? 'red' : pct >= 75 ? '' : 'green' }
  function tempColor(t: number | null) { return t == null ? '' : t >= 75 ? 'red' : t >= 55 ? '' : 'green' }
  function gpuColor(pct: number) { return pct >= 90 ? 'red' : pct >= 70 ? '' : 'green' }
</script>

<!-- Hero -->
<div class="pagehead" style="margin-bottom:10px">
  <div>
    <h1 style="display:flex;align-items:center;gap:10px">
      {heroTitle}
      {#if swapOk && !activeModel}
        <span style="font-size:13px;font-weight:400;color:var(--mut)">— bereit für Anfragen</span>
      {/if}
    </h1>
    <div class="sub">{heroSub}</div>
  </div>
</div>

<!-- KPI Tiles -->
<div class="tiles">
  <div class="kpi {swapOk ? 'green' : 'red'}">
    <div class="k-h">
      <span class="k-t">LLM-Engine</span>
      <span class="k-ic">{@html icon('server')}</span>
    </div>
    <div class="k-v">{swapOk ? 'Online' : 'Offline'}</div>
    <div class="k-s">{s?.swap_url?.replace(/^https?:\/\//, '') ?? '—'}</div>
  </div>

  <div class="kpi {activeModel ? 'blue' : 'muted'}">
    <div class="k-h">
      <span class="k-t">Aktives Modell</span>
      <span class="k-ic">{@html icon('cpu')}</span>
    </div>
    <div class="k-v" style="font-size:16px;word-break:break-word">{activeModel ? activeModel.name : 'Keins'}</div>
    <div class="k-s">
      {#if activeModel}
        {activeModel.meta?.ctx ? Math.round(activeModel.meta.ctx / 1024) + 'k ctx' : ''} · {activeModel.state}
      {:else}
        lädt bei erster Anfrage
      {/if}
    </div>
  </div>

  {#if sys}
    {@const t = sys.gpu_temp ?? sys.cpu?.temp ?? null}
    {@const tCol = tempColor(t)}
    <div class="kpi {tCol}">
      <div class="k-h"><span class="k-t">Temperatur (GPU)</span><span class="k-ic">{@html icon('thermo')}</span></div>
      <div class="k-v">{t != null ? `${Math.round(t)}°C` : '–'}</div>
      <div class="k-s">{t == null ? 'messe…' : t < 55 ? 'kühl' : t < 75 ? 'normal' : '⚠ heiß'}</div>
    </div>
    {@const free = sys.ram.total - sys.ram.used}
    {@const freePct = 100 - sys.ram.percent}
    <div class="kpi {freePct < 15 ? 'red' : freePct < 30 ? '' : 'green'}">
      <div class="k-h"><span class="k-t">Freier Speicher</span><span class="k-ic">{@html icon('database')}</span></div>
      <div class="k-v">{Math.round(free / 1024 ** 3)}<small> GB</small></div>
      <div class="k-s">von {Math.round(sys.ram.total / 1024 ** 3)} GB · {Math.round(freePct)} % frei</div>
    </div>
  {:else}
    <div class="kpi muted"><div class="k-h"><span class="k-t">Temperatur</span></div><div class="k-v">–</div><div class="k-s">messe…</div></div>
    <div class="kpi muted"><div class="k-h"><span class="k-t">Freier Speicher</span></div><div class="k-v">–</div><div class="k-s">messe…</div></div>
  {/if}
</div>

<!-- Split: Health + Quickstart -->
<div class="split">
  <div class="card">
    <div class="card-h"><h3>System-Gesundheit</h3></div>
    <div class="card-sub">Auslastung in Echtzeit.</div>
    {#if sys}
      {@const gpu = gpuPct()}
      {#each [
        ['Prozessor (CPU)', sys.cpu?.percent ?? 0, ''],
        ['Arbeitsspeicher (RAM)', sys.ram.percent, ramColor(sys.ram.percent)],
        ['Grafikspeicher (VRAM)', gpu, gpuColor(gpu)]
      ] as [label, pct, cls]}
        {@const p = Math.max(0, Math.min(100, (pct as number) || 0))}
        <div class="meter">
          <div class="meter-h"><span class="mk">{label}</span><span class="mv">{Math.round(p)} %</span></div>
          <div class="bar {p >= 90 ? 'bad' : p >= 75 ? 'warn' : ''}"><i style="width:{Math.max(2, p)}%"></i></div>
        </div>
      {/each}
    {:else}
      <div class="empty">Warte auf Messwerte…</div>
    {/if}
  </div>

  <div class="card">
    <div class="card-h"><h3>Schnellstart</h3></div>
    {#if !configuredModels.length}
      <!-- Onboarding-Pfad: noch keine Modelle -->
      <div class="card-sub">Noch kein Modell eingerichtet — starte hier:</div>
      <button class="qa" onclick={() => go('cookbook')}>
        <span class="qa-ic teal">{@html icon('search')}</span>
        <span class="qa-main"><span class="qa-t">Schritt 1 · Modell holen</span><span class="qa-s">Cookbook → passendes Setup installieren</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
      <button class="qa" onclick={() => go('connect')} style="opacity:.55;pointer-events:none">
        <span class="qa-ic teal">{@html icon('swap')}</span>
        <span class="qa-main"><span class="qa-t">Schritt 2 · Tools verbinden</span><span class="qa-s">Erst nach dem Download verfügbar</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
      <button class="qa" onclick={() => go('guides')}>
        <span class="qa-ic blue">{@html icon('file')}</span>
        <span class="qa-main"><span class="qa-t">Einsteiger-Guide lesen</span><span class="qa-s">Alle Begriffe erklärt, ohne Vorwissen</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
    {:else}
      <!-- Normalbetrieb -->
      <div class="card-sub">Die häufigsten Aufgaben — ein Klick.</div>
      <button class="qa" onclick={() => go('cookbook')}>
        <span class="qa-ic teal">{@html icon('search')}</span>
        <span class="qa-main"><span class="qa-t">Modell finden</span><span class="qa-s">Passend zu deiner Hardware</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
      <button class="qa" onclick={freeMemory}>
        <span class="qa-ic amber">{@html icon('refresh')}</span>
        <span class="qa-main"><span class="qa-t">Speicher freigeben</span><span class="qa-s">Alle Modelle entladen</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
      <button class="qa" onclick={() => go('server')}>
        <span class="qa-ic blue">{@html icon('file')}</span>
        <span class="qa-main"><span class="qa-t">Logs ansehen</span><span class="qa-s">Live mitlesen, was läuft</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
      <button class="qa" onclick={() => go('connect')}>
        <span class="qa-ic teal">{@html icon('swap')}</span>
        <span class="qa-main"><span class="qa-t">Tools verbinden</span><span class="qa-s">Zed, OpenCode, Cline einrichten</span></span>
        <span class="qa-arrow">{@html icon('chevron')}</span>
      </button>
    {/if}
  </div>
</div>

<!-- Stack + News -->
<div class="grid grid-2">
  <div class="card">
    <div class="card-h">
      <h3>Dein Stack</h3>
      <span class="meta">{configuredModels.length ? configuredModels.length + ' konfiguriert' : ''}</span>
    </div>
    {#if configuredModels.length}
      <div class="list">
        {#each configuredModels as m}
          {@const isLoaded = LOADED.includes(m.state)}
          {@const downloading = m.state === 'downloading'}
          {@const dot = (m.state === 'loading' || m.state === 'starting' || downloading) ? 'load' : isLoaded ? 'on' : ''}
          {@const statusText = downloading
            ? `↓ ${m.download_progress != null ? Math.round(m.download_progress) + '%' : '...'}`
            : m.state === 'loading' || m.state === 'starting' ? 'lädt…'
            : isLoaded ? 'geladen ✓' : 'bereit'}
          <div class="li" style="padding:10px 4px">
            <span class="li-dot {dot}"></span>
            <div class="li-main">
              <div class="flex items-center gap-2" style="flex-wrap:wrap">
                <span class="li-id" style="{isLoaded ? 'color:var(--accent)' : ''}">{m.name}</span>
                {#if m.meta?.caps?.includes('Bild')}<span class="tag img">Bild</span>
                {:else if m.meta?.caps?.includes('Code')}<span class="tag code">Code</span>
                {:else}<span class="tag text">Text</span>{/if}
                {#if m.ttl >= 99999}<span class="chip" style="padding:2px 7px;font-size:11px">∞ aktiv</span>{/if}
              </div>
              <div class="li-sub mono-sm">
                {m.meta?.ctx ? Math.round(m.meta.ctx / 1024) + 'k ctx' : ''}
                {m.meta?.quant ? ' · ' + m.meta.quant : ''}
                {m.meta?.size_bytes ? ' · ' + (m.meta.size_bytes / 1024 ** 3).toFixed(1) + ' GB' : ''}
              </div>
            </div>
            <div class="flex items-center gap-2">
              <span class="li-meta" style="white-space:nowrap;color:{isLoaded ? 'var(--on)' : 'var(--mut)'}">{statusText}</span>
              {#if !isLoaded && !downloading && swapOk}
                <button class="ghost" style="padding:3px 9px;font-size:12px;opacity:{preloadingModel === m.name ? '.5' : '1'}"
                  disabled={preloadingModel === m.name}
                  onclick={() => preload(m.name)}>
                  {preloadingModel === m.name ? '…' : 'Laden'}
                </button>
              {/if}
            </div>
          </div>
        {/each}
      </div>
    {:else}
      <div class="empty-c">
        <div class="e-t">Noch keine Modelle</div>
        <div class="e-s">Hol dir unter „Cookbook" ein Modell, das auf deine Hardware passt.</div>
        <button class="primary" style="margin-top:12px" onclick={() => go('cookbook')}>Zum Cookbook →</button>
      </div>
    {/if}
  </div>

  <div class="card">
    <div class="card-h">
      <h3>Top-News</h3>
      <span class="meta" style="cursor:pointer" role="button" tabindex="0"
        onclick={() => go('news')} onkeydown={e => e.key === 'Enter' && go('news')}>Alle →</span>
    </div>
    {#if news.length}
      <div class="list">
        {#each news as n}
          <a class="li" href={n.link} target="_blank" rel="noopener" style="text-decoration:none;color:inherit">
            <div class="li-main">
              <div style="font-size:13px;line-height:1.4">{n.title}</div>
              <div class="li-sub">{n.source}{n.relevant ? ' · für dich' : ''}</div>
            </div>
          </a>
        {/each}
      </div>
    {:else}
      <div class="empty">News gerade nicht ladbar.</div>
    {/if}
  </div>
</div>
