<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { BookOpen, Search, ArrowLeft, Clock, FileText, Filter, Loader2 } from '@lucide/vue'
import { apiFetch } from '../services/api'
import { renderMarkdown } from '../utils/markdown'
import type { DocFile, DocDetail } from '../types'

// State
const docs = ref<DocFile[]>([])
const loading = ref(false)
const error = ref('')

const searchQuery = ref('')
const categoryFilter = ref('')

const selectedDoc = ref<DocDetail | null>(null)
const contentLoading = ref(false)

const categories = ['phases', 'skills', 'workspace', 'nexus', 'nexus-phases']

// Filtered + sorted docs (newest first)
const filteredDocs = computed(() => {
  let items = [...docs.value]
  if (categoryFilter.value) {
    items = items.filter(d => d.category === categoryFilter.value)
  }
  if (searchQuery.value.trim()) {
    const q = searchQuery.value.trim().toLowerCase()
    items = items.filter(d => d.name.toLowerCase().includes(q) || d.path.toLowerCase().includes(q))
  }
  return items.sort((a, b) => new Date(b.modifiedAt).getTime() - new Date(a.modifiedAt).getTime())
})

async function loadDocs() {
  loading.value = true
  error.value = ''
  try {
    const response = await apiFetch('/api/v1/docs')
    if (!response.ok) throw new Error('Failed to load documents')
    docs.value = await response.json()
  } catch (e) {
    error.value = e instanceof Error ? e.message : 'Failed to load documents'
  } finally {
    loading.value = false
  }
}

async function loadDocContent(path: string) {
  contentLoading.value = true
  selectedDoc.value = null
  try {
    const response = await apiFetch(`/api/v1/docs/${encodeURIComponent(path)}`)
    if (!response.ok) throw new Error('Failed to load document content')
    selectedDoc.value = await response.json()
  } catch (e) {
    error.value = e instanceof Error ? e.message : 'Failed to load document content'
  } finally {
    contentLoading.value = false
  }
}

function selectDoc(name: string, path: string) {
  loadDocContent(path)
}

function goBack() {
  selectedDoc.value = null
}

function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString('de-DE', {
    year: 'numeric', month: 'short', day: 'numeric',
    hour: '2-digit', minute: '2-digit',
  })
}

function formatSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
}

onMounted(loadDocs)
</script>

<template>
  <div class="page-heading">
    <div>
      <span class="eyebrow">KNOWLEDGE</span>
      <h1>Docs</h1>
      <p>Browse documentation, agent skills, and workspace references.</p>
    </div>
  </div>

  <div class="docs-toolbar">
    <div class="docs-search-bar">
      <Search :size="16" />
      <input
        v-model="searchQuery"
        placeholder="Search documents..."
      />
    </div>
    <div class="docs-filter-group">
      <Filter :size="14" />
      <select v-model="categoryFilter">
        <option value="">All categories</option>
        <option v-for="cat in categories" :key="cat" :value="cat">{{ cat }}</option>
      </select>
    </div>
  </div>

  <div class="memory-layout">
    <!-- Left column: document list -->
    <aside class="memory-sidebar">
      <div v-if="loading" class="memory-status">
        <Loader2 :size="16" class="spin" />
        Loading documents...
      </div>
      <div v-else-if="error" class="memory-status error">{{ error }}</div>
      <template v-else-if="filteredDocs.length">
        <div class="memory-list-header">{{ filteredDocs.length }} documents</div>
        <button
          v-for="doc in filteredDocs"
          :key="doc.name + doc.path"
          :class="['memory-file-item', { active: selectedDoc?.name === doc.name && selectedDoc?.path === doc.path }]"
          @click="selectDoc(doc.name, doc.path)"
        >
          <div class="memory-file-icon">
            <FileText :size="14" />
          </div>
          <div class="memory-file-info">
            <strong>{{ doc.name }}</strong>
            <div class="doc-tags">
              <span :class="['doc-category-badge', `cat-${doc.category}`]">{{ doc.category }}</span>
              <span class="doc-type-tag">{{ doc.type }}</span>
            </div>
            <span class="memory-file-meta">
              <Clock :size="10" /> {{ formatDate(doc.modifiedAt) }}
              · {{ formatSize(doc.size) }}
            </span>
          </div>
        </button>
      </template>
      <div v-else class="memory-status">No documents match your filters</div>
    </aside>

    <!-- Right column: content -->
    <main class="memory-content">
      <template v-if="contentLoading">
        <div class="memory-status">
          <Loader2 :size="20" class="spin" />
          Loading content...
        </div>
      </template>
      <template v-else-if="selectedDoc">
        <header class="memory-content-header">
          <button class="memory-back-btn" @click="goBack">
            <ArrowLeft :size="14" />
            Back
          </button>
          <div>
            <strong>{{ selectedDoc.name }}</strong>
            <div class="doc-tags">
              <span :class="['doc-category-badge', `cat-${selectedDoc.category}`]">{{ selectedDoc.category }}</span>
              <span class="doc-type-tag">{{ selectedDoc.type }}</span>
            </div>
            <span class="memory-content-meta">
              <Clock :size="10" /> {{ formatDate(selectedDoc.modifiedAt) }}
              · {{ formatSize(selectedDoc.size) }}
            </span>
          </div>
        </header>
        <article
          class="memory-rendered"
          v-html="renderMarkdown(selectedDoc.content)"
        ></article>
      </template>
      <template v-else>
        <div class="memory-empty-state">
          <BookOpen :size="28" />
          <h3>Select a document</h3>
          <p>Choose a document from the list or use the search/filter to find what you need.</p>
        </div>
      </template>
    </main>
  </div>
</template>

<style scoped>
.docs-toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.docs-search-bar {
  flex: 1;
  min-width: 200px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: #6f7889;
}
.docs-search-bar input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  color: #e8eaf0;
  font: inherit;
  font-size: 13px;
}
.docs-filter-group {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: #8991a1;
}
.docs-filter-group select {
  border: none;
  outline: none;
  background: transparent;
  color: #e8eaf0;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.memory-layout {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 12px;
  min-height: 480px;
}
.memory-sidebar {
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
  padding: 8px;
  max-height: 640px;
  overflow-y: auto;
}
.memory-list-header {
  font-size: 9px;
  font-weight: 700;
  color: #7065c8;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  padding: 10px 8px 6px;
}
.memory-file-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 10px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: #e8eaf0;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.memory-file-item:hover,
.memory-file-item.active {
  background: var(--accent-soft);
}
.memory-file-icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  color: #a99cf5;
  background: rgba(139,124,246,.1);
}
.memory-file-info strong {
  display: block;
  font-size: 11px;
  margin-bottom: 3px;
  word-break: break-word;
}
.doc-tags {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin-bottom: 3px;
}
.doc-category-badge {
  font-size: 8px;
  padding: 1px 6px;
  border-radius: 6px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.doc-category-badge.cat-phases {
  background: rgba(139,124,246,.12);
  color: #a99cf5;
}
.doc-category-badge.cat-skills {
  background: rgba(81,212,154,.1);
  color: #51d49a;
}
.doc-category-badge.cat-workspace {
  background: rgba(229,176,94,.1);
  color: #e5b05e;
}
.doc-category-badge.cat-nexus {
  background: rgba(109,159,230,.1);
  color: #6d9fe6;
}
.doc-category-badge.cat-nexus-phases {
  background: rgba(225,110,117,.1);
  color: #e16e75;
}
.doc-type-tag {
  font-size: 8px;
  padding: 1px 5px;
  border: 1px solid #343947;
  border-radius: 4px;
  color: #8991a1;
}
.memory-file-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  color: #7e8799;
}
.memory-content {
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
  padding: 24px;
  min-height: 480px;
  overflow-y: auto;
}
.memory-content-header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.memory-content-header > div strong {
  display: block;
  font-size: 13px;
  margin-bottom: 4px;
}
.memory-content-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 9px;
  color: #7e8799;
  margin-top: 4px;
}
.memory-back-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: #8991a1;
  font-size: 10px;
  cursor: pointer;
  flex-shrink: 0;
}
.memory-back-btn:hover {
  color: #e8eaf0;
  background: var(--accent-soft);
}
.memory-status {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 32px;
  color: #7e8799;
  font-size: 11px;
}
.memory-status.error {
  color: #e16e75;
}
.memory-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 360px;
  color: #6b7385;
}
.memory-empty-state h3 {
  margin: 12px 0 6px;
  font-size: 14px;
  color: #a5adba;
}
.memory-empty-state p {
  margin: 0;
  font-size: 10px;
  color: #7e8799;
}
.memory-rendered {
  font-size: 12px;
  line-height: 1.7;
  color: #d0d4dd;
}
.memory-rendered :deep(h1),
.memory-rendered :deep(h2),
.memory-rendered :deep(h3) {
  color: #e8eaf0;
  margin: 1.2em 0 0.5em;
}
.memory-rendered :deep(h1) { font-size: 1.3rem; }
.memory-rendered :deep(h2) { font-size: 1.1rem; }
.memory-rendered :deep(h3) { font-size: 1rem; }
.memory-rendered :deep(p) { margin: 0.6em 0; }
.memory-rendered :deep(code) {
  padding: 2px 5px;
  background: rgba(139,124,246,.08);
  border-radius: 4px;
  font-size: 11px;
}
.memory-rendered :deep(pre) {
  padding: 12px;
  border-radius: 8px;
  background: #0d1016;
  border: 1px solid var(--nx-line);
  overflow-x: auto;
}
.memory-rendered :deep(pre code) {
  background: none;
  padding: 0;
}
.memory-rendered :deep(a) {
  color: #a99cf5;
  text-decoration: none;
}
.memory-rendered :deep(a:hover) {
  text-decoration: underline;
}
.memory-rendered :deep(ul) {
  padding-left: 20px;
}
.memory-rendered :deep(li) {
  margin: 0.3em 0;
}
.memory-rendered :deep(hr) {
  border: none;
  border-top: 1px solid var(--nx-line);
  margin: 1.2em 0;
}
.memory-rendered :deep(strong) {
  color: #e8eaf0;
}
.spin {
  animation: spin 1s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}

@media (max-width: 900px) {
  .memory-layout {
    grid-template-columns: 1fr;
  }
  .memory-sidebar {
    max-height: 280px;
  }
}
</style>
