<template>
  <div class="trash-page">
    <Breadcrumb :items="['知识管理', '回收站']" />
    <a-card class="general-card" :bordered="false">
      <template #title>回收站</template>
      <template #extra>
        <a-button :loading="loading" :disabled="!canManage || actionBusy" @click="loadTrash">刷新</a-button>
      </template>

      <a-alert v-if="!canManage" type="warning">当前账号没有知识内容管理权限。</a-alert>
      <template v-else>
        <a-form :model="filters" layout="inline" class="filters" @submit-success="search">
          <a-form-item label="资源类型">
            <a-select v-model="filters.resource_type" placeholder="全部类型" allow-clear style="width: 160px">
              <a-option v-for="option in resourceTypeOptions" :key="option.value" :value="option.value">
                {{ option.label }}
              </a-option>
            </a-select>
          </a-form-item>
          <a-form-item><a-button type="primary" html-type="submit" :disabled="actionBusy">查询</a-button></a-form-item>
        </a-form>

        <a-table
          row-key="id"
          :data="records"
          :columns="columns"
          :loading="loading"
          :pagination="pagination"
          @page-change="changePage"
          @page-size-change="changePageSize"
        >
          <template #resource_type="{ record }">
            <a-tag :color="getResourceTypeColor(record.resource_type)">{{ getResourceTypeText(record.resource_type) }}</a-tag>
          </template>
          <template #deleted_name="{ record }">{{ record.deleted_name || `用户 ${record.deleted_by}` }}</template>
          <template #deleted_time="{ record }">{{ formatTime(record.deleted_time) }}</template>
          <template #actions="{ record }">
            <a-space>
              <a-button type="text" size="small" :disabled="actionBusy" @click="openDetail(record)">查看</a-button>
              <a-button
                type="text"
                size="small"
                :loading="actionBusy && actionID === record.id"
                :disabled="actionBusy"
                @click="confirmRestore(record)"
              >
                恢复
              </a-button>
              <a-button
                type="text"
                size="small"
                status="danger"
                :loading="actionBusy && actionID === record.id"
                :disabled="actionBusy"
                @click="confirmDelete(record)"
              >
                彻底删除
              </a-button>
            </a-space>
          </template>
          <template #empty><a-empty description="回收站为空" /></template>
        </a-table>
      </template>
    </a-card>

    <a-drawer v-model:visible="detailVisible" title="已删除内容" :width="720" :footer="false">
      <a-alert v-if="detailParseError" type="error" class="parse-alert">原始数据无法解析，恢复操作仍以服务端结果为准。</a-alert>
      <a-descriptions v-if="detailRecord" :column="2" bordered>
        <a-descriptions-item label="资源类型">
          <a-tag :color="getResourceTypeColor(detailRecord.resource_type)">{{ getResourceTypeText(detailRecord.resource_type) }}</a-tag>
        </a-descriptions-item>
        <a-descriptions-item label="资源 ID">{{ detailRecord.resource_id }}</a-descriptions-item>
        <a-descriptions-item :label="detailRecord.resource_type === 'document' ? '标题' : '问题'" :span="2">
          {{ originalTitle || detailRecord.resource_name }}
        </a-descriptions-item>
        <a-descriptions-item label="删除人">{{ detailRecord.deleted_name || `用户 ${detailRecord.deleted_by}` }}</a-descriptions-item>
        <a-descriptions-item label="删除时间">{{ formatTime(detailRecord.deleted_time) }}</a-descriptions-item>
        <a-descriptions-item label="删除原因" :span="2">{{ detailRecord.delete_reason || '-' }}</a-descriptions-item>
        <a-descriptions-item v-if="detailRecord.resource_type === 'document'" label="描述" :span="2">
          {{ originalDocument?.description || '-' }}
        </a-descriptions-item>
        <a-descriptions-item v-if="detailRecord.resource_type === 'document'" label="正文" :span="2">
          <pre class="content-preview">{{ originalDocument?.content || '-' }}</pre>
        </a-descriptions-item>
        <a-descriptions-item v-if="detailRecord.resource_type === 'faq'" label="答案" :span="2">
          <pre class="content-preview">{{ originalFaq?.answer || '-' }}</pre>
        </a-descriptions-item>
        <a-descriptions-item v-if="detailRecord.resource_type === 'faq'" label="解决方案" :span="2">
          <pre class="content-preview">{{ originalFaq?.solution || '-' }}</pre>
        </a-descriptions-item>
        <a-descriptions-item v-if="detailRecord.resource_type === 'faq'" label="处理步骤" :span="2">
          <pre class="content-preview">{{ originalFaq?.process_steps || '-' }}</pre>
        </a-descriptions-item>
      </a-descriptions>
    </a-drawer>
  </div>
</template>

<script lang="ts" setup>
import { computed, onMounted, reactive, ref } from 'vue'
import axios from 'axios'
import dayjs from 'dayjs'
import { Message, Modal } from '@arco-design/web-vue'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
import {
  deleteTrash,
  fetchTrashList,
  getResourceTypeColor,
  getResourceTypeText,
  resourceTypeOptions,
  restoreTrash,
  type TrashRecord,
  type TrashResourceType,
} from '@/api/kb/trash'
import type { Document } from '@/api/kb/document'
import type { Faq } from '@/api/kb/faq'
import usePermissionCodes from '@/hooks/usePermissionCodes'

const columns: TableColumnData[] = [
  { title: '资源名称', dataIndex: 'resource_name', ellipsis: true, tooltip: true },
  { title: '资源类型', dataIndex: 'resource_type', slotName: 'resource_type', width: 120, align: 'center' },
  { title: '删除人', dataIndex: 'deleted_name', slotName: 'deleted_name', width: 150 },
  { title: '删除时间', dataIndex: 'deleted_time', slotName: 'deleted_time', width: 180, align: 'center' },
  { title: '删除原因', dataIndex: 'delete_reason', ellipsis: true, tooltip: true },
  { title: '操作', slotName: 'actions', width: 250, fixed: 'right', align: 'center' },
]

const { hasPermission } = usePermissionCodes()
const canManage = computed(() => hasPermission('kb:content:manage'))
const filters = reactive<{ resource_type?: TrashResourceType }>({ resource_type: undefined })
const records = ref<TrashRecord[]>([])
const loading = ref(false)
const pagination = reactive({ current: 1, pageSize: 20, total: 0, showTotal: true, showPageSize: true })
let listSequence = 0
const actionID = ref(0)
const actionBusy = ref(false)

const detailVisible = ref(false)
const detailRecord = ref<TrashRecord | null>(null)
const originalDocument = ref<Document | null>(null)
const originalFaq = ref<Faq | null>(null)
const detailParseError = ref(false)
const originalTitle = computed(() => originalDocument.value?.title || originalFaq.value?.question || '')

/** 加载回收站列表。 */
async function loadTrash() {
  if (!canManage.value) {
    records.value = []
    pagination.total = 0
    return
  }
  const sequence = ++listSequence
  loading.value = true
  try {
    const reply = await fetchTrashList({
      page: pagination.current,
      page_size: pagination.pageSize,
      resource_type: filters.resource_type,
    })
    if (sequence !== listSequence) return
    if (reply.code !== 0) throw new Error(reply.message || '获取回收站失败')
    records.value = reply.details?.data || []
    pagination.total = reply.details?.total || 0
  } catch (error) {
    if (sequence === listSequence) {
      records.value = []
      pagination.total = 0
      showRequestError(error, '获取回收站失败')
    }
  } finally {
    if (sequence === listSequence) loading.value = false
  }
}

function search() {
  pagination.current = 1
  loadTrash()
}

function changePage(page: number) {
  pagination.current = page
  loadTrash()
}

function changePageSize(pageSize: number) {
  pagination.current = 1
  pagination.pageSize = pageSize
  loadTrash()
}

function openDetail(record: TrashRecord) {
  detailRecord.value = record
  originalDocument.value = null
  originalFaq.value = null
  detailParseError.value = false
  try {
    const parsed: unknown = JSON.parse(record.original_data)
    if (!parsed || typeof parsed !== 'object') throw new Error('invalid original_data')
    if (record.resource_type === 'document') originalDocument.value = parsed as Document
    else originalFaq.value = parsed as Faq
  } catch {
    detailParseError.value = true
  }
  detailVisible.value = true
}

function confirmRestore(record: TrashRecord) {
  if (!canManage.value) return Message.error('无操作权限')
  if (actionBusy.value) return
  actionBusy.value = true
  actionID.value = record.id
  Modal.confirm({
    title: '确认恢复',
    content: `确认恢复${getResourceTypeText(record.resource_type)}「${record.resource_name}」吗？`,
    onOk: () => runAction(record, 'restore'),
    onCancel: finishAction,
  })
}

function confirmDelete(record: TrashRecord) {
  if (!canManage.value) return Message.error('无操作权限')
  if (actionBusy.value) return
  actionBusy.value = true
  actionID.value = record.id
  Modal.confirm({
    title: '确认彻底删除',
    content: `彻底删除「${record.resource_name}」后不可恢复，是否继续？`,
    okText: '彻底删除',
    okButtonProps: { status: 'danger' },
    onOk: () => runAction(record, 'delete'),
    onCancel: finishAction,
  })
}

async function runAction(record: TrashRecord, action: 'restore' | 'delete') {
  try {
    const reply = action === 'restore' ? await restoreTrash(record.id) : await deleteTrash(record.id)
    if (reply.code !== 0) throw new Error(reply.message || (action === 'restore' ? '恢复失败' : '彻底删除失败'))
    Message.success(action === 'restore' ? '资源已恢复' : '资源已彻底删除')
    if (detailRecord.value?.id === record.id) detailVisible.value = false
    await loadTrash()
  } catch (error) {
    showRequestError(error, action === 'restore' ? '恢复失败' : '彻底删除失败')
  } finally {
    finishAction()
  }
}

function finishAction() {
  actionBusy.value = false
  actionID.value = 0
}

function showRequestError(error: unknown, fallback: string) {
  if (axios.isAxiosError(error)) {
    const status = error.response?.status
    const message = (error.response?.data as { message?: string } | undefined)?.message
    if (status === 403) return Message.error('无操作权限')
    if (status === 400 || status === 409) return Message.error(message || fallback)
  }
  Message.error(error instanceof Error && error.message ? error.message : fallback)
}

function formatTime(value: string | null) {
  return value ? dayjs(value).format('YYYY-MM-DD HH:mm') : '-'
}

onMounted(loadTrash)
</script>

<style scoped lang="less">
.trash-page {
  padding: 0 20px 20px;
}
.filters {
  margin-bottom: 16px;
}
.parse-alert {
  margin-bottom: 16px;
}
.content-preview {
  max-height: 300px;
  margin: 0;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: inherit;
}
</style>
