<!-- SPEC: PJ2026-010405 云端控制台. -->
<!-- Implementation reference: MDTODO hwlab-web-product-experience/R3. -->

<script setup lang="ts">
import { computed } from "vue";
import ContentViewer from "@/components/common/ContentViewer.vue";
import InspectorPanel from "@/components/console/InspectorPanel.vue";
import StatusBadge from "@/components/common/StatusBadge.vue";
import { agentObserverStatusToken, type AgentObserverEvent, type AgentObserverRun } from "@/stores/agent-observer";

type InspectorTab = "overview" | "relations" | "events" | "logs" | "raw";

const props = withDefaults(defineProps<{
  run: AgentObserverRun;
  events: AgentObserverEvent[];
  logs: AgentObserverEvent[];
  inEventWindow: boolean;
  nowMs: number;
  tab: InspectorTab;
  embedded?: boolean;
}>(), {
  embedded: false,
});
const emit = defineEmits<{ close: []; "update:tab": [value: InspectorTab] }>();
const tabs: Array<{ value: InspectorTab; label: string }> = [
  { value: "overview", label: "概览" },
  { value: "relations", label: "关系" },
  { value: "events", label: "事件" },
  { value: "logs", label: "日志" },
  { value: "raw", label: "原始事实" }
];
const taskToken = computed(() => agentObserverStatusToken(props.run.taskStatus));
const runToken = computed(() => agentObserverStatusToken(props.run.runStatus));
const commandToken = computed(() => agentObserverStatusToken(props.run.commandState));
const attemptToken = computed(() => agentObserverStatusToken(props.run.attemptStatus));
const deepLink = computed(() => `/agents/runs/${encodeURIComponent(props.run.id)}?view=table`);
const rawFacts = computed(() => ({ run: props.run, events: props.events }));
const logContent = computed(() => props.logs.length
  ? props.logs.map((event) => `[${formatTime(event.createdAt)}] ${event.label}\n${event.message || "未知"}`).join("\n\n")
  : "正式事件未提供日志事实。");

function unknown(value: string | number | null): string | number {
  return value === null || value === "" ? "未知" : value;
}

function formatTime(value: string | null): string {
  if (!value) return "未知";
  const timestamp = Date.parse(value);
  return Number.isFinite(timestamp) ? new Date(timestamp).toLocaleString("zh-CN") : value;
}

function duration(): string {
  if (!props.run.startedAt) return "未知";
  const end = props.run.finishedAt ? Date.parse(props.run.finishedAt) : props.nowMs;
  const start = Date.parse(props.run.startedAt);
  if (!Number.isFinite(start) || !Number.isFinite(end)) return "未知";
  const seconds = Math.max(0, Math.floor((end - start) / 1000));
  if (seconds < 60) return `${seconds} 秒`;
  if (seconds < 3600) return `${Math.floor(seconds / 60)} 分钟`;
  return `${Math.floor(seconds / 3600)} 小时 ${Math.floor((seconds % 3600) / 60)} 分钟`;
}

function fact(value: boolean | null): string {
  return value === null ? "未知" : value ? "是" : "否";
}
</script>

<template>
  <InspectorPanel :title="run.id" :subtitle="`${runToken.label} · ${run.phase || '阶段未知'}`" :embedded="embedded" @close="emit('close')">
    <template #tabs>
      <button v-for="item in tabs" :key="item.value" type="button" role="tab" :aria-selected="tab === item.value" @click="emit('update:tab', item.value)">{{ item.label }}</button>
    </template>

    <p v-if="!inEventWindow" class="agent-observer-window-warning" role="status">所选实体不在当前有界 Kafka 事件窗口；保留稳定深链与最后确认实体事实，不静默改选。</p>

    <div v-if="tab === 'overview'" class="agent-observer-inspector-section">
      <div class="agent-observer-status-matrix">
        <span><small>Task</small><StatusBadge :status="taskToken.tone" :label="taskToken.label" /></span>
        <span><small>Run</small><StatusBadge :status="runToken.tone" :label="runToken.label" /></span>
        <span><small>Command</small><StatusBadge :status="commandToken.tone" :label="commandToken.label" /></span>
        <span><small>Attempt</small><StatusBadge :status="attemptToken.tone" :label="attemptToken.label" /></span>
      </div>
      <dl class="agent-observer-inspector-grid">
        <div class="agent-observer-inspector-wide"><dt>任务标题</dt><dd>{{ unknown(run.title) }}</dd></div>
        <div><dt>阶段</dt><dd>{{ unknown(run.phase) }}</dd></div><div><dt>错误分类</dt><dd>{{ unknown(run.errorCode) }}</dd></div>
        <div><dt>开始</dt><dd>{{ formatTime(run.startedAt) }}</dd></div><div><dt>结束</dt><dd>{{ formatTime(run.finishedAt) }}</dd></div>
        <div><dt>耗时</dt><dd>{{ duration() }}</dd></div><div><dt>最后活动</dt><dd>{{ formatTime(run.updatedAt) }}</dd></div>
        <div><dt>最终回复</dt><dd>{{ fact(run.final) }}</dd></div><div><dt>回复 Authority</dt><dd>{{ fact(run.replyAuthority) }}</dd></div>
        <div><dt>业务结果</dt><dd>{{ unknown(run.result) }}</dd></div>
      </dl>
    </div>

    <dl v-else-if="tab === 'relations'" class="agent-observer-inspector-grid">
      <div><dt>Task</dt><dd class="mono">{{ unknown(run.taskId) }}</dd></div><div><dt>Run</dt><dd class="mono">{{ run.id }}</dd></div>
      <div><dt>Command</dt><dd class="mono">{{ unknown(run.commandId) }}</dd></div><div><dt>Attempt</dt><dd class="mono">{{ unknown(run.attemptId) }}</dd></div>
      <div><dt>Session</dt><dd class="mono">{{ unknown(run.sessionId) }}</dd></div><div><dt>Trace</dt><dd class="mono">{{ unknown(run.traceId) }}</dd></div>
      <div><dt>Project</dt><dd>{{ unknown(run.projectId) }}</dd></div><div><dt>Workspace</dt><dd class="mono agent-observer-break">{{ unknown(run.workspace) }}</dd></div>
      <div><dt>Runner</dt><dd class="mono">{{ unknown(run.runnerId) }}</dd></div><div><dt>Node / Lane</dt><dd>{{ unknown(run.nodeId) }} / {{ unknown(run.lane) }}</dd></div>
      <div class="agent-observer-inspector-wide"><dt>稳定深链</dt><dd><a :href="deepLink" class="mono agent-observer-break">{{ deepLink }}</a></dd></div>
    </dl>

    <ol v-else-if="tab === 'events'" class="agent-observer-event-tail">
      <li v-for="event in events" :key="event.id"><span>{{ formatTime(event.createdAt) }}</span><strong>{{ event.label }}</strong><small>{{ event.message || event.status || "未知" }}</small></li>
      <li v-if="events.length === 0">当前有界 Kafka 事件窗口无可显示事件。</li>
    </ol>

    <ContentViewer v-else-if="tab === 'logs'" :content="logContent" mode="log" title="Kafka 日志事实" filename="agentrun-events.log" />

    <ContentViewer v-else :content="rawFacts" mode="json" title="AgentRun 原始事实" filename="agentrun-facts.json" />
  </InspectorPanel>
</template>
