<template>
  <div class="panel">
    <search-table
      :form-model="formModel"
      :form-items="formItems"
      :data="tableData"
      :columns="columns"
      :loading="loading"
      :pagination="pagination"
      title="审计日志"
      search-button-text="查询"
      reset-button-text="重置"
      :show-download="false"
      @update:form-model="handleFormModelUpdate"
      @search="handleSearch"
      @reset="handleReset"
      @page-change="handlePageChange"
      @page-size-change="handlePageSizeChange"
      @refresh="fetchList"
    >
      <template #operation_risk="{ record }">
        <a-tag :color="record.operation_risk === 'dangerous' ? 'red' : 'green'">
          {{ record.operation_risk === 'dangerous' ? '危险' : '普通' }}
        </a-tag>
      </template>
      <template #result="{ record }">
        <a-tag :color="record.result === 'failed' ? 'red' : 'green'">
          {{ record.result === 'failed' ? '失败' : '成功' }}
        </a-tag>
      </template>
      <template #operations="{ record }">
        <a-button type="text" size="small" @click="openDetail(record)">详情</a-button>
      </template>
    </search-table>

    <a-drawer
      v-model:visible="detailVisible"
      width="720px"
      :title="detailRow ? `审计详情 #${detailRow.id}` : '审计详情'"
      :footer="false"
      unmount-on-close
    >
      <a-descriptions v-if="detailRow" :column="1" bordered>
        <a-descriptions-item label="Trace ID">{{ detailRow.trace_id || '-' }}</a-descriptions-item>
        <a-descriptions-item label="服务">{{ detailRow.source_service || '-' }}</a-descriptions-item>
        <a-descriptions-item label="操作人">{{ detailRow.actor_name || detailRow.actor_id || '-' }}</a-descriptions-item>
        <a-descriptions-item label="动作">{{ detailRow.action || '-' }}</a-descriptions-item>
        <a-descriptions-item label="对象">{{ detailRow.object_type }} / {{ detailRow.object_id }}</a-descriptions-item>
        <a-descriptions-item label="审批单">{{ detailRow.approval_id || '-' }}</a-descriptions-item>
        <a-descriptions-item label="请求">{{ detailRow.request_method }} {{ detailRow.request_path }}</a-descriptions-item>
        <a-descriptions-item label="客户端">{{ detailRow.client_ip || '-' }}</a-descriptions-item>
        <a-descriptions-item label="变更前"><pre class="pre-block">{{ detailRow.before_json || '-' }}</pre></a-descriptions-item>
        <a-descriptions-item label="变更后"><pre class="pre-block">{{ detailRow.after_json || '-' }}</pre></a-descriptions-item>
        <a-descriptions-item label="错误">{{ detailRow.error_message || '-' }}</a-descriptions-item>
      </a-descriptions>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
import type { FormItem } from '@/components/search-form/types'
import SearchTable from '@/components/search-table/index.vue'
import { fetchAuditLogs, unwrapLogsPayload, type AuditLog } from '@/api/ops/logs'
import { Message } from '@arco-design/web-vue'

const loading = ref(false)
const tableData = ref<AuditLog[]>([])
const detailVisible = ref(false)
const detailRow = ref<AuditLog | null>(null)
const formModel = ref({
  source_service: '',
  actor_id: '',
  object_type: '',
  operation_risk: '',
  result: '',
})
const pagination = reactive({ current: 1, pageSize: 50, total: 0 })

const formItems = computed<FormItem[]>(() => [
  { field: 'source_service', label: '服务', type: 'input', placeholder: 'alert / feedback', span: 5 },
  { field: 'actor_id', label: '操作人ID', type: 'input', placeholder: '输入操作人', span: 5 },
  { field: 'object_type', label: '对象类型', type: 'input', placeholder: '输入对象类型', span: 5 },
  {
    field: 'operation_risk',
    label: '风险',
    type: 'select',
    placeholder: '全部',
    span: 4,
    options: [
      { label: '全部', value: '' },
      { label: '普通', value: 'normal' },
      { label: '危险', value: 'dangerous' },
    ],
  },
  {
    field: 'result',
    label: '结果',
    type: 'select',
    placeholder: '全部',
    span: 4,
    options: [
      { label: '全部', value: '' },
      { label: '成功', value: 'success' },
      { label: '失败', value: 'failed' },
    ],
  },
])

const columns = computed<TableColumnData[]>(() => [
  { title: 'ID', dataIndex: 'id', width: 80 },
  { title: '时间', dataIndex: 'created_at', width: 180, ellipsis: true, tooltip: true },
  { title: '服务', dataIndex: 'source_service', width: 120 },
  { title: '操作人', dataIndex: 'actor_name', width: 130, ellipsis: true, tooltip: true },
  { title: '动作', dataIndex: 'action', width: 180, ellipsis: true, tooltip: true },
  { title: '对象类型', dataIndex: 'object_type', width: 150, ellipsis: true, tooltip: true },
  { title: '对象ID', dataIndex: 'object_id', width: 150, ellipsis: true, tooltip: true },
  { title: '风险', dataIndex: 'operation_risk', slotName: 'operation_risk', width: 90 },
  { title: '结果', dataIndex: 'result', slotName: 'result', width: 90 },
  { title: 'Trace ID', dataIndex: 'trace_id', ellipsis: true, tooltip: true },
  { title: '操作', dataIndex: 'operations', slotName: 'operations', width: 90, fixed: 'right' },
])

function handleFormModelUpdate(v: Record<string, unknown>) {
  formModel.value = v as typeof formModel.value
}

async function fetchList() {
  loading.value = true
  try {
    const res: any = await fetchAuditLogs({
      page: pagination.current,
      page_size: pagination.pageSize,
      source_service: formModel.value.source_service || undefined,
      actor_id: formModel.value.actor_id || undefined,
      object_type: formModel.value.object_type || undefined,
      operation_risk: formModel.value.operation_risk || undefined,
      result: formModel.value.result || undefined,
    })
    const payload = unwrapLogsPayload(res) ?? {}
    tableData.value = payload.items ?? []
    pagination.total = payload.total ?? 0
  } catch (e: any) {
    Message.error(e?.message || '审计日志加载失败')
    tableData.value = []
    pagination.total = 0
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  pagination.current = 1
  fetchList()
}

function handleReset() {
  formModel.value = { source_service: '', actor_id: '', object_type: '', operation_risk: '', result: '' }
  pagination.current = 1
  fetchList()
}

function handlePageChange(page: number) {
  pagination.current = page
  fetchList()
}

function handlePageSizeChange(size: number) {
  pagination.pageSize = size
  pagination.current = 1
  fetchList()
}

function openDetail(row: AuditLog) {
  detailRow.value = row
  detailVisible.value = true
}

fetchList()
</script>

<style scoped lang="less">
.panel {
  padding: 16px;
}

.pre-block {
  margin: 0;
  max-height: 240px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 12px;
  line-height: 1.5;
}
</style>
