<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

import { showConfirm, showError, showSuccess } from '@/lib/feedback'
import { fetchAdminWebhookEventDetail, replayAdminWebhookEvent } from '@/services/admin'
import AdminStatusTag from '@/components/admin/AdminStatusTag.vue'
import type { AdminWebhookEventDetail, AdminWebhookReplayResponse } from '@/types/admin'
import { hasAdminRole } from '@/utils/admin-auth'
import { formatAdminDateTime } from '@/utils/admin-time'
import { stringifyDisplayJson } from '@/utils/date-time'
import { formatAdminWebhookEventType } from '@/utils/admin-webhook'

const route = useRoute()
const loading = ref(true)
const replayLoading = ref(false)
const errorMessage = ref('')
const detail = ref<AdminWebhookEventDetail | null>(null)
const lastReplayResult = ref<AdminWebhookReplayResponse['result'] | null>(null)

async function loadDetail() {
  loading.value = true
  errorMessage.value = ''

  try {
    const response = await fetchAdminWebhookEventDetail(String(route.params.eventId || ''))
    detail.value = response.data
  } catch (error) {
    errorMessage.value = error instanceof Error ? error.message : '读取 webhook 详情失败'
  } finally {
    loading.value = false
  }
}

async function submitReplay() {
  if (!detail.value) {
    return
  }

  try {
    await showConfirm(
      `确认重放 webhook #${detail.value.eventId} 吗？这会重新推进订单与任务处理。`,
      '确认重放',
      {
        type: 'warning',
        confirmButtonText: '继续重放',
        cancelButtonText: '取消',
      },
    )
  } catch {
    return
  }

  replayLoading.value = true

  try {
    const response = await replayAdminWebhookEvent(detail.value.eventId)
    lastReplayResult.value = response.data.result
    showSuccess(`Webhook 已重放，生成/更新任务 ${response.data.result.taskCount} 条`)
    await loadDetail()
  } catch (error) {
    showError(error instanceof Error ? error.message : '重放 webhook 失败')
  } finally {
    replayLoading.value = false
  }
}

function prettyJson(value: Record<string, unknown>) {
  return stringifyDisplayJson(value, 2)
}

function formatRequestTimestamp(value: string) {
  const normalized = String(value || '').trim()

  if (!/^\d{10,13}$/.test(normalized)) {
    return normalized || '-'
  }

  const epochMs = normalized.length === 13 ? Number(normalized) : Number(normalized) * 1000
  return formatAdminDateTime(new Date(epochMs).toISOString())
}

function formatAmount(detail: AdminWebhookEventDetail) {
  return detail.totalAmount ? `${detail.totalAmount} ${detail.currency}` : '-'
}

onMounted(loadDetail)
</script>

<template>
  <section class="admin-panel">
    <AdminPageHeader title="Webhook 详情" description="查看原始请求并手动重放处理流程。">
      <el-button
        v-if="hasAdminRole('admin')"
        :loading="replayLoading"
        round
        type="primary"
        @click="submitReplay"
        >重放处理</el-button
      >
    </AdminPageHeader>

    <p v-if="errorMessage" class="error-copy">{{ errorMessage }}</p>
    <div v-if="loading" class="empty-block">Webhook 详情加载中</div>

    <template v-else-if="detail">
      <section class="info-card">
        <div class="overview-top">
          <div>
            <h3>{{ formatAdminWebhookEventType(detail.eventType) }}</h3>
            <p class="muted-copy">
              #{{ detail.eventId }} · {{ detail.provider }} / {{ detail.platform }}
              <template v-if="detail.platformRaw && detail.platformRaw !== detail.platform">
                · 原始平台 {{ detail.platformRaw }}
              </template>
            </p>
          </div>
          <div class="tag-row">
            <AdminStatusTag :status="detail.signatureValid ? 'success' : 'failed'" />
            <AdminStatusTag :status="detail.processed ? 'success' : 'failed'" />
          </div>
        </div>

        <div class="summary-grid">
          <div class="summary-item">
            <span class="summary-label">店铺</span>
            <strong>{{ detail.shopName || detail.shopId || '-' }}</strong>
            <span class="summary-note">ID: {{ detail.shopId || '-' }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">平台订单</span>
            <strong>{{ detail.platformOrderId || '-' }}</strong>
            <span class="summary-note">aopic: {{ detail.aopic || '-' }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">关联订单</span>
            <strong v-if="detail.relatedOrderId">
              <RouterLink class="inline-link" :to="`/admin/orders/${detail.relatedOrderId}`">{{
                detail.relatedOrderId
              }}</RouterLink>
            </strong>
            <strong v-else>-</strong>
            <span class="summary-note">任务数: {{ detail.taskCount }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">买家</span>
            <strong>{{ detail.buyerName || detail.buyerId || '-' }}</strong>
            <span class="summary-note">买家 ID: {{ detail.buyerId || '-' }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">金额</span>
            <strong>{{ formatAmount(detail) }}</strong>
            <span class="summary-note">商品数: {{ detail.itemCount }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">请求时间</span>
            <strong>{{ formatRequestTimestamp(detail.requestTimestamp) }}</strong>
            <span class="summary-note">入库时间: {{ formatAdminDateTime(detail.createdAt) }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">来源 Host</span>
            <strong>{{ detail.sourceHost || '-' }}</strong>
            <span class="summary-note">来源 IP: {{ detail.sourceIp || '-' }}</span>
          </div>
          <div class="summary-item">
            <span class="summary-label">消息说明</span>
            <strong>{{ detail.messageText || '-' }}</strong>
            <span class="summary-note">签名: {{ detail.requestSign || '-' }}</span>
          </div>
        </div>

        <div class="event-key-block">
          <span class="summary-label">事件 Key</span>
          <code>{{ detail.eventKey }}</code>
        </div>

        <div v-if="detail.processError" class="inline-error">{{ detail.processError }}</div>
      </section>

      <section v-if="lastReplayResult" class="info-card">
        <h3>最近一次重放结果</h3>
        <p class="result-copy">
          {{ lastReplayResult.provider }} / {{ lastReplayResult.platform }}
          <template
            v-if="
              lastReplayResult.platformRaw &&
              lastReplayResult.platformRaw !== lastReplayResult.platform
            "
          >
            · 原始平台 {{ lastReplayResult.platformRaw }}
          </template>
          · 平台订单 {{ lastReplayResult.platformOrderId }} · 事件
          {{ formatAdminWebhookEventType(lastReplayResult.eventType) }} · 任务数
          {{ lastReplayResult.taskCount }}
        </p>
        <el-table :data="lastReplayResult.tasks" size="small">
          <el-table-column prop="taskId" label="任务 ID" />
          <el-table-column prop="taskNo" label="任务号" />
          <el-table-column label="状态">
            <template #default="{ row }">
              <AdminStatusTag :status="row.status" />
            </template>
          </el-table-column>
        </el-table>
      </section>

      <section class="info-card">
        <h3>解析后的 Payload</h3>
        <pre class="json-block">{{ prettyJson(detail.payload) }}</pre>
      </section>

      <section class="info-card">
        <h3>Headers</h3>
        <pre class="json-block">{{ prettyJson(detail.headers) }}</pre>
      </section>

      <section class="info-card">
        <h3>Query</h3>
        <pre class="json-block">{{ prettyJson(detail.query) }}</pre>
      </section>

      <section class="info-card">
        <h3>Body</h3>
        <pre class="json-block">{{ prettyJson(detail.body) }}</pre>
      </section>
    </template>
  </section>
</template>

<style scoped>
.admin-panel {
  display: grid;
  gap: var(--space-4);
}

.info-card,
.empty-block,
.error-copy {
  padding: 18px;
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
}

.overview-top {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  align-items: flex-start;
}

.overview-top h3,
.info-card h3 {
  margin: 0;
  color: var(--text-primary);
}

.muted-copy {
  margin: var(--space-2) 0 0;
  color: var(--text-secondary);
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.summary-item {
  display: grid;
  gap: 6px;
  padding: 14px;
  border-radius: var(--radius-md);
  background: var(--bg-page);
  border: 1px solid var(--border-default);
}

.summary-label {
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 700;
}

.summary-item strong {
  color: var(--text-primary);
  word-break: break-all;
}

.summary-note {
  color: var(--text-secondary);
  font-size: var(--text-xs);
  line-height: 1.5;
  word-break: break-all;
}

.event-key-block {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: 14px;
  border-radius: var(--radius-md);
  background: var(--bg-page);
  border: 1px solid var(--border-default);
}

.event-key-block code {
  color: var(--text-primary);
  font-size: var(--text-xs);
  line-height: 1.6;
  word-break: break-all;
  white-space: pre-wrap;
}

.error-copy {
  color: var(--color-danger);
}

.inline-error {
  margin-top: var(--space-4);
  padding: var(--space-3) 14px;
  border-radius: 14px;
  color: var(--color-danger);
  background: var(--color-danger-light);
  border: 1px solid #fecdca;
  line-height: 1.6;
}

.result-copy {
  margin: var(--space-3) 0;
  color: var(--text-secondary);
}

.inline-link {
  color: var(--color-primary);
}

.json-block {
  margin: var(--space-3) 0 0;
  padding: 14px;
  border-radius: 14px;
  background: #0f172a;
  color: #e2e8f0;
  overflow-y: auto;
  font-size: var(--text-xs);
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

@media (max-width: 900px) {
  .overview-top {
    flex-direction: column;
  }

  .summary-grid {
    grid-template-columns: 1fr;
  }
}
</style>
