<template>
  <div class="favorite-page">
    <Breadcrumb :items="['知识管理', '我的收藏']" />
    <a-card class="general-card" :bordered="false">
      <template #title>我的收藏</template>
      <template #extra><a-button :loading="loading" :disabled="actionBusy" @click="loadFavorites">刷新</a-button></template>

      <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 value="document">文档</a-option>
            <a-option value="faq">FAQ</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="favorites"
        :columns="columns"
        :loading="loading"
        :pagination="pagination"
        @page-change="changePage"
        @page-size-change="changePageSize"
      >
        <template #resource_type="{ record }">
          <a-space>
            <a-tag :color="record.resource_type === 'document' ? 'blue' : 'green'">
              {{ record.resource_type === 'document' ? '文档' : 'FAQ' }}
            </a-tag>
            <a-tag v-if="record.is_deleted" color="red">已删除</a-tag>
          </a-space>
        </template>
        <template #created_at="{ record }">{{ formatTime(record.created_at) }}</template>
        <template #actions="{ record }">
          <a-space>
            <a-button type="text" size="small" :disabled="record.is_deleted || actionBusy" @click="openDetail(record)">查看</a-button>
            <a-button
              type="text"
              size="small"
              status="danger"
              :loading="actionBusy && actionID === record.id"
              :disabled="actionBusy"
              @click="confirmUncollect(record)"
            >
              取消收藏
            </a-button>
          </a-space>
        </template>
        <template #empty><a-empty description="暂无收藏" /></template>
      </a-table>
    </a-card>

    <a-drawer v-model:visible="detailVisible" :title="detailType === 'document' ? '文档详情' : 'FAQ 详情'" :width="720" :footer="false">
      <a-spin :loading="detailLoading" class="detail-spin">
        <a-descriptions v-if="detailType === 'document' && detailDocument" :column="2" bordered>
          <a-descriptions-item label="标题" :span="2">{{ detailDocument.title }}</a-descriptions-item>
          <a-descriptions-item label="作者">{{ detailDocument.author_name || `用户 ${detailDocument.author_id}` }}</a-descriptions-item>
          <a-descriptions-item label="状态">{{ statusText(detailDocument.status) }}</a-descriptions-item>
          <a-descriptions-item label="描述" :span="2">{{ detailDocument.description || '-' }}</a-descriptions-item>
          <a-descriptions-item label="正文" :span="2">
            <pre class="content-preview">{{ detailDocument.content }}</pre>
          </a-descriptions-item>
        </a-descriptions>
        <a-descriptions v-else-if="detailType === 'faq' && detailFaq" :column="2" bordered>
          <a-descriptions-item label="问题" :span="2">{{ detailFaq.question }}</a-descriptions-item>
          <a-descriptions-item label="作者">{{ detailFaq.author_name || `用户 ${detailFaq.author_id}` }}</a-descriptions-item>
          <a-descriptions-item label="状态">{{ statusText(detailFaq.status) }}</a-descriptions-item>
          <a-descriptions-item label="答案" :span="2">
            <pre class="content-preview">{{ detailFaq.answer }}</pre>
          </a-descriptions-item>
          <a-descriptions-item label="解决方案" :span="2">
            <pre class="content-preview">{{ detailFaq.solution || '-' }}</pre>
          </a-descriptions-item>
          <a-descriptions-item label="处理步骤" :span="2">
            <pre class="content-preview">{{ detailFaq.process_steps || '-' }}</pre>
          </a-descriptions-item>
          <a-descriptions-item label="适用范围" :span="2">{{ detailFaq.applicable_scope || '-' }}</a-descriptions-item>
        </a-descriptions>
      </a-spin>
    </a-drawer>
  </div>
</template>

<script lang="ts" setup>
import { 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 { fetchFavoriteList, uncollectResource, type Favorite, type ResourceType } from '@/api/kb/favorite'
import { fetchDocumentDetail, type Document, type DocumentStatus } from '@/api/kb/document'
import { fetchFaqDetail, type Faq } from '@/api/kb/faq'

const columns: TableColumnData[] = [
  { title: '资源名称', dataIndex: 'resource_name', ellipsis: true, tooltip: true },
  { title: '资源类型', dataIndex: 'resource_type', slotName: 'resource_type', width: 170, align: 'center' },
  { title: '收藏备注', dataIndex: 'remarks', ellipsis: true, tooltip: true },
  { title: '收藏时间', dataIndex: 'created_at', slotName: 'created_at', width: 180, align: 'center' },
  { title: '操作', slotName: 'actions', width: 180, fixed: 'right', align: 'center' },
]

const filters = reactive<{ resource_type?: ResourceType }>({ resource_type: undefined })
const favorites = ref<Favorite[]>([])
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 detailLoading = ref(false)
const detailType = ref<ResourceType>('document')
const detailDocument = ref<Document | null>(null)
const detailFaq = ref<Faq | null>(null)
let detailSequence = 0

/** 加载当前用户收藏，忽略过期请求。 */
async function loadFavorites() {
  const sequence = ++listSequence
  loading.value = true
  try {
    const reply = await fetchFavoriteList({
      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 || '获取收藏列表失败')
    favorites.value = reply.details?.data || []
    pagination.total = reply.details?.total || 0
  } catch (error) {
    if (sequence === listSequence) {
      favorites.value = []
      pagination.total = 0
      showRequestError(error, '获取收藏列表失败')
    }
  } finally {
    if (sequence === listSequence) loading.value = false
  }
}

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

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

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

async function openDetail(record: Favorite) {
  if (record.is_deleted) {
    Message.warning('资源已删除，无法查看详情')
    return
  }
  const sequence = ++detailSequence
  detailType.value = record.resource_type
  detailDocument.value = null
  detailFaq.value = null
  detailVisible.value = true
  detailLoading.value = true
  try {
    if (record.resource_type === 'document') {
      const cached = asDocument(record)
      if (cached) detailDocument.value = cached
      else {
        const reply = await fetchDocumentDetail(record.resource_id)
        if (sequence !== detailSequence) return
        if (reply.code !== 0) throw new Error(reply.message || '获取文档详情失败')
        detailDocument.value = reply.details
      }
    } else {
      const cached = asFaq(record)
      if (cached) detailFaq.value = cached
      else {
        const reply = await fetchFaqDetail(record.resource_id)
        if (sequence !== detailSequence) return
        if (reply.code !== 0) throw new Error(reply.message || '获取 FAQ 详情失败')
        detailFaq.value = reply.details
      }
    }
  } catch (error) {
    if (sequence === detailSequence) showRequestError(error, '获取收藏详情失败')
  } finally {
    if (sequence === detailSequence) detailLoading.value = false
  }
}

function asDocument(record: Favorite): Document | null {
  if (record.resource_type !== 'document' || !record.resource_data) return null
  return record.resource_data as Document
}

function asFaq(record: Favorite): Faq | null {
  if (record.resource_type !== 'faq' || !record.resource_data) return null
  return record.resource_data as Faq
}

function confirmUncollect(record: Favorite) {
  if (actionBusy.value) return
  actionBusy.value = true
  actionID.value = record.id
  Modal.confirm({
    title: '确认取消收藏',
    content: `确认取消收藏「${record.resource_name}」吗？`,
    onOk: async () => {
      try {
        const reply = await uncollectResource({ resource_type: record.resource_type, resource_id: record.resource_id })
        if (reply.code !== 0) throw new Error(reply.message || '取消收藏失败')
        Message.success('已取消收藏')
        await loadFavorites()
      } catch (error) {
        showRequestError(error, '取消收藏失败')
      } finally {
        finishAction()
      }
    },
    onCancel: 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 statusText(status: DocumentStatus) {
  return { draft: '草稿', published: '待审核', reviewed: '已审核', rejected: '已拒绝' }[status]
}

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

onMounted(loadFavorites)
</script>

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