<template>
  <div class="kb-mgmt-view">
    <a-page-header
      title="知识库管理"
      sub-title="管理知识源、文档上传与索引同步"
      class="kb-mgmt-view__header"
    >
      <template #extra>
        <a-space :size="8">
          <a-button @click="loadAll" :loading="loadingSources || loadingDocs">刷新</a-button>
          <a-button type="primary" @click="openUpload">上传文档</a-button>
        </a-space>
      </template>
    </a-page-header>

    <a-tabs v-model:activeKey="activeTab">
      <!-- Sources -->
      <a-tab-pane key="sources" tab="知识源">
        <a-card>
          <a-table
            :columns="sourceColumns"
            :data-source="sources"
            :row-key="(record: IKbSource) => record.id"
            :loading="loadingSources"
            :pagination="false"
            size="middle"
          >
            <template #bodyCell="{ column, record }: { column: TableColumnType<IKbSource>; record: IKbSource }">
              <template v-if="column.key === 'status'">
                <a-tag :color="sourceStatusColor(record.status)">{{ record.status }}</a-tag>
              </template>
              <template v-else-if="column.key === 'last_synced'">
                {{ record.last_synced ? formatTime(record.last_synced) : '—' }}
              </template>
              <template v-else-if="column.key === 'actions'">
                <a-space :size="4">
                  <a-button type="link" size="small" @click="handleSync(record)">同步</a-button>
                  <a-button type="link" size="small" @click="handleRebuild(record)">重建索引</a-button>
                </a-space>
              </template>
            </template>
          </a-table>
        </a-card>
      </a-tab-pane>

      <!-- Documents -->
      <a-tab-pane key="documents" tab="文档">
        <a-card>
          <a-space direction="vertical" :size="16" style="width: 100%">
            <a-form layout="inline">
              <a-form-item label="知识源筛选">
                <a-select
                  v-model:value="docSourceFilter"
                  placeholder="全部知识源"
                  allow-clear
                  style="width: 240px"
                  :options="sourceFilterOptions"
                  @change="loadDocuments"
                />
              </a-form-item>
              <a-form-item label="部门筛选">
                <a-select
                  v-model:value="docDeptFilter"
                  placeholder="全部部门"
                  allow-clear
                  style="width: 200px"
                  :options="deptFilterOptions"
                  @change="loadDocuments"
                />
              </a-form-item>
            </a-form>

            <a-table
              :columns="docColumns"
              :data-source="documents"
              :row-key="(record: IKbDocument) => record.document_id"
              :loading="loadingDocs"
              :pagination="{ pageSize: 20, showSizeChanger: true }"
              size="middle"
            >
              <template #bodyCell="{ column, record }: { column: TableColumnType<IKbDocument>; record: IKbDocument }">
                <template v-if="column.key === 'status'">
                  <a-tag :color="docStatusColor(record.status)">{{ record.status }}</a-tag>
                </template>
                <template v-else-if="column.key === 'created_at'">
                  {{ formatTime(record.created_at) }}
                </template>
                <template v-else-if="column.key === 'actions'">
                  <a-popconfirm
                    title="确认删除该文档？"
                    ok-text="删除"
                    cancel-text="取消"
                    @confirm="handleDeleteDoc(record)"
                  >
                    <a-button type="link" danger size="small">删除</a-button>
                  </a-popconfirm>
                </template>
              </template>
            </a-table>
          </a-space>
        </a-card>
      </a-tab-pane>
    </a-tabs>

    <!-- Upload document modal -->
    <a-modal
      v-model:open="uploadOpen"
      title="上传文档"
      :confirm-loading="uploading"
      ok-text="上传"
      cancel-text="取消"
      @ok="handleUpload"
    >
      <a-form layout="vertical">
        <a-form-item label="文件名" required>
          <a-input v-model:value="uploadForm.filename" placeholder="如: guide.md" />
        </a-form-item>
        <a-form-item label="知识源 ID">
          <a-input v-model:value="uploadForm.source_id" placeholder="留空使用默认知识源" />
        </a-form-item>
        <a-form-item label="部门">
          <a-select
            v-model:value="uploadForm.department_id"
            placeholder="不绑定部门（全局）"
            allow-clear
            :options="deptFilterOptions"
          />
        </a-form-item>
        <a-form-item label="文档内容" required>
          <a-textarea
            v-model:value="uploadForm.content"
            :rows="10"
            placeholder="粘贴文档文本内容"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
/**
 * KB management view — sources list + documents list + upload/delete/sync/rebuild.
 *
 * Uses the existing ``kbApi`` for listing sources and the admin API for
 * document operations and source sync/rebuild.
 */
import { ref, reactive, computed, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import type { TableColumnType } from 'ant-design-vue'
import { kbApi, type IKbSource } from '@/api/kb'
import { adminApi, type IKbDocument, type IDepartment } from '@/api/admin'

interface ISelectOption {
  label: string
  value: string
}

const activeTab = ref<'sources' | 'documents'>('sources')

// --- Sources ---
const sources = ref<IKbSource[]>([])
const loadingSources = ref(false)

const sourceColumns: TableColumnType<IKbSource>[] = [
  { title: '名称', key: 'name', dataIndex: 'name', width: 200 },
  { title: '类型', key: 'type', dataIndex: 'type', width: 120 },
  { title: '文档数', key: 'document_count', dataIndex: 'document_count', width: 100 },
  { title: '状态', key: 'status', width: 120 },
  { title: '最近同步', key: 'last_synced', width: 180 },
  { title: '操作', key: 'actions', width: 180 },
]

function sourceStatusColor(status: string): string {
  switch (status) {
    case 'active':
    case 'healthy':
      return 'green'
    case 'syncing':
      return 'blue'
    case 'error':
      return 'red'
    default:
      return 'default'
  }
}

async function loadSources(): Promise<void> {
  loadingSources.value = true
  try {
    const res = await kbApi.listSources()
    sources.value = res.sources
  } catch (err) {
    message.error(extractMessage(err, '加载知识源列表失败'))
  } finally {
    loadingSources.value = false
  }
}

async function handleSync(record: IKbSource): Promise<void> {
  try {
    await adminApi.syncKbSource(record.id)
    message.success(`知识源 ${record.name} 同步已触发`)
    await loadSources()
  } catch (err) {
    message.error(extractMessage(err, '触发同步失败'))
  }
}

async function handleRebuild(record: IKbSource): Promise<void> {
  try {
    await adminApi.rebuildKbSource(record.id)
    message.success(`知识源 ${record.name} 索引重建已触发`)
    await loadSources()
  } catch (err) {
    message.error(extractMessage(err, '触发重建失败'))
  }
}

// --- Documents ---
const documents = ref<IKbDocument[]>([])
const loadingDocs = ref(false)
const docSourceFilter = ref<string | undefined>(undefined)
const docDeptFilter = ref<string | undefined>(undefined)
const departments = ref<IDepartment[]>([])

const docColumns: TableColumnType<IKbDocument>[] = [
  { title: '文件名', key: 'filename', dataIndex: 'filename', width: 240, ellipsis: true },
  { title: '知识源', key: 'source_id', dataIndex: 'source_id', width: 160, ellipsis: true },
  { title: '分块数', key: 'chunks', dataIndex: 'chunks', width: 90 },
  { title: '状态', key: 'status', width: 110 },
  { title: '部门', key: 'department_id', dataIndex: 'department_id', width: 140, ellipsis: true },
  { title: '创建时间', key: 'created_at', width: 170 },
  { title: '操作', key: 'actions', width: 100, fixed: 'right' },
]

function docStatusColor(status: string): string {
  switch (status) {
    case 'ready':
    case 'indexed':
      return 'green'
    case 'processing':
    case 'pending':
      return 'blue'
    case 'error':
    case 'failed':
      return 'red'
    default:
      return 'default'
  }
}

const sourceFilterOptions = computed<ISelectOption[]>(() =>
  sources.value.map((s) => ({ label: s.name, value: s.id })),
)

const deptFilterOptions = computed<ISelectOption[]>(() =>
  departments.value.map((d) => ({ label: d.name, value: d.id })),
)

async function loadDocuments(): Promise<void> {
  loadingDocs.value = true
  try {
    documents.value = await adminApi.listKbDocuments(docSourceFilter.value, docDeptFilter.value)
  } catch (err) {
    message.error(extractMessage(err, '加载文档列表失败'))
  } finally {
    loadingDocs.value = false
  }
}

async function loadDepartments(): Promise<void> {
  try {
    departments.value = await adminApi.listDepartments()
  } catch (err) {
    message.error(extractMessage(err, '加载部门列表失败'))
  }
}

async function handleDeleteDoc(record: IKbDocument): Promise<void> {
  try {
    await adminApi.deleteKbDocument(record.document_id)
    message.success('文档已删除')
    await loadDocuments()
  } catch (err) {
    message.error(extractMessage(err, '删除文档失败'))
  }
}

// --- Upload ---
const uploadOpen = ref(false)
const uploading = ref(false)
const uploadForm = reactive({
  filename: '',
  content: '',
  source_id: '',
  department_id: undefined as string | undefined,
})

function openUpload(): void {
  uploadForm.filename = ''
  uploadForm.content = ''
  uploadForm.source_id = ''
  uploadForm.department_id = undefined
  uploadOpen.value = true
}

async function handleUpload(): Promise<void> {
  if (!uploadForm.filename.trim() || !uploadForm.content.trim()) {
    message.warning('请填写文件名和文档内容')
    return
  }
  uploading.value = true
  try {
    await adminApi.uploadKbDocument({
      filename: uploadForm.filename.trim(),
      content: uploadForm.content,
      source_id: uploadForm.source_id || '',
      department_id: uploadForm.department_id,
    })
    message.success('文档已上传')
    uploadOpen.value = false
    await loadDocuments()
  } catch (err) {
    message.error(extractMessage(err, '上传文档失败'))
  } finally {
    uploading.value = false
  }
}

// --- Helpers ---
function formatTime(iso: string): string {
  if (!iso) return '—'
  try {
    return new Date(iso).toLocaleString('zh-CN', { hour12: false })
  } catch {
    return iso
  }
}

function extractMessage(err: unknown, fallback: string): string {
  if (err && typeof err === 'object') {
    const obj = err as { detail?: unknown; message?: unknown }
    if (typeof obj.detail === 'string' && obj.detail) return obj.detail
    if (typeof obj.message === 'string' && obj.message) return obj.message
  }
  return fallback
}

async function loadAll(): Promise<void> {
  await Promise.all([loadSources(), loadDocuments(), loadDepartments()])
}

onMounted(() => {
  loadAll()
})
</script>

<style scoped>
.kb-mgmt-view {
  padding: 24px;
  max-width: 1200px;
  margin: 0 auto;
}

.kb-mgmt-view__header {
  margin-bottom: 16px;
}
</style>
