<template>
  <div class="page-content">
    <div class="mb-5">
      <h2 class="text-xl font-semibold">事件投递</h2>
      <p class="text-g-500 mt-1 text-sm">查看事务 Outbox 到 Redis Stream 的投递状态、死信原因并安全重试</p>
    </div>

    <div class="mb-4 flex flex-wrap items-center gap-3">
      <ElSelect v-model="filters.status" clearable placeholder="全部状态" class="!w-36">
        <ElOption label="待投递" value="pending" />
        <ElOption label="死信" value="dead" />
        <ElOption label="已投递" value="processed" />
      </ElSelect>
      <ElInput v-model="filters.type" clearable placeholder="事件类型（精确匹配）" class="!w-64" @keyup.enter="load" />
      <ElButton type="primary" :loading="loading" @click="load">查询</ElButton>
    </div>

    <ElAlert class="mb-4" type="info" :closable="false" show-icon title="重试不会重复写入 Stream：Worker 使用事件 ID 去重；下游消费者仍应使用 event_id 执行事务幂等。" />
    <ElTable v-loading="loading" :data="events" row-key="event_id">
      <ElTableColumn label="状态" width="100"><template #default="{ row }"><ElTag :type="statusOf(row).type">{{ statusOf(row).label }}</ElTag></template></ElTableColumn>
      <ElTableColumn prop="event_type" label="事件类型" min-width="210" />
      <ElTableColumn label="聚合" min-width="220"><template #default="{ row }"><div>{{ row.aggregate_type }}</div><div class="text-g-500 text-xs">{{ row.aggregate_id }}</div></template></ElTableColumn>
      <ElTableColumn prop="attempts" label="尝试" width="80" />
      <ElTableColumn label="发生时间" min-width="180"><template #default="{ row }">{{ formatTime(row.occurred_at) }}</template></ElTableColumn>
      <ElTableColumn label="投递信息" min-width="220"><template #default="{ row }"><div v-if="row.published_stream_id">Stream: {{ row.published_stream_id }}</div><div v-if="row.last_error" class="text-danger line-clamp-2">{{ row.last_error }}</div><span v-if="!row.published_stream_id && !row.last_error">—</span></template></ElTableColumn>
      <ElTableColumn label="操作" fixed="right" width="160"><template #default="{ row }"><ElButton link type="primary" @click="showPayload(row)">Payload</ElButton><ElButton v-if="!row.processed_at" link type="warning" @click="retry(row)">重试</ElButton></template></ElTableColumn>
    </ElTable>

    <ElDialog v-model="payloadVisible" title="事件 Payload" width="680px">
      <pre class="max-h-[60vh] overflow-auto rounded bg-black/5 p-4 text-xs dark:bg-white/5">{{ selectedPayload }}</pre>
    </ElDialog>
  </div>
</template>

<script setup lang="ts">
  import { ElMessage, ElMessageBox } from 'element-plus'
  import { OutboxEvent, fetchOutboxEvents, retryOutboxEvent } from '@/api/outbox'

  const loading = ref(false)
  const events = ref<OutboxEvent[]>([])
  const filters = reactive({ status: 'pending', type: '' })
  const payloadVisible = ref(false)
  const selectedPayload = ref('')

  async function load() {
    loading.value = true
    try { events.value = await fetchOutboxEvents({ status: filters.status || undefined, type: filters.type.trim() || undefined, limit: 200 }) }
    finally { loading.value = false }
  }
  function statusOf(row: OutboxEvent): { label: string; type: 'success' | 'danger' | 'warning' } {
    if (row.processed_at) return { label: '已投递', type: 'success' }
    if (row.dead_lettered_at) return { label: '死信', type: 'danger' }
    return { label: '待投递', type: 'warning' }
  }
  function showPayload(row: OutboxEvent) {
    selectedPayload.value = JSON.stringify({ payload: row.payload, trace_context: row.trace_context }, null, 2)
    payloadVisible.value = true
  }
  async function retry(row: OutboxEvent) {
    await ElMessageBox.confirm(`确认重新投递 ${row.event_type}？`, '重试事件', { type: 'warning' })
    await retryOutboxEvent(row.event_id)
    ElMessage.success('事件已进入重试队列')
    await load()
  }
  function formatTime(value: string) { return new Date(value).toLocaleString() }
  onMounted(load)
</script>
