<template>
  <section class="agent-trace-center">
    <section class="trace-filters panel">
      <label class="trace-field trace-search">
        <span>关键字</span>
        <input
          v-model="filters.keyword"
          type="search"
          placeholder="Run ID、会话 ID、摘要、场景"
          @keydown.enter.prevent="refresh"
        />
      </label>
      <label class="trace-field">
        <span>Agent</span>
        <select v-model="filters.agent">
          <option value="">全部 Agent</option>
          <option value="orchestrator">Orchestrator</option>
          <option value="user_agent">User Agent</option>
          <option value="hermes">Hermes</option>
        </select>
      </label>
      <label class="trace-field">
        <span>状态</span>
        <select v-model="filters.status">
          <option value="">全部状态</option>
          <option value="succeeded">成功</option>
          <option value="blocked">阻断</option>
          <option value="failed">失败</option>
          <option value="running">运行中</option>
        </select>
      </label>
      <label class="trace-field">
        <span>来源</span>
        <select v-model="filters.source">
          <option value="">全部来源</option>
          <option value="user_message">用户消息</option>
          <option value="schedule">定时任务</option>
          <option value="system_event">系统事件</option>
        </select>
      </label>
    </section>

    <div class="trace-layout">
      <section class="trace-list panel">
        <div class="trace-list-head">
          <div>
            <strong>运行记录</strong>
            <span>共 {{ traces.length }} 条</span>
          </div>
          <div class="trace-list-actions">
            <button v-if="hasActiveFilter" class="trace-mini-action" type="button" @click="resetFilters">
              清空筛选
            </button>
            <button class="trace-mini-action" type="button" :disabled="loading" @click="refresh">
              <i :class="loading ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-refresh'"></i>
              <span>{{ loading ? '刷新中' : '刷新' }}</span>
            </button>
          </div>
        </div>

        <div v-if="loading && !traces.length" class="trace-state">
          <i class="mdi mdi-loading mdi-spin"></i>
          <strong>正在加载 Trace</strong>
        </div>
        <div v-else-if="errorMessage" class="trace-state error">
          <i class="mdi mdi-alert-circle-outline"></i>
          <strong>加载失败</strong>
          <p>{{ errorMessage }}</p>
        </div>
        <div v-else-if="!traces.length" class="trace-state">
          <i class="mdi mdi-timeline-question-outline"></i>
          <strong>暂无 Trace 记录</strong>
          <p>当前筛选条件下没有可展示的 Agent 运行链路。</p>
        </div>
        <table v-else class="trace-table">
          <thead>
            <tr>
              <th>开始时间</th>
              <th>场景</th>
              <th>状态</th>
              <th>摘要</th>
              <th>Run ID</th>
            </tr>
          </thead>
          <tbody>
            <tr
              v-for="trace in traces"
              :key="trace.runId"
              :class="{ active: trace.runId === selectedRunId }"
              tabindex="0"
              @click="openTrace(trace.runId)"
              @keydown.enter.prevent="openTrace(trace.runId)"
            >
              <td>{{ formatTraceDateTime(trace.startedAt) }}</td>
              <td>
                <strong>{{ trace.title }}</strong>
                <span>{{ trace.sourceLabel }} · {{ trace.agent }}</span>
              </td>
              <td>
                <span class="trace-status" :class="resolveTraceStatusTone(trace.status)">
                  {{ trace.statusLabel }}
                </span>
              </td>
              <td>
                <strong>{{ trace.summary || '暂无摘要' }}</strong>
                <span>{{ trace.eventCount || trace.toolCallCount }} 个事件 · {{ trace.failedToolCallCount }} 个失败工具</span>
              </td>
              <td class="trace-run-id">{{ trace.runId }}</td>
            </tr>
          </tbody>
        </table>
      </section>

      <section class="trace-detail panel">
        <div v-if="detailLoading" class="trace-state">
          <i class="mdi mdi-loading mdi-spin"></i>
          <strong>正在读取链路详情</strong>
        </div>
        <div v-else-if="detailError" class="trace-state error">
          <i class="mdi mdi-alert-circle-outline"></i>
          <strong>详情加载失败</strong>
          <p>{{ detailError }}</p>
        </div>
        <div v-else-if="!detail" class="trace-state">
          <i class="mdi mdi-timeline-clock-outline"></i>
          <strong>选择一条运行记录</strong>
          <p>点击左侧 Run ID，可查看完整事件时间线、输入输出和会话上下文。</p>
        </div>
        <template v-else>
          <header class="trace-detail-head">
            <div>
              <span class="trace-kicker">{{ detail.agent || 'agent' }}</span>
              <h4>{{ detail.runId }}</h4>
              <p>{{ detail.summary || detail.errorMessage || '暂无运行摘要' }}</p>
            </div>
            <span class="trace-status" :class="resolveTraceStatusTone(detail.status)">
              {{ detail.status || 'unknown' }}
            </span>
          </header>

          <div v-if="detail.fallbackGenerated" class="trace-inline-alert">
            当前运行没有持久化 trace event，已从 AgentRun、语义解析和工具调用合成只读时间线。
          </div>

          <div class="trace-metrics">
            <div>
              <span>会话</span>
              <strong>{{ detail.conversationId || '-' }}</strong>
            </div>
            <div>
              <span>工具调用</span>
              <strong>{{ detail.toolCalls.length }}</strong>
            </div>
            <div>
              <span>事件数</span>
              <strong>{{ detail.events.length }}</strong>
            </div>
          </div>

          <div class="trace-detail-grid">
            <section class="trace-event-list">
              <button
                v-for="event in detail.events"
                :key="event.id"
                class="trace-event"
                :class="{ active: selectedEvent?.id === event.id }"
                type="button"
                @click="selectedEventId = event.id"
              >
                <span class="event-index">{{ event.sequence }}</span>
                <span class="event-copy">
                  <strong>{{ event.title || event.eventName }}</strong>
                  <small>{{ event.stage }} · {{ formatTraceDuration(event.durationMs) }}</small>
                </span>
                <span class="trace-status mini" :class="resolveTraceStatusTone(event.status)">
                  {{ event.statusLabel }}
                </span>
              </button>
            </section>

            <section class="trace-event-payload">
              <template v-if="selectedEvent">
                <div class="payload-head">
                  <div>
                    <strong>{{ selectedEvent.title }}</strong>
                    <span>{{ formatTraceDateTime(selectedEvent.startedAt) }}</span>
                  </div>
                  <span>{{ selectedEvent.summary || selectedEvent.eventName }}</span>
                </div>
                <p v-if="selectedEvent.errorMessage" class="trace-error-text">
                  {{ selectedEvent.errorMessage }}
                </p>
                <div class="payload-columns">
                  <div>
                    <h5>输入</h5>
                    <pre>{{ formatTraceJson(selectedEvent.inputJson) }}</pre>
                  </div>
                  <div>
                    <h5>输出</h5>
                    <pre>{{ formatTraceJson(selectedEvent.outputJson) }}</pre>
                  </div>
                </div>
              </template>
            </section>
          </div>
        </template>
      </section>
    </div>
  </section>
</template>

<script setup>
import { computed, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'

import { fetchAgentTraceDetail, fetchAgentTraces } from '../services/agentTraces.js'
import {
  formatTraceDateTime,
  formatTraceDuration,
  formatTraceJson,
  normalizeTraceDetail,
  normalizeTraceListItem,
  resolveTraceStatusTone
} from '../utils/agentTraceViewModel.js'

defineOptions({
  name: 'AgentTraceCenterView'
})

const route = useRoute()
const router = useRouter()
const traces = ref([])
const detail = ref(null)
const selectedRunId = ref('')
const selectedEventId = ref('')
const loading = ref(false)
const detailLoading = ref(false)
const errorMessage = ref('')
const detailError = ref('')
const filters = ref({
  keyword: '',
  agent: '',
  status: '',
  source: ''
})

const hasActiveFilter = computed(() =>
  Object.values(filters.value).some((value) => String(value || '').trim())
)
const selectedEvent = computed(() =>
  detail.value?.events.find((event) => event.id === selectedEventId.value) || detail.value?.events[0] || null
)

async function refresh() {
  loading.value = true
  errorMessage.value = ''
  try {
    const payload = await fetchAgentTraces({
      keyword: filters.value.keyword,
      agent: filters.value.agent,
      status: filters.value.status,
      source: filters.value.source,
      limit: 80
    })
    traces.value = Array.isArray(payload) ? payload.map(normalizeTraceListItem) : []
  } catch (error) {
    errorMessage.value = error?.message || 'Agent Trace 加载失败，请稍后重试。'
  } finally {
    loading.value = false
  }
}

async function openTrace(runId) {
  const normalizedRunId = String(runId || '').trim()
  if (!normalizedRunId) {
    return
  }
  selectedRunId.value = normalizedRunId
  detailLoading.value = true
  detailError.value = ''
  router.replace({
    name: 'app-settings',
    query: {
      ...route.query,
      section: 'agentTraces',
      run_id: normalizedRunId
    }
  })
  try {
    detail.value = normalizeTraceDetail(await fetchAgentTraceDetail(normalizedRunId))
    selectedEventId.value = detail.value.events[0]?.id || ''
  } catch (error) {
    detail.value = null
    detailError.value = error?.message || 'Agent Trace 详情加载失败，请稍后重试。'
  } finally {
    detailLoading.value = false
  }
}

function resetFilters() {
  filters.value = {
    keyword: '',
    agent: '',
    status: '',
    source: ''
  }
  void refresh()
}

watch(
  () => [filters.value.agent, filters.value.status, filters.value.source],
  () => {
    void refresh()
  }
)

watch(
  () => route.query.run_id,
  (runId) => {
    const normalizedRunId = String(runId || '').trim()
    if (normalizedRunId && normalizedRunId !== selectedRunId.value) {
      void openTrace(normalizedRunId)
    }
  }
)

onMounted(async () => {
  await refresh()
  const initialRunId = String(route.query.run_id || '').trim()
  if (initialRunId) {
    await openTrace(initialRunId)
  }
})
</script>

<style scoped src="../assets/styles/views/agent-trace-center-view.css"></style>
