<template>
  <div class="admin-dashboard">
    <!-- Statistics Cards -->
    <a-row :gutter="16" class="stat-cards">
      <a-col :span="6">
        <a-card>
          <a-statistic title="文档总数" :value="stats.total_documents" :loading="loading">
            <template #prefix><FileTextOutlined /></template>
          </a-statistic>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card>
          <a-statistic title="Chunk 总数" :value="stats.total_chunks" :loading="loading">
            <template #prefix><DatabaseOutlined /></template>
          </a-statistic>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card>
          <a-statistic title="图谱节点数" :value="stats.graph_nodes" :loading="loading">
            <template #prefix><DeploymentUnitOutlined /></template>
          </a-statistic>
        </a-card>
      </a-col>
      <a-col :span="6">
        <a-card>
          <a-statistic title="今日入库" :value="stats.today_ingested" :loading="loading">
            <template #prefix><CloudUploadOutlined /></template>
          </a-statistic>
        </a-card>
      </a-col>
    </a-row>

    <!-- System Health -->
    <a-card title="服务健康状态" class="health-card" :loading="loading">
      <a-space size="large">
        <a-badge
          :status="statusBadge(stats.es_status)"
          :text="`OpenSearch: ${stats.es_status || '—'}`"
        />
        <a-badge
          :status="statusBadge(stats.neo4j_status)"
          :text="`Neo4j: ${stats.neo4j_status || '—'}`"
        />
        <a-badge
          :status="statusBadge(stats.redis_status)"
          :text="`Redis: ${stats.redis_status || '—'}`"
        />
        <a-badge
          :status="statusBadge(stats.celery_status)"
          :text="`Celery Worker: ${stats.celery_status || '—'}`"
        />
        <a-badge
          :status="statusBadge(stats.converter_status)"
          :text="`Doc Converter: ${stats.converter_status || '—'}`"
        />
      </a-space>
    </a-card>

    <!-- Recent Ingest Logs -->
    <a-card title="近期入库日志" class="log-card">
      <template #extra>
        <a-space>
          <a-button :loading="loading" @click="loadAll" size="small">
            <template #icon><ReloadOutlined /></template>
            刷新
          </a-button>
          <a-popconfirm
            title="确认删除选中的文档？"
            description="此操作将永久删除选中文档的全部索引数据和图谱节点，不可恢复。"
            ok-text="确认删除"
            cancel-text="取消"
            ok-type="danger"
            :disabled="selectedRowKeys.length === 0"
            @confirm="deleteSelected"
          >
            <a-button
              size="small"
              danger
              :disabled="selectedRowKeys.length === 0"
              :loading="deletingBatch"
            >
              <template #icon><DeleteOutlined /></template>
              删除选中 ({{ selectedRowKeys.length }})
            </a-button>
          </a-popconfirm>
          <a-popconfirm
            title="确认删除全部文档？"
            description="此操作将永久删除所有文档的索引数据、图谱节点，不可恢复！"
            ok-text="确认删除全部"
            cancel-text="取消"
            ok-type="danger"
            @confirm="deleteAll"
          >
            <a-button size="small" type="primary" danger :loading="deletingAll">
              <template #icon><DeleteOutlined /></template>
              删除全部
            </a-button>
          </a-popconfirm>
        </a-space>
      </template>
      <a-table
        :columns="columns"
        :data-source="logs"
        :loading="logsLoading"
        :pagination="pagination"
        :row-selection="{ selectedRowKeys, onChange: onSelectChange }"
        row-key="doc_id"
        size="small"
        @change="handleTableChange"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'title'">
            <a @click="$router.push(`/doc/${record.doc_id}`)">{{ record.title || '—' }}</a>
          </template>
          <template v-if="column.key === 'status'">
            <a-tooltip v-if="record.error" :title="record.error" placement="topLeft">
              <a-tag :color="statusColor(record.status)" style="cursor: help">
                {{ statusLabel(record.status) }}
              </a-tag>
            </a-tooltip>
            <a-tag v-else :color="statusColor(record.status)">
              {{ statusLabel(record.status) }}
            </a-tag>
          </template>
          <template v-if="column.key === 'chunk_count'">
            {{ record.chunk_count || 0 }}
          </template>
          <template v-if="column.key === 'acl'">
            <span v-if="record.acl_ids && record.acl_ids.length > 0">
              {{ countAclPrefix(record.acl_ids, 'D_') }}部门 / {{ countAclPrefix(record.acl_ids, 'U_') }}人员
            </span>
            <span v-else style="color: #999">—</span>
          </template>
          <template v-if="column.key === 'created_at'">
            {{ formatDate(record.created_at) }}
          </template>
        </template>
      </a-table>
    </a-card>

    <!-- Bulk Delete Result Modal -->
    <a-modal
      v-model:open="bulkDeleteResultVisible"
      title="删除完成"
      :footer="null"
      width="400px"
    >
      <a-descriptions :column="1" size="small" bordered>
        <a-descriptions-item v-if="bulkDeleteResult.requested != null" label="请求删除">{{ bulkDeleteResult.requested }} 条</a-descriptions-item>
        <a-descriptions-item label="删除文档">{{ bulkDeleteResult.deleted_meta }}</a-descriptions-item>
        <a-descriptions-item label="删除 Chunks">{{ bulkDeleteResult.deleted_chunks }}</a-descriptions-item>
        <a-descriptions-item label="删除办事指南">{{ bulkDeleteResult.deleted_guides }}</a-descriptions-item>
        <a-descriptions-item label="删除图谱节点">{{ bulkDeleteResult.deleted_graph_nodes }}</a-descriptions-item>
        <a-descriptions-item v-if="bulkDeleteResult.errors && bulkDeleteResult.errors.length > 0" label="失败">
          {{ bulkDeleteResult.errors.length }} 条
        </a-descriptions-item>
      </a-descriptions>
    </a-modal>
  </div>
</template>

/**
 * 管理后台仪表盘
 * 展示系统关键指标（文档/Chunk/图谱节点数量、今日入库），服务健康状态，
 * 以及近期入库日志表格（支持追踪跳转、失败重试、文档删除操作）。
 */
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import {
  FileTextOutlined, DatabaseOutlined,
  DeploymentUnitOutlined, CloudUploadOutlined, ReloadOutlined, DeleteOutlined,
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import request from '@/api/request'
import type { IngestLogRecord, BulkDeleteResult, TablePaginationParams } from '@/types/admin'
// 使用共享的格式化工具函数
// Use shared formatting utilities
import { statusColor, statusLabel, formatDate } from '@/utils/format'

const router = useRouter()

// ── State ──────────────────────────────────────────────────────────────────

const loading = ref(false)
const logsLoading = ref(false)
const retrying = ref<string | null>(null)
const deletingBatch = ref(false)
const deletingAll = ref(false)

const selectedRowKeys = ref<string[]>([])

const bulkDeleteResultVisible = ref(false)
const bulkDeleteResult = ref<BulkDeleteResult>({
  deleted_meta: 0,
  deleted_chunks: 0,
  deleted_guides: 0,
  deleted_graph_nodes: 0,
})

const stats = ref({
  total_documents: 0,
  total_chunks: 0,
  graph_nodes: 0,
  today_ingested: 0,
  es_status: '',
  neo4j_status: '',
  redis_status: '',
  celery_status: '',
  converter_status: '',
})

const logs = ref<IngestLogRecord[]>([])
const pagination = reactive({
  current: 1,
  pageSize: 20,
  total: 0,
  showSizeChanger: false,
})

// ── Table columns ──────────────────────────────────────────────────────────

const columns = [
  { title: '标题', dataIndex: 'title', key: 'title', ellipsis: true },
  { title: '状态', dataIndex: 'status', key: 'status', width: 90 },
  { title: 'Chunks', dataIndex: 'chunk_count', key: 'chunk_count', width: 80 },
  { title: '权限', key: 'acl', width: 140 },
  { title: '入库时间', dataIndex: 'created_at', key: 'created_at', width: 160 },
]

// ── Helpers ────────────────────────────────────────────────────────────────

/** 将服务健康状态映射为 Ant Design Badge 的展示状态 */
function statusBadge(status: string): 'success' | 'error' | 'processing' | 'default' {
  if (status === 'healthy') return 'success'
  if (status === 'error') return 'error'
  if (status === 'unknown' || !status) return 'default'
  return 'processing'
}

// ── Data loading ───────────────────────────────────────────────────────────

async function loadStats() {
  loading.value = true
  try {
    const res = await request.get('/api/ai/v1/admin/stats')
    stats.value = res.data
  } catch (err) {
    message.error('加载统计数据失败')
  } finally {
    loading.value = false
  }
}

async function loadLogs(page = 1, pageSize = 20) {
  logsLoading.value = true
  try {
    const res = await request.get('/api/ai/v1/admin/ingest-logs', {
      params: { page, page_size: pageSize },
    })
    const data = res.data
    logs.value = data.records || []
    pagination.total = data.total || 0
    pagination.current = page
  } catch (err) {
    message.error('加载入库日志失败')
    logs.value = []
  } finally {
    logsLoading.value = false
  }
}

async function loadAll() {
  await Promise.all([loadStats(), loadLogs(1, pagination.pageSize)])
}

function handleTableChange(pag: TablePaginationParams) {
  loadLogs(pag.current, pag.pageSize)
}

// ── Helpers ────────────────────────────────────────────────────────────────

/** 统计 acl_ids 中指定前缀的数量 */
function countAclPrefix(aclIds: string[], prefix: string): number {
  return aclIds.filter(id => id.startsWith(prefix)).length
}

function onSelectChange(keys: string[]) {
  selectedRowKeys.value = keys
}

// ── Actions ────────────────────────────────────────────────────────────────

/** 批量删除选中文档 */
async function deleteSelected() {
  if (selectedRowKeys.value.length === 0) return
  deletingBatch.value = true
  try {
    const res = await request.delete('/api/ai/v1/admin/documents/batch', {
      data: { doc_ids: selectedRowKeys.value },
    })
    bulkDeleteResult.value = res.data
    bulkDeleteResultVisible.value = true
    selectedRowKeys.value = []
    message.success(`已删除 ${res.data.deleted_meta} 条文档`)
    await loadAll()
  } catch (err: unknown) {
    const axiosErr = err as { response?: { data?: { detail?: string } } }
    message.error(axiosErr?.response?.data?.detail || '批量删除失败')
  } finally {
    deletingBatch.value = false
  }
}

/** 删除全部文档 */
async function deleteAll() {
  deletingAll.value = true
  try {
    const res = await request.delete('/api/ai/v1/admin/documents/all')
    bulkDeleteResult.value = res.data
    bulkDeleteResultVisible.value = true
    selectedRowKeys.value = []
    message.success('已删除全部文档')
    await loadAll()
  } catch (err: unknown) {
    const axiosErr = err as { response?: { data?: { detail?: string } } }
    message.error(axiosErr?.response?.data?.detail || '删除全部失败')
  } finally {
    deletingAll.value = false
  }
}

// ── Lifecycle ──────────────────────────────────────────────────────────────

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

<style scoped lang="less">
.admin-dashboard {
  padding: 24px;

  .stat-cards {
    margin-bottom: 16px;
  }

  .health-card {
    margin-bottom: 16px;
  }

  .log-card {
    margin-top: 0;
  }
}
</style>
