<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import apiClient from '@/api/client'
import { copyToClipboard } from '@/utils/clipboard'

const route = useRoute()
const kbId = route.params.id as string

const isMobile = ref(window.innerWidth <= 768)
const showMobileSidebar = ref(false)

window.addEventListener('resize', () => {
  isMobile.value = window.innerWidth <= 768
  if (!isMobile.value) showMobileSidebar.value = false
})

const kb = ref<any>(null)
const docs = ref<any[]>([])
const categories = ref<any[]>([])
const allCategoriesFlat = ref<any[]>([])
const loading = ref(false)
const uploading = ref(false)
const aiUrl = ref('')
const selectedCategoryId = ref<string | null>(null)
const selectedCategoryPath = ref<string | null>(null)

// 文本内容对话框
const showTextDialog = ref(false)
const textForm = ref({
  title: '',
  content: '',
  content_format: 'markdown',
  category_id: null as string | null,
})
const textLoading = ref(false)

// 目录管理
const showCatDialog = ref(false)
const catForm = ref({ name: '', parent_id: null as string | null, is_folder: true })
const catLoading = ref(false)
const editingCatId = ref<string | null>(null)

// 编辑文档分类
const editingDocId = ref<string | null>(null)

onMounted(async () => {
  await loadKb()
  await loadCategories()
  await loadDocs()
  await loadLink()
})

async function loadKb() {
  try {
    const { data } = await apiClient.get(`/knowledge-bases/${kbId}`)
    kb.value = data
  } catch { /* ignore */ }
}

async function loadCategories() {
  try {
    const { data } = await apiClient.get(`/knowledge-bases/${kbId}/categories/tree`)
    categories.value = data
    // 同时加载平铺列表
    const { data: flat } = await apiClient.get(`/knowledge-bases/${kbId}/categories`)
    allCategoriesFlat.value = flat
  } catch { /* ignore */ }
}

async function loadDocs() {
  loading.value = true
  try {
    let url = `/documents?kb_id=${kbId}`
    if (selectedCategoryId.value) {
      url += `&category_id=${selectedCategoryId.value}`
    }
    const { data } = await apiClient.get(url)
    docs.value = data.items
  } catch { /* ignore */ }
  loading.value = false
}

// 链接有效期
const expiryOptions = [
  { label: '10 分钟', value: 10 },
  { label: '30 分钟', value: 30 },
  { label: '1 小时', value: 60 },
  { label: '3 小时', value: 180 },
  { label: '24 小时', value: 1440 },
  { label: '长期有效', value: 0 },
]
const linkExpiry = ref<{ expires_at: string | null; is_expired: boolean }>({
  expires_at: null,
  is_expired: false,
})
const expiryText = computed(() => {
  if (linkExpiry.value.is_expired) return '⛔ 已失效'
  if (!linkExpiry.value.expires_at) return '♾️ 长期有效'
  return `⏱️ 有效期至 ${linkExpiry.value.expires_at}`
})

async function loadLink() {
  try {
    const { data } = await apiClient.get(`/knowledge-bases/${kbId}/link`)
    aiUrl.value = `${window.location.origin}/k/${data.token}`
    linkExpiry.value = {
      expires_at: data.expires_at,
      is_expired: data.is_expired,
    }
  } catch { /* ignore */ }
}

// 设置链接有效期（0 = 长期有效，需二次确认）
async function handleExpiryChange(val: number) {
  if (val === 0) {
    try {
      await ElMessageBox.confirm(
        '长期有效的链接一旦泄露，任何持有该链接的人都可永久访问此知识库，存在泄露风险。确定设为长期有效？',
        '⚠️ 泄露风险提示',
        { type: 'warning', confirmButtonText: '仍要设为长期有效', cancelButtonText: '取消' },
      )
    } catch {
      return // 用户取消
    }
  }
  try {
    await apiClient.post(`/knowledge-bases/${kbId}/set-expiry`, {
      expires_in_minutes: val === 0 ? null : val,
    })
    ElMessage.success('链接有效期已更新。')
    loadLink()
  } catch { /* ignore */ }
}

function selectCategory(cat: any) {
  selectedCategoryId.value = cat.id
  selectedCategoryPath.value = cat.path
  loadDocs()
}

function clearCategoryFilter() {
  selectedCategoryId.value = null
  selectedCategoryPath.value = null
  loadDocs()
}

// 上传文档
async function handleUpload(options: any) {
  uploading.value = true
  try {
    const formData = new FormData()
    formData.append('kb_id', kbId)
    formData.append('file', options.file)
    if (selectedCategoryId.value) {
      formData.append('category_id', selectedCategoryId.value)
    }
    await apiClient.post('/documents/upload', formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
    })
    ElMessage.success('文档上传成功！')
    loadDocs()
    loadCategories()
  } catch { /* ignore */ }
  uploading.value = false
}

// 打开添加文本对话框（预填左侧选中的目录，对话框内的选择优先）
function openTextDialog() {
  textForm.value.category_id = selectedCategoryId.value
  showTextDialog.value = true
}

// 创建文本内容
async function handleCreateText() {
  if (!textForm.value.title.trim() || !textForm.value.content.trim()) {
    ElMessage.warning('请输入标题和内容。')
    return
  }
  textLoading.value = true
  try {
    await apiClient.post('/documents/create-text', {
      kb_id: kbId,
      title: textForm.value.title,
      content: textForm.value.content,
      content_format: textForm.value.content_format,
      category_id: textForm.value.category_id,
    })
    ElMessage.success('文本内容已创建！')
    showTextDialog.value = false
    textForm.value = { title: '', content: '', content_format: 'markdown', category_id: null }
    loadDocs()
    loadCategories()
  } catch { /* ignore */ }
  textLoading.value = false
}

// 修改文档分类
async function handleChangeDocCategory(doc: any, newCategoryId: string) {
  try {
    await apiClient.put(`/documents/${doc.id}`, { category_id: newCategoryId })
    ElMessage.success('目录已更新。')
    loadDocs()
    loadCategories()
  } catch { /* ignore */ }
}

async function handleDeleteDoc(doc: any) {
  try {
    await ElMessageBox.confirm(`确定删除「${doc.original_filename}」？`, '确认删除', { type: 'warning' })
    await apiClient.delete(`/documents/${doc.id}`)
    ElMessage.success('已删除。')
    loadDocs()
    loadCategories()
  } catch { /* ignore */ }
}

async function handleReprocess(doc: any) {
  try {
    await apiClient.post(`/documents/${doc.id}/reprocess`)
    ElMessage.success('重新解析已提交。')
    loadDocs()
  } catch { /* ignore */ }
}

async function handleCopyLink() {
  const success = await copyToClipboard(aiUrl.value)
  if (success) {
    ElMessage.success('AI 链接已复制！')
  } else {
    ElMessage.error('复制失败，请手动长按复制。')
  }
}

// 重新生成 AI 链接
async function handleRegenerateLink() {
  try {
    await ElMessageBox.confirm('重新生成链接后，旧链接将立即失效。确定继续？', '确认', { type: 'warning' })
    const { data } = await apiClient.post(`/knowledge-bases/${kbId}/regenerate-token`)
    aiUrl.value = `${window.location.origin}/k/${data.token}`
    ElMessage.success('链接已重新生成！')
  } catch { /* ignore */ }
}

// 目录管理
function openAddCategory(parentId: string | null = null) {
  editingCatId.value = null
  catForm.value = { name: '', parent_id: parentId, is_folder: true }
  showCatDialog.value = true
}

function openEditCategory(cat: any) {
  editingCatId.value = cat.id
  catForm.value = { name: cat.name, parent_id: cat.parent_id || null, is_folder: cat.is_folder }
  showCatDialog.value = true
}

async function handleSaveCategory() {
  if (!catForm.value.name.trim()) {
    ElMessage.warning('请输入目录名称。')
    return
  }
  catLoading.value = true
  try {
    if (editingCatId.value) {
      await apiClient.put(`/knowledge-bases/${kbId}/categories/${editingCatId.value}`, catForm.value)
      ElMessage.success('目录已更新。')
    } else {
      await apiClient.post(`/knowledge-bases/${kbId}/categories`, catForm.value)
      ElMessage.success('目录已创建。')
    }
    showCatDialog.value = false
    loadCategories()
  } catch { /* ignore */ }
  catLoading.value = false
}

async function handleDeleteCategory(cat: any) {
  try {
    await ElMessageBox.confirm(`确定删除目录「${cat.name}」及其所有子目录？`, '确认删除', { type: 'warning' })
    await apiClient.delete(`/knowledge-bases/${kbId}/categories/${cat.id}`)
    ElMessage.success('已删除。')
    if (selectedCategoryId.value === cat.id) {
      clearCategoryFilter()
    }
    loadCategories()
    loadDocs()
  } catch { /* ignore */ }
}

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

function statusType(status: string) {
  if (status === 'READY') return 'success'
  if (status === 'FAILED') return 'danger'
  return 'warning'
}

// 获取分类名称
function getCategoryName(catId: string) {
  const cat = allCategoriesFlat.value.find((c: any) => c.id === catId)
  return cat ? cat.name : '未分类'
}

// AI 链接打码：显示域名，token 部分用 • 代替
const maskedAiUrl = computed(() => {
  if (!aiUrl.value) return '尚未生成'
  const idx = aiUrl.value.indexOf('/k/')
  if (idx === -1) return '••••••••'
  const prefix = aiUrl.value.slice(0, idx + 3)
  const tokenLen = aiUrl.value.length - idx - 3
  return prefix + '•'.repeat(tokenLen)
})
</script>

<template>
  <div v-if="kb">
    <!-- 手机端：顶部操作栏 -->
    <div class="mobile-header">
      <h1 style="margin: 0; font-size: 20px">{{ kb.name }}</h1>
      <div style="display: flex; gap: 8px; margin-top: 10px">
        <el-button @click="handleCopyLink" size="small" style="flex: 1">📋 复制链接</el-button>
        <el-button type="warning" @click="handleRegenerateLink" size="small" style="flex: 1">🔄 重置链接</el-button>
      </div>
    </div>

    <div class="main-layout">
      <!-- 左侧：目录树（桌面端常驻，手机端抽屉） -->
      <aside class="sidebar" :class="{ 'mobile-show': showMobileSidebar }">
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px">
          <h3 style="margin: 0; font-size: 16px">📁 目录</h3>
          <el-button size="small" type="primary" @click="openAddCategory(null)">+ 新建</el-button>
        </div>

        <div
          class="cat-item"
          :class="{ active: !selectedCategoryId }"
          @click="clearCategoryFilter"
        >
          📋 全部文档
        </div>

        <el-tree :data="categories" node-key="id" default-expand-all :expand-on-click-node="false">
          <template #default="{ data }">
            <div class="tree-node">
              <span class="tree-label" :class="{ selected: selectedCategoryId === data.id }" @click="selectCategory(data)">
                {{ data.is_folder ? '📁' : '📄' }} {{ data.name }}
                <span v-if="data.doc_count > 0" style="color: #999; font-size: 12px">({{ data.doc_count }})</span>
              </span>
              <span class="tree-actions">
                <el-button size="small" text @click.stop="openAddCategory(data.id)">+</el-button>
                <el-button size="small" text @click.stop="openEditCategory(data)">✎</el-button>
                <el-button size="small" text type="danger" @click.stop="handleDeleteCategory(data)">×</el-button>
              </span>
            </div>
          </template>
        </el-tree>
      </aside>

      <!-- 手机端遮罩 -->
      <div v-if="showMobileSidebar" class="mobile-overlay" @click="showMobileSidebar = false"></div>

      <!-- 右侧：文档列表 -->
      <main class="content">
        <!-- 桌面端标题 -->
        <div class="desktop-header">
          <h1 style="margin: 0; font-size: 24px">{{ kb.name }}</h1>
          <div style="display: flex; gap: 12px">
            <el-button @click="handleCopyLink" size="large">📋 复制 AI 链接</el-button>
            <el-button type="warning" @click="handleRegenerateLink" size="large">🔄 重新生成链接</el-button>
          </div>
        </div>

        <!-- AI 链接（打码显示，只能复制获取） -->
        <el-card style="margin-bottom: 16px" shadow="hover">
          <div style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap">
            <span style="font-weight: bold; font-size: 14px">AI 链接：</span>
            <span style="flex: 1; min-width: 200px; font-size: 14px; color: #666; font-family: monospace; user-select: none">
              {{ maskedAiUrl }}
            </span>
            <el-select
              :model-value="null"
              placeholder="⏱️ 设置有效期"
              style="width: 150px"
              @change="(val: number) => handleExpiryChange(val)"
            >
              <el-option
                v-for="opt in expiryOptions"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              />
            </el-select>
            <el-button type="primary" @click="handleCopyLink" size="large">📋 复制 AI 链接</el-button>
          </div>
          <div style="display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin-top: 8px; font-size: 12px">
            <span :style="{ color: linkExpiry.is_expired ? '#f56c6c' : '#67c23a', fontWeight: linkExpiry.is_expired ? 'bold' : 'normal' }">
              {{ expiryText }}
            </span>
            <span style="color: #999">🔒 链接即访问凭证，已隐藏显示；仅可通过复制按钮获取。请勿公开传播。</span>
          </div>
        </el-card>

        <!-- 手机端目录按钮 + 操作按钮 -->
        <div class="mobile-actions">
          <el-button @click="showMobileSidebar = true" style="flex: 1">📁 目录</el-button>
          <el-button @click="openTextDialog" style="flex: 1">✏️ 添加文本</el-button>
          <el-upload :show-file-list="false" :http-request="handleUpload" accept=".docx,.pdf" style="flex: 1">
            <el-button type="primary" :loading="uploading" style="width: 100%">📤 上传</el-button>
          </el-upload>
        </div>

        <el-card shadow="hover">
          <template #header>
            <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px">
              <span style="font-size: 16px; font-weight: bold">
                📄 文档列表
                <el-tag v-if="selectedCategoryPath" closable @close="clearCategoryFilter" style="margin-left: 8px">
                  {{ selectedCategoryPath }}
                </el-tag>
              </span>
              <div class="desktop-actions">
                <el-button @click="openTextDialog">✏️ 添加文本</el-button>
                <el-upload :show-file-list="false" :http-request="handleUpload" accept=".docx,.pdf">
                  <el-button type="primary" :loading="uploading">📤 上传文档</el-button>
                </el-upload>
              </div>
            </div>
          </template>

          <!-- 桌面端：表格 -->
          <div class="desktop-table">
            <el-table :data="docs" v-loading="loading" style="width: 100%">
              <el-table-column prop="original_filename" label="标题" min-width="180" show-overflow-tooltip />
              <el-table-column label="目录" width="180">
                <template #default="{ row }">
                  <el-select :model-value="row.category_id" @change="(val: string) => handleChangeDocCategory(row, val)" placeholder="选择目录" size="small" style="width: 100%">
                    <el-option v-for="cat in allCategoriesFlat" :key="cat.id" :label="cat.name" :value="cat.id" />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column label="状态" width="90" align="center">
                <template #default="{ row }">
                  <el-tag :type="statusType(row.status)" size="small">{{ row.status }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="大小" width="80" align="center">
                <template #default="{ row }">{{ formatSize(row.file_size) }}</template>
              </el-table-column>
              <el-table-column label="操作" width="180" align="center">
                <template #default="{ row }">
                  <el-button size="small" @click="handleReprocess(row)">重新解析</el-button>
                  <el-button size="small" type="danger" @click="handleDeleteDoc(row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>

          <!-- 手机端：卡片列表 -->
          <div class="mobile-cards">
            <div v-for="doc in docs" :key="doc.id" class="doc-card">
              <div style="font-weight: bold; font-size: 15px; margin-bottom: 8px">{{ doc.original_filename }}</div>
              <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap">
                <el-tag :type="statusType(doc.status)" size="small">{{ doc.status }}</el-tag>
                <span style="color: #999; font-size: 12px">{{ formatSize(doc.file_size) }}</span>
              </div>
              <el-select :model-value="doc.category_id" @change="(val: string) => handleChangeDocCategory(doc, val)" placeholder="选择目录" size="small" style="width: 100%; margin-bottom: 8px">
                <el-option v-for="cat in allCategoriesFlat" :key="cat.id" :label="cat.name" :value="cat.id" />
              </el-select>
              <div style="display: flex; gap: 8px">
                <el-button size="small" style="flex: 1" @click="handleReprocess(doc)">重新解析</el-button>
                <el-button size="small" type="danger" style="flex: 1" @click="handleDeleteDoc(doc)">删除</el-button>
              </div>
            </div>
          </div>
        </el-card>
      </main>
    </div>

    <!-- 对话框 -->
    <el-dialog v-model="showTextDialog" title="✏️ 添加文本内容" :width="isMobile ? '95%' : '700px'">
      <el-form :model="textForm" label-position="top">
        <el-form-item label="标题" required>
          <el-input v-model="textForm.title" placeholder="文档标题" size="large" />
        </el-form-item>
        <el-form-item label="所属目录">
          <el-select v-model="textForm.category_id" placeholder="选择目录" clearable style="width: 100%" size="large">
            <el-option v-for="cat in allCategoriesFlat" :key="cat.id" :label="cat.name" :value="cat.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="格式">
          <el-radio-group v-model="textForm.content_format" size="large">
            <el-radio value="markdown">Markdown</el-radio>
            <el-radio value="text">纯文本</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="内容" required>
          <el-input v-model="textForm.content" type="textarea" :rows="12" placeholder="输入文本内容（支持 Markdown）" size="large" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showTextDialog = false" size="large">取消</el-button>
        <el-button type="primary" :loading="textLoading" @click="handleCreateText" size="large">创建</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="showCatDialog" :title="editingCatId ? '✏️ 编辑目录' : '📁 新建目录'" :width="isMobile ? '95%' : '450px'">
      <el-form :model="catForm" label-position="top">
        <el-form-item label="目录名称" required>
          <el-input v-model="catForm.name" placeholder="如：公司基本信息" size="large" />
        </el-form-item>
        <el-form-item label="类型">
          <el-radio-group v-model="catForm.is_folder" size="large">
            <el-radio :value="true">📁 文件夹</el-radio>
            <el-radio :value="false">📄 叶子分类</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCatDialog = false" size="large">取消</el-button>
        <el-button type="primary" :loading="catLoading" @click="handleSaveCategory" size="large">{{ editingCatId ? '保存' : '创建' }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.main-layout {
  display: flex;
  gap: 20px;
}

.sidebar {
  width: 280px;
  flex-shrink: 0;
  overflow-y: auto;
  max-height: calc(100vh - 180px);
  position: sticky;
  top: 20px;
}

.content {
  flex: 1;
  min-width: 0;
}

.cat-item {
  padding: 10px 12px;
  cursor: pointer;
  border-radius: 6px;
  margin-bottom: 6px;
  font-size: 14px;
  background: #f5f7fa;
  transition: all 0.2s;
}

.cat-item:hover {
  background: #e8e8e8;
}

.cat-item.active {
  background: #ecf5ff;
  color: #409eff;
  font-weight: bold;
}

.tree-node {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 4px 0;
}

.tree-label {
  cursor: pointer;
  font-size: 14px;
  flex: 1;
}

.tree-label.selected {
  color: #409eff;
  font-weight: bold;
}

.tree-actions {
  display: flex;
  gap: 2px;
}

.mobile-header {
  display: none;
}

.mobile-actions {
  display: none;
}

.mobile-cards {
  display: none;
}

.desktop-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.desktop-actions {
  display: flex;
  gap: 10px;
}

.mobile-overlay {
  display: none;
}

/* 手机端适配 */
@media (max-width: 768px) {
  .main-layout {
    flex-direction: column;
  }

  .sidebar {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 80%;
    max-width: 300px;
    height: 100vh;
    background: #fff;
    z-index: 1000;
    padding: 20px;
    box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
    overflow-y: auto;
    max-height: 100vh;
  }

  .sidebar.mobile-show {
    display: block;
  }

  .mobile-overlay {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 999;
  }

  .content {
    width: 100%;
  }

  .mobile-header {
    display: block;
    margin-bottom: 16px;
  }

  .desktop-header {
    display: none;
  }

  .mobile-actions {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
  }

  .desktop-actions {
    display: none;
  }

  .desktop-table {
    display: none;
  }

  .mobile-cards {
    display: block;
  }

  .doc-card {
    border: 1px solid #eee;
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 12px;
  }
}
</style>
