<template>
  <div class="text-split">
    <!-- Header -->
    <div class="page-header">
      <div class="header-left">
        <h2 class="page-title">分割生成</h2>
        <p class="page-subtitle">选择文件进行智能分割</p>
      </div>
      <div class="header-actions">
        <el-button @click="refreshFiles" class="refresh-btn">
          <el-icon><Refresh /></el-icon>
          <span>刷新</span>
        </el-button>
        <el-button
          type="primary"
          @click="handleBatchGenerateQA"
          :disabled="!hasProcessedFiles"
          class="generate-btn"
        >
          <el-icon><ChatDotSquare /></el-icon>
          <span>批量生成问答对</span>
        </el-button>
      </div>
    </div>

    <!-- Stats Cards -->
    <div class="stats-grid">
      <div class="stat-card">
        <div class="stat-icon total">
          <el-icon><Document /></el-icon>
        </div>
        <div class="stat-content">
          <span class="stat-value">{{ files.length }}</span>
          <span class="stat-label">总文件</span>
        </div>
      </div>
      <div class="stat-card success">
        <div class="stat-icon">
          <el-icon><CircleCheckFilled /></el-icon>
        </div>
        <div class="stat-content">
          <span class="stat-value">{{ completedFiles }}</span>
          <span class="stat-label">已分割</span>
        </div>
      </div>
      <div class="stat-card processing">
        <div class="stat-icon">
          <el-icon><Loading /></el-icon>
        </div>
        <div class="stat-content">
          <span class="stat-value">{{ processingCount }}</span>
          <span class="stat-label">分割中</span>
        </div>
      </div>
      <div class="stat-card">
        <div class="stat-icon chunks">
          <el-icon><List /></el-icon>
        </div>
        <div class="stat-content">
          <span class="stat-value">{{ totalChunks }}</span>
          <span class="stat-label">总文本块</span>
        </div>
      </div>
    </div>

    <!-- File List / Split View -->
    <div class="content-area">
      <!-- Empty State -->
      <div v-if="!loading && files.length === 0" class="empty-state">
        <div class="empty-icon">
          <el-icon size="56"><FolderOpened /></el-icon>
        </div>
        <h3 class="empty-title">暂无可分割文件</h3>
        <p class="empty-desc">请先在文件管理中上传文档</p>
      </div>

      <!-- File Table -->
      <div v-else-if="!selectedFile" class="files-table-wrapper">
        <div class="table-header">
          <span class="table-title">文件列表</span>
        </div>
        <div class="files-list">
          <div
            v-for="(file, index) in files"
            :key="file.id"
            class="file-row"
            :class="{ processing: file.status === 'processing' }"
            :style="{ '--delay': index * 0.03 + 's' }"
            @click="handleFileClick(file)"
          >
            <div class="col-icon">
              <div class="file-type-icon" :style="{ background: getFileBg(file.file_type) }">
                <el-icon size="18" color="white">
                  <component :is="getFileIcon(file.file_type)" />
                </el-icon>
              </div>
            </div>
            <div class="col-name">
              <span class="file-name">{{ file.filename }}</span>
              <span class="file-meta">{{ formatSize(file.size) }}</span>
            </div>
            <div class="col-chunks">
              <span v-if="fileChunks[file.id]" class="chunk-count">
                {{ fileChunks[file.id] }} 块
              </span>
              <span v-else class="chunk-count empty">-</span>
            </div>
            <div class="col-status">
              <div v-if="file.status === 'processing'" class="status-badge processing">
                <el-icon class="spin" size="12"><Loading /></el-icon>
                <span>分割中</span>
              </div>
              <div v-else-if="fileChunks[file.id]" class="status-badge success">
                <el-icon size="12"><CircleCheckFilled /></el-icon>
                <span>已完成</span>
              </div>
              <div v-else class="status-badge pending">
                <el-icon size="12"><Clock /></el-icon>
                <span>待分割</span>
              </div>
            </div>
            <div class="col-action">
              <el-icon><ArrowRight /></el-icon>
            </div>
          </div>
        </div>
      </div>

      <!-- Split Detail View -->
      <div v-else class="split-detail">
        <div class="detail-header">
          <el-button text @click="selectedFile = null" class="back-btn">
            <el-icon><ArrowLeft /></el-icon>
            <span>返回文件列表</span>
          </el-button>
          <div class="file-info">
            <div class="file-type-icon small" :style="{ background: getFileBg(selectedFile.file_type) }">
              <el-icon size="14" color="white">
                <component :is="getFileIcon(selectedFile.file_type)" />
              </el-icon>
            </div>
            <span class="file-name">{{ selectedFile.filename }}</span>
          </div>
        </div>

        <!-- Split Config -->
        <div class="config-card">
          <div class="config-title">分割配置</div>
          <div class="config-form">
            <div class="form-row">
              <div class="form-item">
                <label>分割算法</label>
                <el-select v-model="splitConfig.method" placeholder="选择算法">
                  <el-option label="Markdown 结构分割" value="markdown_structure" />
                  <el-option label="递归字符分割" value="recursive" />
                  <el-option label="Token 数量分割" value="token" />
                  <el-option label="代码感知分割" value="code" />
                  <el-option label="自定义分隔符" value="custom" />
                </el-select>
              </div>
            </div>
            <div class="form-row sliders">
              <div class="form-item">
                <label>块大小: {{ splitConfig.chunk_size }}</label>
                <el-slider
                  v-model="splitConfig.chunk_size"
                  :min="100"
                  :max="2000"
                  :step="100"
                  :marks="{100: '100', 500: '500', 1000: '1k', 2000: '2k'}"
                />
              </div>
              <div class="form-item">
                <label>重叠字符: {{ splitConfig.overlap }}</label>
                <el-slider
                  v-model="splitConfig.overlap"
                  :min="0"
                  :max="500"
                  :step="50"
                  :marks="{0: '0', 250: '250', 500: '500'}"
                />
              </div>
            </div>
            <div class="form-item" v-if="splitConfig.method === 'custom'">
              <label>自定义分隔符</label>
              <el-input v-model="splitConfig.separator" placeholder="例如: \n\n 或 || 或 ---" />
            </div>
            <div class="config-actions">
              <el-button type="primary" @click="handleSplit" :loading="splitting" class="split-btn">
                <el-icon><CaretRight /></el-icon>
                开始分割
              </el-button>
            </div>
          </div>
        </div>

        <!-- Chunks List -->
        <div class="chunks-card" v-if="chunks.length > 0">
          <div class="chunks-header">
            <div class="chunks-title">
              <el-icon><List /></el-icon>
              <span>文本块 ({{ chunks.length }})</span>
            </div>
            <el-tag type="primary" effect="dark">
              总计 {{ totalWords }} 字
            </el-tag>
          </div>
          <div class="chunks-list" v-loading="loadingChunks">
            <div
              v-for="(chunk, index) in chunks"
              :key="chunk.id"
              class="chunk-item"
            >
              <div class="chunk-header">
                <div class="chunk-badge">{{ index + 1 }}</div>
                <el-input
                  v-model="chunk.name"
                  class="chunk-name-input"
                  placeholder="输入块名称"
                  @blur="saveChunkName(chunk)"
                />
                <span class="chunk-meta">{{ chunk.word_count || 0 }} 字</span>
              </div>
              <el-input
                v-model="chunk.content"
                type="textarea"
                :rows="4"
                class="chunk-content-input"
                @blur="saveChunkContent(chunk)"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { fileApi, chunkApi } from '@/api'

const route = useRoute()
const router = useRouter()
const projectId = computed(() => route.params.id)

const loading = ref(false)
const loadingChunks = ref(false)
const splitting = ref(false)
const files = ref([])
const selectedFile = ref(null)
const chunks = ref([])
const fileChunks = ref({})

const splitConfig = reactive({
  method: 'recursive',
  chunk_size: 500,
  overlap: 50,
  separator: '\n\n'
})

const completedFiles = computed(() => {
  return Object.keys(fileChunks.value).length
})

const processingCount = computed(() => {
  return files.value.filter(f => f.status === 'processing').length
})

const totalChunks = computed(() => {
  return Object.values(fileChunks.value).reduce((sum, count) => sum + count, 0)
})

const hasProcessedFiles = computed(() => {
  return Object.keys(fileChunks.value).length > 0
})

const totalWords = computed(() => {
  return chunks.value.reduce((sum, c) => sum + (c.word_count || 0), 0)
})

const fetchFiles = async () => {
  loading.value = true
  try {
    const res = await fileApi.list(projectId.value)
    files.value = res.data || []
    // 获取每个文件的 chunk 数量
    await fetchChunksCount()
  } catch (error) {
    console.error(error)
  } finally {
    loading.value = false
  }
}

const fetchChunksCount = async () => {
  const counts = {}
  for (const file of files.value) {
    try {
      const res = await chunkApi.list(projectId.value, { file_id: file.id })
      const chunks = res.data?.chunks || []
      if (chunks.length > 0) {
        counts[file.id] = chunks.length
      }
    } catch (e) {
      console.error(e)
    }
  }
  fileChunks.value = counts
}

const fetchChunks = async () => {
  if (!selectedFile.value) return
  loadingChunks.value = true
  try {
    const res = await chunkApi.list(projectId.value, { file_id: selectedFile.value.id })
    chunks.value = res.data?.chunks || []
  } catch (error) {
    ElMessage.error('获取分割结果失败')
  } finally {
    loadingChunks.value = false
  }
}

const handleFileClick = (file) => {
  selectedFile.value = file
  fetchChunks()
}

const handleSplit = async () => {
  if (!selectedFile.value) {
    ElMessage.warning('请先选择文件')
    return
  }
  splitting.value = true
  try {
    await chunkApi.split(projectId.value, { file_id: selectedFile.value.id, ...splitConfig })
    ElMessage.success('分割任务已启动')
    // 等待一下再获取结果
    setTimeout(() => {
      fetchChunks()
      fetchFiles()
    }, 2000)
  } catch (error) {
    ElMessage.error('分割失败')
  } finally {
    splitting.value = false
  }
}

const saveChunkName = async (chunk) => {
  try {
    await chunkApi.update(projectId.value, chunk.id, { name: chunk.name })
  } catch (error) {
    console.error(error)
  }
}

const saveChunkContent = async (chunk) => {
  try {
    await chunkApi.update(projectId.value, chunk.id, { content: chunk.content })
  } catch (error) {
    console.error(error)
  }
}

const handleBatchGenerateQA = () => {
  if (!hasProcessedFiles.value) {
    ElMessage.warning('请先分割文件')
    return
  }
  ElMessage.info('跳转到问答生成页面')
  router.push(`/project/${projectId.value}/questions`)
}

const refreshFiles = () => {
  fetchFiles()
}

const formatSize = (bytes) => {
  if (!bytes) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB']
  let i = 0
  while (bytes >= 1024 && i < units.length - 1) {
    bytes /= 1024
    i++
  }
  return `${bytes.toFixed(1)} ${units[i]}`
}

const getFileBg = (type) => {
  const colors = {
    pdf: '#ef4444',
    docx: '#3b82f6',
    xlsx: '#22c55e',
    csv: '#f59e0b',
    md: '#8b5cf6',
    txt: '#6b7280',
    epub: '#ec4899'
  }
  return colors[type] || '#6b7280'
}

const getFileIcon = (type) => {
  const icons = {
    pdf: 'Document',
    docx: 'Document',
    xlsx: 'Grid',
    csv: 'Grid',
    md: 'Document',
    txt: 'Document',
    epub: 'Book'
  }
  return icons[type] || 'Document'
}

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

<style scoped>
.text-split {
  --accent-cyan: #00d4ff;
  --accent-cyan-dim: rgba(0, 212, 255, 0.15);
  --accent-cyan-glow: rgba(0, 212, 255, 0.4);
  --bg-elevated: #0f1117;
  --bg-card: #161920;
  --bg-hover: #1c2029;
  --border-subtle: rgba(255, 255, 255, 0.08);
  --border-active: rgba(0, 212, 255, 0.3);
  --text-secondary: #9ca3af;
  --text-muted: #6b7280;
  --success: #22c55e;
  --warning: #f59e0b;
  --danger: #ef4444;
  --radius-lg: 12px;
  --radius-md: 8px;
  --radius-sm: 6px;
  padding: 28px 32px;
}

/* Header */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 28px;
}

.header-left {
  position: relative;
}

.page-title {
  font-size: 28px;
  font-weight: 700;
  margin: 0;
  background: linear-gradient(135deg, #ffffff 0%, var(--accent-cyan) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.page-subtitle {
  font-size: 14px;
  color: var(--text-muted);
  margin: 6px 0 0;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.refresh-btn {
  background: var(--bg-card) !important;
  border: 1px solid var(--border-subtle) !important;
  color: var(--text-secondary) !important;
  font-weight: 500;
  padding: 10px 18px;
  border-radius: var(--radius-md);
}

.refresh-btn:hover {
  background: var(--bg-hover) !important;
  border-color: var(--accent-cyan) !important;
}

.generate-btn {
  background: var(--accent-cyan) !important;
  border: none !important;
  color: #030407 !important;
  font-weight: 600;
  padding: 10px 22px;
  border-radius: var(--radius-md);
  box-shadow: 0 0 20px var(--accent-cyan-dim);
}

.generate-btn:hover:not(:disabled) {
  box-shadow: 0 0 35px var(--accent-cyan-glow);
  transform: translateY(-1px);
}

.generate-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Stats Grid */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.stat-card {
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  position: relative;
  overflow: hidden;
  transition: all 0.2s ease;
}

.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
}

.stat-card.total::before { background: linear-gradient(90deg, #8b5cf6, #a78bfa); }
.stat-card.success::before { background: linear-gradient(90deg, #22c55e, #4ade80); }
.stat-card.processing::before { background: linear-gradient(90deg, #f59e0b, #fbbf24); }

.stat-card:hover {
  border-color: var(--border-active);
  transform: translateY(-2px);
}

.stat-icon {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  font-size: 22px;
}

.stat-icon.total { background: rgba(139, 92, 246, 0.15); color: #a78bfa; }
.stat-icon.success { background: rgba(34, 197, 94, 0.15); color: #4ade80; }
.stat-icon.processing { background: rgba(245, 158, 11, 0.15); color: #fbbf24; }
.stat-icon.chunks { background: var(--accent-cyan-dim); color: var(--accent-cyan); }

.stat-content {
  display: flex;
  flex-direction: column;
}

.stat-value {
  font-size: 26px;
  font-weight: 700;
  font-family: 'SF Mono', Monaco, monospace;
  color: #fff;
}

.stat-label {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 2px;
}

/* Content Area */
.content-area {
  min-height: 400px;
}

/* Empty State */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  background: var(--bg-card);
  border: 2px dashed var(--border-subtle);
  border-radius: var(--radius-lg);
}

.empty-icon {
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-hover);
  border-radius: 50%;
  margin-bottom: 24px;
  border: 1px solid var(--border-subtle);
}

.empty-icon .el-icon {
  color: var(--text-muted);
}

.empty-title {
  font-size: 22px;
  font-weight: 600;
  color: #ffffff;
  margin: 0 0 8px;
}

.empty-desc {
  font-size: 14px;
  color: var(--text-muted);
  margin: 0;
}

/* Files Table */
.files-table-wrapper {
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.table-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-subtle);
}

.table-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-secondary);
}

.files-list {
  max-height: 500px;
  overflow-y: auto;
}

.file-row {
  display: grid;
  grid-template-columns: 50px 1fr 80px 100px 40px;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border-subtle);
  cursor: pointer;
  transition: all 0.2s ease;
  animation: slideIn 0.3s ease backwards;
  animation-delay: var(--delay);
}

.file-row:last-child {
  border-bottom: none;
}

.file-row:hover {
  background: var(--bg-hover);
}

.file-row.processing {
  opacity: 0.7;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateX(-10px);
  }
}

.col-icon {
  display: flex;
  justify-content: center;
}

.file-type-icon {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
}

.col-name {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.file-name {
  font-weight: 500;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 2px;
}

.col-chunks {
  text-align: center;
}

.chunk-count {
  font-size: 14px;
  color: var(--text-secondary);
}

.chunk-count.empty {
  color: var(--text-muted);
}

.col-status {
  display: flex;
  justify-content: center;
}

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
}

.status-badge.processing {
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
}

.status-badge.success {
  background: rgba(34, 197, 94, 0.15);
  color: #4ade80;
}

.status-badge.pending {
  background: rgba(107, 114, 128, 0.15);
  color: var(--text-muted);
}

.col-action {
  color: var(--text-muted);
  display: flex;
  justify-content: center;
}

.file-row:hover .col-action {
  color: var(--accent-cyan);
}

.spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Split Detail */
.split-detail {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.detail-header {
  display: flex;
  align-items: center;
  gap: 16px;
}

.back-btn {
  color: var(--text-secondary) !important;
  font-weight: 500;
}

.back-btn:hover {
  color: var(--accent-cyan) !important;
}

.file-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.file-type-icon.small {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
}

.file-info .file-name {
  font-weight: 600;
}

/* Config Card */
.config-card {
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: 24px;
}

.config-title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 20px;
  color: var(--text-secondary);
}

.config-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.form-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-item label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
}

.config-actions {
  display: flex;
  justify-content: flex-end;
  padding-top: 16px;
  border-top: 1px solid var(--border-subtle);
}

.split-btn {
  background: var(--accent-cyan) !important;
  border: none !important;
  color: #030407 !important;
  font-weight: 600;
  padding: 12px 28px;
  border-radius: var(--radius-md);
}

/* Chunks Card */
.chunks-card {
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.chunks-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-subtle);
}

.chunks-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

.chunks-list {
  max-height: 500px;
  overflow-y: auto;
}

.chunk-item {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-subtle);
}

.chunk-item:last-child {
  border-bottom: none;
}

.chunk-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.chunk-badge {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--accent-cyan), #06b6d4);
  color: white;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 600;
  flex-shrink: 0;
}

.chunk-name-input {
  flex: 1;
  max-width: 300px;
}

.chunk-name-input :deep(.el-input__wrapper) {
  background: var(--bg-hover);
  border: 1px solid var(--border-subtle);
  box-shadow: none;
}

.chunk-name-input :deep(.el-input__inner) {
  color: #fff;
  font-weight: 500;
}

.chunk-meta {
  font-size: 12px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.chunk-content-input :deep(.el-textarea__inner) {
  background: var(--bg-hover);
  border: 1px solid var(--border-subtle);
  box-shadow: none;
  color: var(--text-secondary);
  font-size: 13px;
  line-height: 1.7;
}

.chunk-content-input :deep(.el-textarea__inner:focus) {
  border-color: var(--accent-cyan);
}

/* Responsive */
@media (max-width: 768px) {
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .file-row {
    grid-template-columns: 40px 1fr 60px;
  }

  .col-chunks,
  .col-status,
  .col-action {
    display: none;
  }
}
</style>
