<script setup>
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { api, wsVerbinden } from './api.js'
import Board from './components/Board.vue'
import Guide from './components/Guide.vue'
import Ueben from './components/Ueben.vue'
import Kennzahlen from './components/Kennzahlen.vue'

const topics = ref([])
const topic = ref('')
const state = ref(null)
const tab = ref('board')
const neuName = ref('')
const neuArt = ref('thema')
const fehler = ref('')
const theme = ref(localStorage.getItem('theme') || 'auto')
const navAuf = ref(localStorage.getItem('navAuf') !== '0')

function navToggle() {
  navAuf.value = !navAuf.value
  localStorage.setItem('navAuf', navAuf.value ? '1' : '0')
}
watch(navAuf, (a) => document.body.classList.toggle('nav-zu', !a), { immediate: true })

let wsSchliessen = null
let timer = null
const media = window.matchMedia('(prefers-color-scheme: light)')

function themeAnwenden() {
  const hell = theme.value === 'hell' || (theme.value === 'auto' && media.matches)
  document.documentElement.dataset.theme =
    theme.value === 'papier' ? 'sepia' : hell ? 'light' : 'dark'
  localStorage.setItem('theme', theme.value)
}
watch(theme, themeAnwenden)
media.addEventListener('change', themeAnwenden)

async function topicsLaden() {
  topics.value = await api.topics()
  if (!topic.value && topics.value.length) topic.value = topics.value[0].name
}

async function stateLaden() {
  if (!topic.value) { state.value = null; return }
  try {
    state.value = await api.state(topic.value)
  } catch (e) { fehler.value = String(e) }
}

function onWs() {
  clearTimeout(timer)
  timer = setTimeout(stateLaden, 400)
}

async function anlegen() {
  if (!neuName.value.trim()) return
  try {
    await api.topicAnlegen({ name: neuName.value.trim(), art: neuArt.value })
    const name = neuName.value.trim()
    neuName.value = ''
    await topicsLaden()
    topic.value = name
    await stateLaden()
  } catch (e) { fehler.value = String(e) }
}

const menue = ref(null) // Kontextmenü: { x, y, name }

function menueOeffnen(e, name) {
  menue.value = { x: e.clientX, y: e.clientY, name }
}

async function menueLoeschen() {
  const name = menue.value?.name
  menue.value = null
  if (!name) return
  try {
    await api.topicLoeschen(name)
    if (topic.value === name) topic.value = ''
    await topicsLaden()
    await stateLaden()
  } catch (e) { fehler.value = String(e) }
}

async function starten() {
  try { fehler.value = ''; await api.start(topic.value); await stateLaden() }
  catch (e) { fehler.value = String(e) }
}

async function stoppen() {
  await api.stop(topic.value)
  await stateLaden()
}

const transferOk = ref(false) // nur im lokalen Dev-Betrieb (Server: 403)
const uebertragung = ref('')

async function uebertragen(richtung) {
  uebertragung.value = richtung === 'push' ? 'pusht' : 'pullt'
  try {
    fehler.value = ''
    await api.transfer(topic.value, richtung)
    await topicsLaden()
    await stateLaden()
  } catch (e) { fehler.value = String(e) }
  finally { uebertragung.value = '' }
}

async function waehlen(name) {
  topic.value = name
  await stateLaden()
}

let poll = null // Fallback, falls während langer LLM-Calls keine WS-Deltas kommen

onMounted(async () => {
  themeAnwenden()
  api.transferInfo().then((i) => { transferOk.value = i.verfuegbar }).catch(() => {})
  await topicsLaden()
  await stateLaden()
  wsSchliessen = wsVerbinden(onWs)
  poll = setInterval(() => {
    if (state.value?.run?.status === 'running') stateLaden()
  }, 5000)
})
onUnmounted(() => {
  wsSchliessen && wsSchliessen()
  clearInterval(poll)
  media.removeEventListener('change', themeAnwenden)
})

const tok = (n) => (n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : `${Math.round(n / 1000)}k`)

function runBadge(run) {
  if (!run) return null
  const farbe = { running: 'blau', done: 'gruen', paused: 'gelb', budget: 'gelb',
                  failed: 'rot', stopped: 'rot' }[run.status] || ''
  return { farbe, text: run.status + (run.ebene && run.status === 'running' ? ` · ${run.ebene}` : '') }
}
</script>

<template>
  <aside class="sidebar">
    <div class="topics">
      <div v-for="t in topics" :key="t.name" class="topic-eintrag"
           :class="{ aktiv: t.name === topic }" @click="waehlen(t.name)"
           @contextmenu.prevent="menueOeffnen($event, t.name)">
        <span>{{ t.titel }}</span>
        <span v-if="t.run?.status === 'running'" class="badge blau">läuft</span>
        <span v-else-if="t.status === 'fertig'" class="badge gruen">✓</span>
      </div>
    </div>
    <div class="neu">
      <input v-model="neuName" placeholder="neues Thema…" @keyup.enter="anlegen" />
      <div style="display: flex; gap: 6px">
        <select v-model="neuArt" style="flex: 1">
          <option value="thema">thema</option><option value="uni">uni</option>
        </select>
        <button class="sekundaer" @click="anlegen">Anlegen</button>
      </div>
    </div>
  </aside>

  <div v-if="menue" style="position: fixed; inset: 0; z-index: 99"
       @click="menue = null" @contextmenu.prevent="menue = null">
    <div class="kontextmenue" :style="{ left: menue.x + 'px', top: menue.y + 'px' }">
      <button class="rot" @click.stop="menueLoeschen">Thema „{{ menue.name }}" löschen</button>
    </div>
  </div>

  <div class="hauptbereich">
    <button class="nav-toggle" :title="navAuf ? 'Navigation einklappen' : 'Navigation anzeigen'"
            @click="navToggle">☰</button>
    <div class="topbar">
      <div class="tabs">
        <button v-for="t in ['board', 'guide', 'üben', 'kennzahlen']" :key="t"
                :class="{ aktiv: tab === t }" @click="tab = t">{{ t }}</button>
      </div>
      <button @click="starten" :disabled="!topic || state?.run?.status === 'running'">Start</button>
      <button class="sekundaer" @click="stoppen" :disabled="state?.run?.status !== 'running'">Stop</button>
      <template v-if="transferOk">
        <button class="sekundaer" title="Thema auf den Server pushen (überschreibt dort)"
                :disabled="!topic || !!uebertragung || state?.run?.status === 'running'"
                @click="uebertragen('push')">⇡ Push</button>
        <button class="sekundaer" title="Thema vom Server pullen (überschreibt lokal)"
                :disabled="!topic || !!uebertragung || state?.run?.status === 'running'"
                @click="uebertragen('pull')">⇣ Pull</button>
        <span v-if="uebertragung" class="badge blau">{{ uebertragung }}…</span>
      </template>
      <span v-if="state?.run" class="badge" :class="runBadge(state.run).farbe">{{ runBadge(state.run).text }}</span>
      <span v-if="state" class="badge">{{ tok(state.verbraucht) }} Tokens</span>
      <span v-if="state?.run?.grund" class="badge gelb">{{ state.run.grund }}</span>
      <span v-if="fehler" class="badge rot">{{ fehler }}</span>
      <span style="flex: 1"></span>
      <select v-model="theme" title="Farbschema">
        <option value="hell">hell</option>
        <option value="dunkel">dunkel</option>
        <option value="papier">papier</option>
        <option value="auto">auto</option>
      </select>
    </div>
    <div class="inhalt">
      <Board v-if="tab === 'board'" :state="state" :topic="topic" @reload="stateLaden" />
      <Guide v-else-if="tab === 'guide'" :topic="topic" :state="state" />
      <Ueben v-else-if="tab === 'üben'" :topic="topic" />
      <Kennzahlen v-else :run="state?.run" />
    </div>
  </div>
</template>
