<script setup>
import { ref, computed, watch } from 'vue'
import { fetchBlocksOverview, fetchBlocksCompleteness } from '../api.js'
import { usePolling } from '../composables/usePolling.js'

const props = defineProps({
  topic: { type: String, required: true },
  generating: { type: Boolean, default: false },
  progress: { type: String, default: null },
  ready: { type: Boolean, default: false },
  partial: { type: Boolean, default: false },
})
const emit = defineEmits(['close', 'openGeneration'])

const items = ref([])
const loading = ref(true)
const error = ref(null)
const comp = ref(null)      // Vollständigkeits-Beleg (nur wenn ready)
const compOpen = ref(false)

async function loadCompleteness() {
  if (!props.ready) { comp.value = null; return }
  try {
    comp.value = await fetchBlocksCompleteness(props.topic)
  } catch { comp.value = null }
}
watch(() => [props.topic, props.ready, props.generating], loadCompleteness, { immediate: true })

// Während einer Generierung wächst das Grid live nach (leichter Overview-Poll,
// das Kanban-Board selbst lebt in der Generierungs-View). Visibility-Pause via usePolling.
const { start: startPoll } = usePolling(load, () => props.generating, 5000)
watch(() => props.topic, () => { items.value = []; load() }, { immediate: true })
watch(() => props.generating, (g) => { if (g) startPoll(); else load() }, { immediate: true })

// ── Fertige Blöcke (Grid) ──────────────────────────────────────────────────────
const LEVELS = [
  { key: 'beginner', label: 'Beginner' },
  { key: 'advanced', label: 'Advanced' },
  { key: 'expert', label: 'Expert' },
]
const LEGACY_LEVEL = { einfach: 'beginner', mittel: 'advanced', schwer: 'expert' }

async function load() {
  if (!items.value.length) loading.value = true  // Spinner nur beim Erstladen, Live-Reload flackert nicht
  error.value = null
  try {
    items.value = await fetchBlocksOverview(props.topic)
  } catch (e) {
    items.value = []
    error.value = 'Overview not available — create blocks first.'
  } finally {
    loading.value = false
  }
}

function relevant(b) {
  const withRelevance = (b.subblocks || []).filter((s) => s.relevance)
  return !withRelevance.length || withRelevance.some((s) => s.relevance === 'relevant')
}

function groups(b) {
  return LEVELS
    .map((st) => ({ ...st, subs: (b.subblocks || []).filter((s) => (LEGACY_LEVEL[s.level] || s.level) === st.key) }))
    .filter((g) => g.subs.length)
}

const subTotal = computed(() => items.value.reduce((n, b) => n + (b.subblocks?.length || 0), 0))
</script>

<template>
  <div class="bk-view">
    <header class="bk-head">
      <h1>{{ topic }}</h1>
      <span class="bk-sub">Bausteine-Übersicht</span>
      <span v-if="items.length" class="bk-count">{{ items.length }} Blocks · {{ subTotal }} Subblocks</span>
      <span class="bk-spacer"></span>
      <button class="bk-close" title="Schließen" @click="emit('close')">✕</button>
    </header>

    <button v-if="generating" class="bk-banner" @click="emit('openGeneration')">
      <span class="bk-progress-dot"></span>
      Generierung läuft{{ progress ? ' · ' + progress : '' }} — Board öffnen →
    </button>
    <button v-else-if="!ready && !partial && !items.length && !loading" class="bk-banner idle" @click="emit('openGeneration')">
      Noch keine Bausteine — zur Generierung →
    </button>

    <section v-if="comp" class="bk-panel" :class="{ ok: comp.vollstaendig }">
      <button class="bk-panel-row" @click="compOpen = !compOpen">
        <span class="bk-panel-status">{{ comp.vollstaendig ? '✓ Zerlegung vollständig' : '○ Zerlegung unvollständig' }}</span>
        <span class="bk-panel-stat">{{ comp.bloecke }} Blöcke</span>
        <span class="bk-panel-stat">{{ comp.subs }} Subbausteine</span>
        <span v-if="comp.ziele_total" class="bk-panel-stat">Lernziele {{ comp.ziele_covered }}/{{ comp.ziele_total }}</span>
        <span class="bk-panel-stat">{{ comp.frage_bloecke }}/{{ comp.bloecke }} mit Prüfungsfragen</span>
        <span class="bk-panel-stat">{{ comp.lernkarten }} Lernartefakte</span>
        <span v-if="comp.dead" class="bk-panel-stat warn">{{ comp.dead }} dead</span>
        <span class="bk-panel-toggle">{{ compOpen ? '▴' : '▾' }}</span>
      </button>
      <div v-if="compOpen" class="bk-panel-detail">
        <span>{{ comp.verworfen }} Kandidaten geprüft verworfen</span>
        <span>{{ comp.zusammengelegt }} zusammengelegt (Dubletten/Umbrellas)</span>
        <span>{{ comp.degradiert_geprueft }} Fragmente degradiert (Panel-geprüft)</span>
        <span v-if="comp.panel_gerettet">{{ comp.panel_gerettet }} vom Panel gerettet</span>
        <span v-if="comp.lauf_minuten">Lauf: {{ comp.lauf_minuten }} min</span>
      </div>
    </section>

    <div v-if="loading" class="bk-empty-state">Lädt…</div>
    <div v-else-if="error && !generating" class="bk-empty-state">{{ error }}</div>
    <div v-else-if="!items.length" class="bk-empty-state">Noch keine Bausteine.</div>

    <div v-else class="bk-grid">
      <article
        v-for="b in items"
        :key="b.num"
        class="bk-card"
        :class="{ 'bk-irrelevant': !relevant(b) }"
        :title="relevant(b) ? null : 'Not relevant — comes later in the &quot;Rest&quot;'"
      >
        <h3 class="bk-title"><span class="bk-num">{{ b.num }}</span>{{ b.title }}</h3>
        <p v-if="b.description" class="bk-desc">{{ b.description }}</p>
        <div v-if="b.subblocks && b.subblocks.length" class="bk-levels">
          <div v-for="g in groups(b)" :key="g.key" class="bk-level" :class="'st-' + g.key">
            <span class="bk-level-label">{{ g.label }}</span>
            <ul>
              <li v-for="s in g.subs" :key="s.title" :class="{ rand: s.relevance === 'peripheral' }">
                {{ s.title }}<span v-if="s.relevance === 'peripheral'" class="rand-tag" title="Randthema — kommt später im „Rest">Rand</span>
              </li>
            </ul>
          </div>
        </div>
        <p v-else class="bk-no-subs">Keine Subbausteine.</p>
      </article>
    </div>
  </div>
</template>

<style scoped>
.bk-view {
  flex: 1;
  min-width: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow-y: auto;   /* EIN Seitenfluss: Board scrollt mit, nur der Kopf bleibt stehen */
  background: var(--bg-preview);
}

.bk-head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 1.25rem 2rem;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
}
.bk-head h1 { font-size: 1.5rem; }
.bk-sub { color: var(--text-faint); font-size: 0.9rem; font-weight: 600; }
.bk-count { color: var(--text-muted); font-size: 0.82rem; }
.bk-spacer { flex: 1; }
.bk-close {
  align-self: center;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  width: 2rem;
  height: 2rem;
  cursor: pointer;
}
.bk-close:hover { border-color: var(--accent); }

.bk-progress-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse-soft 1.2s ease-in-out infinite;
}





.bk-banner {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.85rem 2rem 0;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: var(--panel);
  color: var(--accent);
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
}
.bk-banner.idle { border-color: var(--border-strong); color: var(--text-muted); }
.bk-banner:hover { background: var(--panel-soft); }

.bk-panel {
  margin: 0.85rem 2rem 0;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--panel);
}
.bk-panel.ok { border-color: var(--level-beginner); }
.bk-panel-row {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1.1rem;
  padding: 0.55rem 0.9rem;
  border: none;
  background: none;
  color: var(--text);
  font-size: 0.82rem;
  cursor: pointer;
  text-align: left;
}
.bk-panel-status { font-weight: 700; }
.bk-panel.ok .bk-panel-status { color: var(--level-beginner); }
.bk-panel-stat { color: var(--text-muted); }
.bk-panel-stat.warn { color: var(--danger); font-weight: 600; }
.bk-panel-toggle { margin-left: auto; color: var(--text-faint); }
.bk-panel-detail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.1rem;
  padding: 0 0.9rem 0.6rem;
  font-size: 0.78rem;
  color: var(--text-faint);
  border-top: 1px dashed var(--border);
  padding-top: 0.5rem;
}

.bk-empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}

.bk-grid {
  flex: 1;
  padding: 1.5rem 2rem 4rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 1rem;
  align-content: start;
}

.bk-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent-border);
  border-radius: 10px;
  padding: 1rem 1.1rem;
}
.bk-card.bk-irrelevant { opacity: 0.5; }

.bk-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1rem;
  margin-bottom: 0.4rem;
}
.bk-num {
  flex: 0 0 auto;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  border-radius: 7px;
  background: var(--accent);
  color: var(--on-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  font-weight: 700;
}
.bk-desc {
  color: var(--text-muted);
  font-size: 0.85rem;
  line-height: 1.45;
  margin-bottom: 0.7rem;
}

.bk-levels { display: flex; flex-direction: column; gap: 0.55rem; }
.bk-level {
  border-left: 3px solid var(--st);
  padding-left: 0.6rem;
}
.bk-level.st-beginner { --st: var(--level-beginner); }
.bk-level.st-advanced { --st: var(--level-advanced); }
.bk-level.st-expert { --st: var(--level-expert); }

.bk-level-label {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--st);
}
.bk-level ul {
  list-style: disc;
  margin: 0.25rem 0 0;
  padding-left: 1.15rem;
}
.bk-level li {
  font-size: 0.85rem;
  color: var(--text);
  line-height: 1.35;
  margin-bottom: 2px;
}
.bk-level li::marker { color: var(--text-faint); }
.bk-level li.rand { color: var(--text-faint); }
.rand-tag {
  margin-left: 0.4rem;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-faint);
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  padding: 0 4px;
}

.bk-no-subs { color: var(--text-faint); font-size: 0.8rem; font-style: italic; }
</style>
