<template>
  <div class="raw-events-page">
    <a-card :bordered="false" title="原始事件池">
      <template #extra>
        <a-button type="primary" :loading="loading" :disabled="pageUnauthorized" @click="fetchData">
          <template #icon><icon-refresh /></template>
          刷新
        </a-button>
      </template>

      <a-form :model="filters" layout="inline" class="filter-form">
        <a-form-item field="keyword" label="关键字">
          <a-input v-model="filters.keyword" allow-clear placeholder="标题 / 消息 / 载荷" />
        </a-form-item>
        <a-form-item field="source_type" label="来源">
          <a-select v-model="filters.source_type" allow-clear placeholder="全部">
            <a-option value="metric_threshold">指标阈值</a-option>
            <a-option value="syslog">Syslog</a-option>
            <a-option value="trap">Trap</a-option>
            <a-option value="probe_failure">探测失败</a-option>
            <a-option value="collection_health">采集健康</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="parse_status" label="解析状态">
          <a-select v-model="filters.parse_status" allow-clear placeholder="全部">
            <a-option value="parsed">已解析</a-option>
            <a-option value="unparsed">未解析</a-option>
            <a-option value="replayed">已重放</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="severity" label="级别">
          <a-select v-model="filters.severity" allow-clear placeholder="全部">
            <a-option value="critical">紧急</a-option>
            <a-option value="major">严重</a-option>
            <a-option value="warning">警告</a-option>
            <a-option value="info">提示</a-option>
            <a-option value="minor">轻微</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="resource_uid" label="资源 UID">
          <a-input v-model="filters.resource_uid" allow-clear placeholder="category:identity" />
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button @click="resetFilters">重置</a-button>
            <a-button type="primary" @click="handleSearch">
              <template #icon><icon-search /></template>
              查询
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>

      <PageState :status="pageStatus" :error-text="errorMessage" @retry="fetchData">
      <a-table
        v-if="pageStatus !== 'empty' && pageStatus !== 'error' && pageStatus !== 'unauthorized'"
        row-key="id"
        :loading="loading"
        :data="rows"
        :columns="columns"
        :pagination="pagination"
        :scroll="{ x: 'max-content' }"
        @page-change="handlePageChange"
        @page-size-change="handlePageSizeChange"
      >
        <template #source_type="{ record }">
          <a-tag>{{ sourceText(record.source_type) }}</a-tag>
        </template>
        <template #parse_status="{ record }">
          <a-tag :color="parseStatusColor(record.parse_status)">{{ parseStatusText(record.parse_status) }}</a-tag>
        </template>
        <template #severity="{ record }">
          <a-tag :color="severityColor(record.severity)">{{ severityText(record.severity) }}</a-tag>
        </template>
        <template #resource_uid="{ record }">
          <a-typography-text v-if="record.resource_uid" copyable>{{ record.resource_uid }}</a-typography-text>
          <span v-else>-</span>
        </template>
        <template #event_time="{ record }">{{ formatTime(record.event_time) }}</template>
        <template #actions="{ record }">
          <a-space>
            <a-button type="text" size="small" :disabled="pageUnauthorized" @click="showDetail(record)">详情</a-button>
            <a-button type="text" size="small" :disabled="!canOperate" @click="handleReplay(record)">重放</a-button>
          </a-space>
        </template>
      </a-table>
      </PageState>
    </a-card>

    <a-drawer v-model:visible="detailVisible" width="720px" title="原始事件详情" unmount-on-close>
      <a-descriptions v-if="current" :column="1" bordered size="medium">
        <a-descriptions-item label="事件 ID">{{ current.id }}</a-descriptions-item>
        <a-descriptions-item label="来源">{{ sourceText(current.source_type) }}</a-descriptions-item>
        <a-descriptions-item label="资源 UID">{{ current.resource_uid || '-' }}</a-descriptions-item>
        <a-descriptions-item label="事件时间">{{ formatTime(current.event_time) }}</a-descriptions-item>
        <a-descriptions-item label="级别">{{ severityText(current.severity) }}</a-descriptions-item>
        <a-descriptions-item label="标题">{{ current.title }}</a-descriptions-item>
        <a-descriptions-item label="消息">{{ current.message || '-' }}</a-descriptions-item>
        <a-descriptions-item label="解析状态">{{ parseStatusText(current.parse_status) }}</a-descriptions-item>
        <a-descriptions-item label="Trace ID">{{ current.trace_id || '-' }}</a-descriptions-item>
        <a-descriptions-item label="关联告警">{{ current.alert_record_id || '-' }}</a-descriptions-item>
      </a-descriptions>

      <a-tabs class="detail-tabs" default-active-key="payload">
        <a-tab-pane key="payload" title="原始载荷">
          <pre class="json-block">{{ prettyText(current?.raw_payload) }}</pre>
        </a-tab-pane>
        <a-tab-pane key="labels" title="标签">
          <pre class="json-block">{{ prettyJSON(current?.labels) }}</pre>
        </a-tab-pane>
        <a-tab-pane key="annotations" title="注解">
          <pre class="json-block">{{ prettyJSON(current?.annotations) }}</pre>
        </a-tab-pane>
      </a-tabs>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { Message } from '@arco-design/web-vue'
import { IconRefresh, IconSearch } from '@arco-design/web-vue/es/icon'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
import { fetchRawEvents, replayRawEvent, type RawEvent } from '@/api/ops/rawEvent'

const loading = ref(false)
const rows = ref<RawEvent[]>([])
const current = ref<RawEvent | null>(null)
const detailVisible = ref(false)
const errorMessage = ref('')
const pageUnauthorized = ref(false)

const filters = reactive({
  keyword: '',
  source_type: undefined as string | undefined,
  parse_status: undefined as string | undefined,
  severity: undefined as string | undefined,
  resource_uid: '',
})

const pagination = reactive({
  current: 1,
  pageSize: 20,
  total: 0,
  showTotal: true,
  showPageSize: true,
})

const columns: TableColumnData[] = [
  { title: 'ID', dataIndex: 'id', width: 80 },
  { title: '来源', dataIndex: 'source_type', slotName: 'source_type', width: 120 },
  { title: '解析状态', dataIndex: 'parse_status', slotName: 'parse_status', width: 120 },
  { title: '级别', dataIndex: 'severity', slotName: 'severity', width: 100 },
  { title: '资源 UID', dataIndex: 'resource_uid', slotName: 'resource_uid', width: 230 },
  { title: '标题', dataIndex: 'title', width: 220, ellipsis: true, tooltip: true },
  { title: '消息', dataIndex: 'message', ellipsis: true, tooltip: true },
  { title: '事件时间', dataIndex: 'event_time', slotName: 'event_time', width: 180 },
  { title: 'Trace ID', dataIndex: 'trace_id', width: 180, ellipsis: true, tooltip: true },
  { title: '重放次数', dataIndex: 'replay_count', width: 100 },
  { title: '操作', dataIndex: 'actions', slotName: 'actions', fixed: 'right', width: 130 },
]

const canOperate = computed(() => !pageUnauthorized.value)

const pageStatus = computed(() => {
  if (pageUnauthorized.value) return 'unauthorized'
  if (loading.value) return 'loading'
  if (errorMessage.value && !rows.value.length) return 'error'
  if (!rows.value.length) return 'empty'
  return 'success'
})

const isForbidden = (error: any) => error?.response?.status === 403 || error?.code === 403 || error?.code === 401

const setLoadError = (error: any, fallback: string) => {
  if (isForbidden(error)) {
    pageUnauthorized.value = true
    errorMessage.value = '当前账号没有访问原始事件池的权限。'
    return
  }
  errorMessage.value = error?.message || fallback
}

const fetchData = async () => {
  loading.value = true
  errorMessage.value = ''
  pageUnauthorized.value = false
  try {
    const response: any = await fetchRawEvents({
      page: pagination.current,
      page_size: pagination.pageSize,
      keyword: filters.keyword || undefined,
      source_type: filters.source_type,
      parse_status: filters.parse_status,
      severity: filters.severity,
      resource_uid: filters.resource_uid || undefined,
    })
    rows.value = response.details?.data || []
    pagination.total = response.details?.total || 0
  } catch (error) {
    console.error('获取原始事件失败:', error)
    setLoadError(error, '获取原始事件失败')
    Message.error('获取原始事件失败')
  } finally {
    loading.value = false
  }
}

const handleSearch = () => {
  pagination.current = 1
  fetchData()
}

const resetFilters = () => {
  filters.keyword = ''
  filters.source_type = undefined
  filters.parse_status = undefined
  filters.severity = undefined
  filters.resource_uid = ''
  handleSearch()
}

const handlePageChange = (page: number) => {
  pagination.current = page
  fetchData()
}

const handlePageSizeChange = (pageSize: number) => {
  pagination.pageSize = pageSize
  pagination.current = 1
  fetchData()
}

const showDetail = (record: RawEvent) => {
  current.value = record
  detailVisible.value = true
}

const handleReplay = async (record: RawEvent) => {
  try {
    await replayRawEvent(record.id)
    Message.success('重放请求已提交')
    fetchData()
  } catch (error) {
    console.error('重放原始事件失败:', error)
    Message.error('重放原始事件失败')
  }
}

const formatTime = (value?: string) => {
  if (!value) return '-'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return value
  return date.toLocaleString('zh-CN')
}

const sourceText = (value?: string) => {
  const map: Record<string, string> = {
    metric_threshold: '指标阈值',
    syslog: 'Syslog',
    trap: 'Trap',
    probe_failure: '探测失败',
    collection_health: '采集健康',
  }
  return value ? map[value] || value : '-'
}

const parseStatusText = (value?: string) => {
  const map: Record<string, string> = {
    parsed: '已解析',
    unparsed: '未解析',
    replayed: '已重放',
  }
  return value ? map[value] || value : '-'
}

const parseStatusColor = (value?: string) => {
  if (value === 'parsed') return 'green'
  if (value === 'unparsed') return 'orange'
  if (value === 'replayed') return 'blue'
  return 'gray'
}

const severityText = (value?: string) => {
  const map: Record<string, string> = {
    critical: '紧急',
    major: '严重',
    warning: '警告',
    info: '提示',
    minor: '轻微',
  }
  return value ? map[value] || value : '-'
}

const severityColor = (value?: string) => {
  const map: Record<string, string> = {
    critical: 'red',
    major: 'orangered',
    warning: 'orange',
    info: 'blue',
    minor: 'gray',
  }
  return value ? map[value] || 'gray' : 'gray'
}

const prettyJSON = (value?: string) => {
  if (!value) return '{}'
  try {
    return JSON.stringify(JSON.parse(value), null, 2)
  } catch {
    return value
  }
}

const prettyText = (value?: string) => {
  if (!value) return ''
  try {
    return JSON.stringify(JSON.parse(value), null, 2)
  } catch {
    return value
  }
}

onMounted(fetchData)
</script>

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

<style scoped lang="less">
.raw-events-page {
  padding: 16px;
}

.filter-form {
  margin-bottom: 16px;
}

.detail-tabs {
  margin-top: 16px;
}

.json-block {
  max-height: 360px;
  overflow: auto;
  margin: 0;
  padding: 12px;
  background: var(--color-fill-2);
  border: 1px solid var(--color-border-2);
  border-radius: 4px;
  white-space: pre-wrap;
  word-break: break-word;
}

@media (max-width: 768px) {
  .raw-events-page {
    padding: 12px;
  }

  .filter-form {
    display: block;
  }

  :deep(.arco-form-layout-inline .arco-form-item) {
    width: 100%;
    margin-right: 0;
  }

  :deep(.arco-card-header) {
    flex-wrap: wrap;
    gap: 8px;
  }

  :deep(.arco-card-extra) {
    width: 100%;
  }
}
</style>
