<template>
  <div class="container">
    <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="handleRefresh"
    >
      <template #source_kind="{ record }">
        <a-tag>{{ sourceKindLabel(record.source_kind) }}</a-tag>
      </template>
      <template #raw_payload="{ record }">
        <span class="ellipsis-cell" :title="record.raw_payload">{{ truncate(record.raw_payload, 80) }}</span>
      </template>
      <template #alert_sent="{ record }">
        <a-tag :color="record.alert_sent ? 'green' : 'gray'">
          {{ record.alert_sent ? '已转发' : '否' }}
        </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="640px"
      :title="detailRow ? `日志详情 #${detailRow.id}` : '日志详情'"
      :footer="false"
      unmount-on-close
    >
      <template v-if="detailRow">
        <a-descriptions :column="1" bordered size="large">
          <a-descriptions-item label="来源类型">
            {{ sourceKindLabel(detailRow.source_kind) }}
          </a-descriptions-item>
          <a-descriptions-item label="采集时间">{{ detailRow.created_at }}</a-descriptions-item>
          <a-descriptions-item label="来源地址">{{ detailRow.remote_addr || '-' }}</a-descriptions-item>
          <a-descriptions-item label="设备名">{{ detailRow.device_name || '-' }}</a-descriptions-item>
          <a-descriptions-item label="严重级别">{{ detailRow.severity_code || '-' }}</a-descriptions-item>
          <a-descriptions-item label="Trap OID">{{ detailRow.trap_oid || '-' }}</a-descriptions-item>
          <a-descriptions-item label="已转发告警">
            {{ detailRow.alert_sent ? '是' : '否' }}
          </a-descriptions-item>
          <a-descriptions-item label="摘要">{{ detailRow.normalized_summary || '-' }}</a-descriptions-item>
          <a-descriptions-item label="详情">
            <pre class="pre-block">{{ detailRow.normalized_detail || '-' }}</pre>
          </a-descriptions-item>
          <a-descriptions-item label="原始报文">
            <pre class="pre-block">{{ detailRow.raw_payload || '-' }}</pre>
          </a-descriptions-item>
        </a-descriptions>
      </template>
    </a-drawer>
  </div>
</template>

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

const loading = ref(false)
const tableData = ref<LogEvent[]>([])
const formModel = ref({
  source_kind: '' as string,
})
const detailVisible = ref(false)
const detailRow = ref<LogEvent | null>(null)

const pagination = reactive({
  current: 1,
  pageSize: 50,
  total: 0,
})

const formItems = computed<FormItem[]>(() => [
  {
    field: 'source_kind',
    label: '来源类型',
    type: 'select',
    placeholder: '全部',
    span: 6,
    options: [
      { label: '全部', value: '' },
      { label: 'Syslog', value: 'syslog' },
      { label: 'SNMP Trap', value: 'snmp_trap' },
    ],
  },
])

const columns = computed<TableColumnData[]>(() => [
  { title: 'ID', dataIndex: 'id', width: 80 },
  {
    title: '来源',
    dataIndex: 'source_kind',
    slotName: 'source_kind',
    width: 110,
  },
  { title: '时间', dataIndex: 'created_at', width: 180, ellipsis: true, tooltip: true },
  { title: '来源地址', dataIndex: 'remote_addr', width: 130, ellipsis: true, tooltip: true },
  { title: '设备', dataIndex: 'device_name', width: 120, ellipsis: true, tooltip: true },
  { title: '级别', dataIndex: 'severity_code', width: 90 },
  { title: 'OID', dataIndex: 'trap_oid', width: 140, ellipsis: true, tooltip: true },
  {
    title: '原始报文',
    dataIndex: 'raw_payload',
    slotName: 'raw_payload',
    ellipsis: true,
    tooltip: true,
  },
  {
    title: '已告警',
    dataIndex: 'alert_sent',
    slotName: 'alert_sent',
    width: 90,
  },
  {
    title: '操作',
    dataIndex: 'operations',
    slotName: 'operations',
    width: 88,
    fixed: 'right',
  },
])

function sourceKindLabel(k: string) {
  if (k === 'syslog') return 'Syslog'
  if (k === 'snmp_trap') return 'SNMP Trap'
  return k || '-'
}

function truncate(s: string, n: number) {
  if (!s) return '-'
  return s.length <= n ? s : `${s.slice(0, n)}…`
}

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

async function fetchList() {
  loading.value = true
  try {
    const res: any = await fetchLogEntries({
      page: pagination.current,
      page_size: pagination.pageSize,
      source_kind: formModel.value.source_kind || undefined,
    })
    const payload = unwrapLogsPayload(res) ?? {}
    tableData.value = payload.items ?? []
    pagination.total = payload.total ?? 0
    if (typeof res.code === 'number' && res.code !== 0) {
      Message.error(res.message || res.msg || '加载失败')
    }
  } catch (e: any) {
    console.error(e)
    Message.error(e?.message || '加载失败')
    tableData.value = []
    pagination.total = 0
  } finally {
    loading.value = false
  }
}

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

function handleReset() {
  formModel.value = { source_kind: '' }
  pagination.current = 1
  fetchList()
}

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

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

function handleRefresh() {
  fetchList()
}

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

fetchList()
</script>

<script lang="ts">
export default { name: 'LogMgmtEntries' }
</script>

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

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

.ellipsis-cell {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
