<!-- SPEC: PJ2026-010405 云端控制台 / ExternalSecretDetail. -->
<!-- Implementation reference: draft-2026-07-13-p0-cloud-console. -->
<!-- Responsibility: 展示脱敏 ExternalSecret 事实、事件与消费者状态。 -->

<script setup lang="ts">
import { ChevronLeft, List, LockKeyhole, RefreshCw } from "lucide-vue-next";
import { computed } from "vue";
import DataGrid from "@/components/common/DataGrid.vue";
import type { DataGridColumn } from "@/components/common/DataGrid.vue";
import ResourceCollection from "@/components/common/ResourceCollection.vue";
import ViewModeSwitch from "@/components/console/ViewModeSwitch.vue";
import SectionFrame from "@/components/layout/SectionFrame.vue";
import StatusStrip from "@/components/layout/StatusStrip.vue";
import type { AdminSecretsDetailView, AdminSecretsEventView } from "@/stores/admin-secrets-view";

interface RemoteRefRow extends Record<string, unknown> { id: string; targetKey: string; remotePath: string; property: string; version: string; fingerprint: string }
interface EventRow extends Record<string, unknown> { id: string; status: string; reason: string; message: string; observedAt: string; source: string; traceId: string; jobId: string }

const props = defineProps<{ detail: AdminSecretsDetailView; events: AdminSecretsEventView[]; refreshing: boolean }>();
const activeTab = defineModel<"details" | "events">("activeTab", { required: true });
const emit = defineEmits<{ back: []; refresh: [] }>();
const remoteColumns: DataGridColumn[] = [{ key: "targetKey", label: "Target key" }, { key: "remotePath", label: "Path" }, { key: "property", label: "Property" }, { key: "version", label: "Version" }, { key: "fingerprint", label: "Fingerprint" }];
const eventColumns: DataGridColumn[] = [{ key: "status", label: "Status" }, { key: "reason", label: "Reason" }, { key: "message", label: "Message" }, { key: "observedAt", label: "Observed" }, { key: "evidence", label: "Evidence" }];
const remoteRows = computed<RemoteRefRow[]>(() => props.detail.data.map((item, index) => ({ id: `${item.targetKey}:${item.fingerprint}:${index}`, ...item })));
const eventRows = computed<EventRow[]>(() => props.events.map((event) => ({ id: event.id, status: event.status, reason: event.reason, message: event.message, observedAt: displayDate(event.observedAt), source: event.source, traceId: event.traceId, jobId: event.jobId })));
const statusItems = computed(() => [
  { id: "status", label: "Status", value: props.detail.status, tone: props.detail.ready ? "ok" as const : "warn" as const },
  { id: "updated", label: "Last updated", value: displayDate(props.detail.lastUpdated) },
  { id: "target", label: "Target Secret", value: props.detail.targetSecretName || "-" },
  { id: "values", label: "Values", value: props.detail.valuesPrinted ? "printed" : "redacted", tone: props.detail.valuesPrinted ? "error" as const : "ok" as const }
]);
function displayDate(value: string): string { if (!value) return "-"; const date = new Date(value); return Number.isNaN(date.getTime()) ? value : date.toLocaleString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" }); }
</script>

<template>
  <div class="external-secret-workspace">
    <div class="page-command-actions">
      <button class="table-action" type="button" title="返回密钥列表" @click="emit('back')"><ChevronLeft :size="16" aria-hidden="true" />返回</button>
      <button class="table-action" type="button" :disabled="refreshing" :title="refreshing ? '刷新中' : '刷新 ExternalSecret'" @click="emit('refresh')"><RefreshCw :size="16" aria-hidden="true" />{{ refreshing ? '刷新中' : '刷新' }}</button>
      <ViewModeSwitch v-model="activeTab" :options="[{ value: 'details', label: '详情', icon: LockKeyhole }, { value: 'events', label: `事件 ${events.length}`, icon: List }]" label="ExternalSecret 详情视图" />
    </div>
    <StatusStrip :items="statusItems" label="ExternalSecret 状态" live="polite" />

    <div v-if="activeTab === 'details'" class="external-secret-grid">
      <SectionFrame title="Metadata" :description="`${detail.namespace} / ${detail.cluster}`">
        <dl class="industrial-fact-row"><div v-for="item in detail.metadata" :key="item.label"><dt>{{ item.label }}</dt><dd>{{ item.value }}</dd></div></dl>
      </SectionFrame>
      <SectionFrame title="Target Secret" :description="detail.targetSecretName" :body-padding="false">
        <ResourceCollection
          :items="detail.targetKeys"
          :item-key="(item) => `${item.key}:${item.fingerprint}`"
          :item-title="(item) => item.key"
          :item-subtitle="(item) => item.fingerprint"
          :item-status="(item) => item.presence"
          view="list"
          density="compact"
          :show-controls="false"
          empty-text="暂无 target key。"
          aria-label="Target Secret keys"
        />
      </SectionFrame>
      <SectionFrame class="external-secret-wide" title="Store / RemoteRef" :description="detail.storeText" :body-padding="false">
        <DataGrid :columns="remoteColumns" :rows="remoteRows" :row-key="(row) => row.id" :interactive="false" density="compact" empty-text="暂无 remote reference。" aria-label="ExternalSecret remote references" />
      </SectionFrame>
      <SectionFrame title="Conditions" :description="detail.reason" :body-padding="false">
        <ResourceCollection
          :items="detail.conditions"
          :item-key="(item) => `${item.type}:${item.lastTransitionTime}`"
          :item-title="(item) => `${item.type} / ${item.status}`"
          :item-subtitle="(item) => `${item.reason} / ${displayDate(item.lastTransitionTime)}`"
          :item-status="(item) => item.status"
          view="list"
          density="compact"
          :show-controls="false"
          empty-text="暂无 condition。"
          aria-label="ExternalSecret conditions"
        />
      </SectionFrame>
      <SectionFrame title="Consumers" :description="`${detail.consumers.length} rows`" :body-padding="false">
        <ResourceCollection
          :items="detail.consumers"
          :item-key="(item) => `${item.serviceId}:${item.envName}`"
          :item-title="(item) => item.serviceId"
          :item-subtitle="(item) => `${item.kind} / ${item.injectAs} / ${item.envName} / ${item.rollout}`"
          :item-status="(item) => item.status"
          view="list"
          density="compact"
          :show-controls="false"
          empty-text="暂无 consumer rollout 记录。"
          aria-label="ExternalSecret consumers"
        />
      </SectionFrame>
      <SectionFrame class="external-secret-wide" title="Provenance" description="valuesPrinted=false">
        <dl class="industrial-fact-row"><div v-for="item in detail.provenance" :key="item.label"><dt>{{ item.label }}</dt><dd>{{ item.value }}</dd></div></dl>
      </SectionFrame>
    </div>

    <SectionFrame v-else title="Events" :description="`${events.length} rows`" :body-padding="false">
      <DataGrid :columns="eventColumns" :rows="eventRows" :row-key="(row) => row.id" :interactive="false" density="compact" empty-text="当前 ExternalSecret 暂无资源级事件。" aria-label="ExternalSecret events">
        <template #cell-status="{ row }"><span class="status-pill" :data-status="String((row as EventRow).status).toLowerCase()">{{ (row as EventRow).status }}</span></template>
        <template #cell-evidence="{ row }"><small>{{ (row as EventRow).source }} / trace {{ (row as EventRow).traceId }} / job {{ (row as EventRow).jobId }}</small></template>
      </DataGrid>
    </SectionFrame>
  </div>
</template>

<style scoped>
.external-secret-workspace { display: grid; gap: 12px; min-width: 0; }
.external-secret-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; min-width: 0; }
.external-secret-wide { grid-column: 1 / -1; }
@media (max-width: 840px) { .external-secret-grid { grid-template-columns: 1fr; } .external-secret-wide { grid-column: auto; } }
</style>
