<template>
  <div class="review-page">
    <Breadcrumb :items="['知识管理', '内容审核']" />
    <a-card class="general-card" :bordered="false">
      <template #title>待审核内容</template>
      <template #extra>
        <a-button :loading="loading" :disabled="!canReview || reviewLocked" @click="loadReviews">刷新</a-button>
      </template>

      <a-alert v-if="!canReview" 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" 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="reviewLocked">查询</a-button>
          </a-form-item>
        </a-form>

        <a-table
          row-key="review_key"
          :data="tableData"
          :columns="columns"
          :loading="loading"
          :pagination="pagination"
          @page-change="changePage"
          @page-size-change="changePageSize"
        >
          <template #type="{ record }">
            <a-tag :color="getResourceTypeColor(record.type)">{{ getResourceTypeText(record.type) }}</a-tag>
          </template>
          <template #title="{ record }">{{ resourceTitle(record) }}</template>
          <template #author="{ record }">
            {{ record.resource.author_name || `用户 ${record.resource.author_id}` }}
            <a-tag v-if="isSelfReview(record)" color="orange" size="small">自审</a-tag>
          </template>
          <template #created_at="{ record }">{{ formatTime(record.resource.created_at) }}</template>
          <template #actions="{ record }">
            <a-space>
              <a-button type="text" size="small" :disabled="reviewLocked" @click="openDetail(record)">查看</a-button>
              <a-button
                type="text"
                size="small"
                status="success"
                :loading="isActionLoading(record)"
                :disabled="reviewLocked"
                @click="confirmApprove(record)"
              >
                通过
              </a-button>
              <a-button
                type="text"
                size="small"
                status="danger"
                :loading="isActionLoading(record)"
                :disabled="reviewLocked"
                @click="openReject(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-spin :loading="detailLoading" class="detail-spin">
        <a-descriptions v-if="detailRecord" :column="2" bordered>
          <a-descriptions-item label="资源类型">
            <a-tag :color="getResourceTypeColor(detailRecord.type)">{{ getResourceTypeText(detailRecord.type) }}</a-tag>
          </a-descriptions-item>
          <a-descriptions-item label="编号">{{ resourceNumber(detailRecord) }}</a-descriptions-item>
          <a-descriptions-item :label="detailRecord.type === 'faq' ? '问题' : '标题'" :span="2">
            {{ resourceTitle(detailRecord) }}
          </a-descriptions-item>
          <a-descriptions-item label="作者">
            {{ detailRecord.resource.author_name || `用户 ${detailRecord.resource.author_id}` }}
          </a-descriptions-item>
          <a-descriptions-item label="提交时间">{{ formatTime(detailRecord.resource.published_at) }}</a-descriptions-item>
          <a-descriptions-item v-if="detailRecord.type === 'document'" label="描述" :span="2">
            {{ documentOf(detailRecord)?.description || '-' }}
          </a-descriptions-item>
          <a-descriptions-item v-if="detailRecord.type === 'document'" label="正文" :span="2">
            <pre class="content-preview">{{ documentOf(detailRecord)?.content || '-' }}</pre>
          </a-descriptions-item>
          <a-descriptions-item v-if="detailRecord.type === 'faq'" label="答案" :span="2">
            <pre class="content-preview">{{ faqOf(detailRecord)?.answer || '-' }}</pre>
          </a-descriptions-item>
          <a-descriptions-item v-if="detailRecord.type === 'faq'" label="解决方案" :span="2">
            <pre class="content-preview">{{ faqOf(detailRecord)?.solution || '-' }}</pre>
          </a-descriptions-item>
          <a-descriptions-item label="关键词" :span="2">{{ detailRecord.resource.keywords || '-' }}</a-descriptions-item>
          <a-descriptions-item label="备注" :span="2">{{ detailRecord.resource.remarks || '-' }}</a-descriptions-item>
        </a-descriptions>
      </a-spin>
    </a-drawer>

    <a-modal
      :visible="rejectVisible"
      title="拒绝审核"
      :closable="!actionLoading"
      :mask-closable="!actionLoading"
      :esc-to-close="!actionLoading"
      :on-before-cancel="canCloseReject"
      @cancel="closeReject"
      @update:visible="handleRejectVisibleChange"
    >
      <a-alert v-if="rejectRecord && isSelfReview(rejectRecord)" type="warning" class="self-review-alert">
        这是你创建的内容。提交后还会再次确认，并记录自审日志。
      </a-alert>
      <a-form :model="rejectForm" layout="vertical">
        <a-form-item label="拒绝原因" required>
          <a-textarea
            v-model="rejectForm.reason"
            :max-length="500"
            :auto-size="{ minRows: 4, maxRows: 8 }"
            show-word-limit
            placeholder="请输入拒绝原因"
          />
        </a-form-item>
      </a-form>
      <template #footer>
        <a-space>
          <a-button :disabled="actionLoading" @click="closeReject">取消</a-button>
          <a-button
            type="primary"
            status="danger"
            :loading="actionLoading"
            :disabled="actionLoading || confirmationOpen"
            @click="confirmReject"
          >
            确认拒绝
          </a-button>
        </a-space>
      </template>
    </a-modal>
  </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 {
  approveReview,
  fetchReviewList,
  getResourceTypeColor,
  getResourceTypeText,
  rejectReview,
  resourceTypeOptions,
  type ReviewListItem,
  type ReviewResourceType,
} from '@/api/kb/review'
import { fetchDocumentDetail, type Document } from '@/api/kb/document'
import { fetchFaqDetail, type Faq } from '@/api/kb/faq'
import usePermissionCodes from '@/hooks/usePermissionCodes'
import { useUserStore } from '@/store'
import SafeStorage, { AppStorageKey } from '@/utils/safeStorage'

type ReviewRow = ReviewListItem & { review_key: string }

const columns: TableColumnData[] = [
  { title: '类型', dataIndex: 'type', slotName: 'type', width: 100, align: 'center' },
  { title: '标题 / 问题', slotName: 'title', ellipsis: true, tooltip: true },
  { title: '作者', slotName: 'author', width: 180 },
  { title: '提交时间', slotName: 'created_at', width: 180, align: 'center' },
  { title: '操作', slotName: 'actions', width: 230, fixed: 'right', align: 'center' },
]

const { hasPermission } = usePermissionCodes()
const canReview = computed(() => hasPermission('kb:content:review'))
const canSelfReview = computed(() => hasPermission('kb:content:self-review'))
const userStore = useUserStore()
const currentUserID = computed(() => {
  let source = userStore.$state.userInfo as Record<string, unknown> | null | undefined
  if (!source || typeof source !== 'object') source = SafeStorage.get<Record<string, unknown>>(AppStorageKey.USER_INFO)
  const value = Number(source?.user_id ?? source?.id)
  return Number.isFinite(value) ? value : 0
})

const filters = reactive<{ resource_type: ReviewResourceType }>({ resource_type: 'all' })
const tableData = ref<ReviewRow[]>([])
const loading = ref(false)
const pagination = reactive({ current: 1, pageSize: 10, total: 0, showTotal: true, showPageSize: true })
let listSequence = 0

const detailVisible = ref(false)
const detailLoading = ref(false)
const detailRecord = ref<ReviewListItem | null>(null)
let detailSequence = 0

const actionLoading = ref(false)
const actionKey = ref('')
const reviewLocked = ref(false)
const confirmationOpen = ref(false)
const rejectVisible = ref(false)
const rejectRecord = ref<ReviewListItem | null>(null)
const rejectForm = reactive({ reason: '' })

function rowKey(record: ReviewListItem) {
  return `${record.type}:${record.resource.id}`
}

function isSelfReview(record: ReviewListItem) {
  return currentUserID.value > 0 && record.resource.author_id === currentUserID.value
}

function canOperate(record: ReviewListItem) {
  return canReview.value && record.resource.status === 'published' && (!isSelfReview(record) || canSelfReview.value)
}

/** 加载审核列表，并在前端再次排除无自审权限的本人内容。 */
async function loadReviews() {
  if (!canReview.value) {
    tableData.value = []
    pagination.total = 0
    return
  }
  const sequence = ++listSequence
  loading.value = true
  try {
    const reply = await fetchReviewList({
      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 || '获取审核列表失败')
    const rows = (reply.details?.data || []).filter(canOperate)
    tableData.value = rows.map((item) => ({ ...item, review_key: rowKey(item) }))
    pagination.total = reply.details?.total || 0
  } catch (error) {
    if (sequence === listSequence) {
      tableData.value = []
      pagination.total = 0
      showRequestError(error, '获取审核列表失败')
    }
  } finally {
    if (sequence === listSequence) loading.value = false
  }
}

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

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

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

async function openDetail(record: ReviewListItem) {
  const sequence = ++detailSequence
  detailVisible.value = true
  detailLoading.value = true
  detailRecord.value = record
  try {
    if (record.type === 'document') {
      const reply = await fetchDocumentDetail(record.resource.id)
      if (sequence !== detailSequence) return
      if (reply.code !== 0) throw new Error(reply.message || '获取文档详情失败')
      detailRecord.value = { type: 'document', resource: reply.details }
    } else {
      const reply = await fetchFaqDetail(record.resource.id)
      if (sequence !== detailSequence) return
      if (reply.code !== 0) throw new Error(reply.message || '获取 FAQ 详情失败')
      detailRecord.value = { type: 'faq', resource: reply.details }
    }
  } catch (error) {
    if (sequence === detailSequence) showRequestError(error, '获取审核详情失败')
  } finally {
    if (sequence === detailSequence) detailLoading.value = false
  }
}

function confirmApprove(record: ReviewListItem) {
  if (reviewLocked.value) return
  if (!canOperate(record)) return Message.error('无操作权限')
  reviewLocked.value = true
  const openFinalConfirm = () =>
    Modal.confirm({
      title: '确认审核通过',
      content: `确认通过${getResourceTypeText(record.type)}「${resourceTitle(record)}」吗？`,
      okText: '确认通过',
      onOk: () => runApprove(record),
      onCancel: releaseReviewLock,
    })

  if (isSelfReview(record)) {
    Modal.confirm({
      title: '确认自审',
      content: '这是你创建的内容。继续操作将记录自审日志，是否进入最终确认？',
      okText: '继续',
      onOk: openFinalConfirm,
      onCancel: releaseReviewLock,
    })
    return
  }
  openFinalConfirm()
}

async function runApprove(record: ReviewListItem) {
  actionLoading.value = true
  actionKey.value = rowKey(record)
  try {
    const reply = await approveReview({ resource_type: record.type, id: record.resource.id })
    if (reply.code !== 0) throw new Error(reply.message || '审核失败')
    Message.success('审核已通过')
    await loadReviews()
  } catch (error) {
    showRequestError(error, '审核失败')
  } finally {
    actionLoading.value = false
    actionKey.value = ''
    releaseReviewLock()
  }
}

function openReject(record: ReviewListItem) {
  if (reviewLocked.value) return
  if (!canOperate(record)) return Message.error('无操作权限')
  reviewLocked.value = true
  rejectRecord.value = record
  rejectForm.reason = ''
  rejectVisible.value = true
}

function confirmReject() {
  if (!rejectRecord.value || actionLoading.value || confirmationOpen.value) return
  if (!rejectForm.reason.trim()) {
    Message.warning('请输入拒绝原因')
    return
  }
  const record = rejectRecord.value
  if (isSelfReview(record)) {
    confirmationOpen.value = true
    Modal.confirm({
      title: '再次确认自审拒绝',
      content: '确认拒绝自己创建的内容吗？本次操作将记录自审日志。',
      okText: '确认拒绝',
      onOk: () => {
        confirmationOpen.value = false
        return runReject(record, rejectForm.reason.trim())
      },
      onCancel: () => {
        confirmationOpen.value = false
      },
    })
    return
  }
  runReject(record, rejectForm.reason.trim())
}

async function runReject(record: ReviewListItem, reason: string) {
  let succeeded = false
  actionLoading.value = true
  actionKey.value = rowKey(record)
  try {
    const reply = await rejectReview({ resource_type: record.type, id: record.resource.id, reason })
    if (reply.code !== 0) throw new Error(reply.message || '拒绝审核失败')
    Message.success('审核已拒绝')
    rejectVisible.value = false
    rejectRecord.value = null
    rejectForm.reason = ''
    await loadReviews()
    succeeded = true
  } catch (error) {
    showRequestError(error, '拒绝审核失败')
  } finally {
    actionLoading.value = false
    actionKey.value = ''
    if (succeeded) releaseReviewLock()
  }
}

function closeReject() {
  if (actionLoading.value) return
  rejectVisible.value = false
  rejectRecord.value = null
  rejectForm.reason = ''
  confirmationOpen.value = false
  releaseReviewLock()
}

function canCloseReject() {
  return !actionLoading.value
}

function handleRejectVisibleChange(visible: boolean) {
  if (!visible) closeReject()
}

function releaseReviewLock() {
  reviewLocked.value = false
}

function isActionLoading(record: ReviewListItem) {
  return actionLoading.value && actionKey.value === rowKey(record)
}

function documentOf(record: ReviewListItem | null): Document | null {
  return record?.type === 'document' ? (record.resource as Document) : null
}

function faqOf(record: ReviewListItem | null): Faq | null {
  return record?.type === 'faq' ? (record.resource as Faq) : null
}

function resourceTitle(record: ReviewListItem | null) {
  return documentOf(record)?.title || faqOf(record)?.question || '-'
}

function resourceNumber(record: ReviewListItem | null) {
  return documentOf(record)?.doc_no || faqOf(record)?.faq_no || '-'
}

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 | undefined) {
  return value ? dayjs(value).format('YYYY-MM-DD HH:mm') : '-'
}

onMounted(loadReviews)
</script>

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