<template>
  <section class="log-detail-page">
    <div class="detail-scroll">
      <article v-if="loading" class="panel detail-state">
        <i class="mdi mdi-loading mdi-spin"></i>
        <strong>正在加载日志详情</strong>
        <p>系统正在读取当前记录的结构化信息。</p>
      </article>

      <article v-else-if="error" class="panel detail-state error">
        <i class="mdi mdi-alert-circle-outline"></i>
        <strong>日志详情加载失败</strong>
        <p>{{ error }}</p>
        <button type="button" @click="loadDetail">重新加载</button>
      </article>

      <template v-else-if="isHermes && hermesRun">
        <article class="detail-hero panel">
          <div class="hero-copy">
            <div class="hero-tags">
              <span class="level-pill" :class="resolveLevelTone(resolveRunLevel(hermesRun))">
                {{ resolveRunLevel(hermesRun) }}
              </span>
              <span class="status-pill" :class="resolveStatusTone(hermesRun)">
                {{ resolveStatusLabel(hermesRun) }}
              </span>
            </div>
            <h2>{{ resolveRunTitle(hermesRun) }}</h2>
            <p>{{ hermesRun.result_summary || '暂无运行摘要。' }}</p>
            <p v-if="hermesRun.status === 'running'" class="hero-hint">运行中每 5 秒自动刷新一次详情。</p>
          </div>
          <div class="hero-actions">
            <button class="refresh-btn" type="button" :disabled="loading" @click="loadDetail">
              <i class="mdi mdi-refresh"></i>
              <span>刷新详情</span>
            </button>
          </div>
        </article>

        <article
          v-if="hermesRunAlert"
          class="panel detail-alert"
          :class="hermesRunAlert.tone"
        >
          {{ hermesRunAlert.message }}
        </article>

        <div class="detail-grid">
          <article class="panel detail-card wide">
            <div class="card-head">
              <h3>基本信息</h3>
              <p>围绕当前 Hermes 任务查看关键字段。</p>
            </div>
            <div class="info-grid">
              <div><span>Trace ID</span><strong>{{ hermesRun.run_id }}</strong></div>
              <div><span>开始时间</span><strong>{{ formatDateTime(hermesRun.started_at) }}</strong></div>
              <div><span>结束时间</span><strong>{{ formatDateTime(hermesRun.finished_at) }}</strong></div>
              <div><span>来源</span><strong>{{ resolveRunSourceLabel(hermesRun.source) }}</strong></div>
              <div><span>模块</span><strong>{{ resolveRunModuleLabel(hermesRun) }}</strong></div>
              <div><span>当前阶段</span><strong>{{ hermesRunStatus.phaseLabel }}</strong></div>
              <div><span>当前进度</span><strong>{{ resolveRunProgress(hermesRun) }}</strong></div>
              <div><span>执行耗时</span><strong>{{ resolveRunElapsedLabel(hermesRun) }}</strong></div>
              <div><span>最后心跳</span><strong>{{ resolveHeartbeatAtText(hermesRunHeartbeat) }}</strong></div>
              <div><span>心跳状态</span><strong>{{ hermesRunHeartbeat.label }}</strong></div>
            </div>
          </article>

          <article class="panel detail-card">
            <div class="card-head">
              <h3>处理链路</h3>
              <p>按工具调用顺序查看执行链。</p>
            </div>
            <div v-if="(hermesRun.tool_calls || []).length" class="trace-steps">
              <button
                v-for="(toolCall, index) in hermesRun.tool_calls || []"
                :key="toolCall.id"
                type="button"
                class="trace-step"
                :class="{ active: selectedToolCall?.id === toolCall.id }"
                @click="selectedToolCallId = toolCall.id"
              >
                <span class="step-index">{{ index + 1 }}</span>
                <div class="step-copy">
                  <strong>{{ toolCall.tool_name }}</strong>
                  <span>{{ resolveToolCallMeta(toolCall) }}</span>
                </div>
                <span class="status-pill" :class="resolveToolStatusTone(toolCall.status)">
                  {{ toolCall.status }}
                </span>
              </button>
            </div>
            <div v-else class="inline-empty">
              当前暂无 ToolCall 明细。若长时间停在运行中且没有心跳，通常表示任务尚未真正进入 LightRAG 索引调用，或执行它的是旧版后端进程。
            </div>
          </article>

          <article v-if="selectedToolCall" class="panel detail-card">
            <div class="card-head">
              <h3>当前 ToolCall</h3>
              <p>查看当前工具调用的请求与返回。</p>
            </div>
            <div class="payload-grid">
              <div>
                <h4>请求参数</h4>
                <pre class="code-block">{{ formatJson(selectedToolCall.request_json) }}</pre>
              </div>
              <div>
                <h4>返回结果</h4>
                <pre class="code-block">{{ formatJson(selectedToolCall.response_json) }}</pre>
              </div>
            </div>
          </article>

          <article class="panel detail-card wide">
            <div class="card-head">
              <h3>路由上下文</h3>
              <p>保留 Hermes 路由与进度原文，便于管理员核查。</p>
            </div>
            <pre class="code-block large">{{ formatJson(hermesRun.route_json) }}</pre>
          </article>
        </div>
      </template>

      <template v-else-if="isSystem && systemEntry">
        <article class="detail-hero panel">
          <div class="hero-copy">
            <div class="hero-tags">
              <span class="level-pill" :class="resolveSystemLevelTone(systemEntry.level)">
                {{ systemEntry.level }}
              </span>
              <span class="status-pill" :class="resolveSystemOutcomeTone(systemEntry.outcome)">
                {{ systemEntry.outcome }}
              </span>
            </div>
            <h2>{{ systemEntry.summary || systemEntry.message }}</h2>
            <p>{{ systemEntry.event_type }} · {{ systemEntry.logger || '未标记模块' }}</p>
          </div>
          <button class="refresh-btn" type="button" :disabled="loading" @click="loadDetail">
            <i class="mdi mdi-refresh"></i>
            <span>刷新详情</span>
          </button>
        </article>

        <div class="detail-grid">
          <article class="panel detail-card wide">
            <div class="card-head">
              <h3>解析结果</h3>
              <p>按单条系统日志提取出的结构化字段。</p>
            </div>
            <div class="info-grid">
              <div><span>发生时间</span><strong>{{ formatDateTime(systemEntry.timestamp) }}</strong></div>
              <div><span>日志来源</span><strong>{{ systemEntry.source_file }} #{{ systemEntry.line_number }}</strong></div>
              <div><span>模块</span><strong>{{ systemEntry.logger || '未标记' }}</strong></div>
              <div><span>Request ID</span><strong>{{ systemEntry.request_id || '—' }}</strong></div>
              <div><span>请求方法</span><strong>{{ systemEntry.method || '—' }}</strong></div>
              <div><span>响应状态</span><strong>{{ systemEntry.status_code ?? '—' }}</strong></div>
              <div><span>请求路径</span><strong>{{ systemEntry.path || '—' }}</strong></div>
              <div><span>处理耗时</span><strong>{{ systemEntry.duration_ms == null ? '—' : `${systemEntry.duration_ms}ms` }}</strong></div>
            </div>
          </article>

          <article class="panel detail-card">
            <div class="card-head">
              <h3>解析反馈</h3>
              <p>系统对当前日志的归类与处理建议。</p>
            </div>
            <div class="feedback-grid">
              <div><span>事件类型</span><strong>{{ systemEntry.event_type }}</strong></div>
              <div><span>解析状态</span><strong>{{ resolveSystemParseLabel(systemEntry.parse_status) }}</strong></div>
              <div><span>处理结果</span><strong>{{ systemEntry.outcome }}</strong></div>
              <div><span>建议动作</span><strong>{{ resolveSystemRecommendation(systemEntry) }}</strong></div>
            </div>
          </article>

          <article class="panel detail-card">
            <div class="card-head">
              <h3>原始日志</h3>
              <p>保留该条记录的完整原文，便于排障核对。</p>
            </div>
            <pre class="code-block large">{{ systemEntry.raw }}</pre>
          </article>
        </div>
      </template>
    </div>

    <footer class="detail-actions">
      <button class="back-action" type="button" @click="backToLogs">
        <i class="mdi mdi-arrow-left"></i>
        <span>返回系统日志</span>
      </button>
    </footer>
  </section>
</template>

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

import { fetchAgentRunDetail } from '../services/agentAssets.js'
import { fetchSystemLogEntry } from '../services/systemLogs.js'
import {
  AGENT_RUN_POLL_INTERVAL_MS,
  formatAgentRunElapsed,
  formatAgentRunProgress,
  formatDurationShort,
  resolveAgentRunHeartbeat,
  resolveAgentRunStatus
} from '../utils/agentRunMonitor.js'

const SOURCE_LABELS = {
  schedule: '定时任务',
  system_event: '系统事件',
  user_message: '用户触发'
}

const route = useRoute()
const router = useRouter()
const loading = ref(false)
const error = ref('')
const hermesRun = ref(null)
const systemEntry = ref(null)
const selectedToolCallId = ref('')
const nowTick = ref(Date.now())
let pollTimer = 0

const isHermes = computed(() => route.params.logKind === 'hermes')
const isSystem = computed(() => route.params.logKind === 'system')
const selectedToolCall = computed(() =>
  (hermesRun.value?.tool_calls || []).find((item) => item.id === selectedToolCallId.value) || null
)
const hermesRunStatus = computed(() => resolveAgentRunStatus(hermesRun.value, nowTick.value))
const hermesRunHeartbeat = computed(() => resolveAgentRunHeartbeat(hermesRun.value, nowTick.value))
const hermesRunAlert = computed(() => {
  if (!hermesRun.value) {
    return null
  }
  if (hermesRun.value.error_message) {
    return {
      tone: 'danger',
      message: hermesRun.value.error_message
    }
  }
  if (hermesRunStatus.value.isSuspicious) {
    return {
      tone: hermesRunStatus.value.tone === 'danger' ? 'danger' : 'warning',
      message: hermesRunStatus.value.note || '当前任务长时间没有有效进展，建议检查后台执行器。'
    }
  }
  return null
})

function formatDateTime(value) {
  if (!value) return '未结束'
  const date = new Date(value)
  return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString('zh-CN', { hour12: false })
}

function formatJson(value) {
  try {
    return JSON.stringify(value || {}, null, 2)
  } catch {
    return String(value || '')
  }
}

function resolveStatusLabel(run) {
  return resolveAgentRunStatus(run, nowTick.value).label
}

function resolveStatusTone(run) {
  return resolveAgentRunStatus(run, nowTick.value).tone
}

function resolveToolStatusTone(status) {
  return status === 'succeeded' ? 'success' : status === 'failed' ? 'danger' : 'warning'
}

function resolveRunSourceLabel(source) {
  return SOURCE_LABELS[source] || source || '未标记'
}

function resolveRunModuleLabel(run) {
  const routeJson = run?.route_json || {}
  if (routeJson.job_type === 'knowledge_index_sync' || routeJson.job_type === 'llm_wiki_sync') return '\u77e5\u8bc6\u5f52\u7eb3'
  if (routeJson.selected_agent) return String(routeJson.selected_agent)
  if (routeJson.folder) return String(routeJson.folder)
  return resolveRunSourceLabel(run?.source)
}

function resolveRunTitle(run) {
  const routeJson = run?.route_json || {}
  if (routeJson.job_type === 'knowledge_index_sync' || routeJson.job_type === 'llm_wiki_sync') {
    return `\u77e5\u8bc6\u5f52\u7eb3 \u00b7 ${routeJson.folder || '\u672a\u6307\u5b9a\u76ee\u5f55'}`
  }
  return `Hermes 调用 · ${resolveRunModuleLabel(run)}`
}

function resolveRunLevel(run) {
  const progress = run?.route_json?.progress || {}
  const statusInfo = resolveAgentRunStatus(run, nowTick.value)
  if (run?.status === 'failed' || run?.error_message) return 'ERROR'
  if (statusInfo.isSuspicious) return 'WARN'
  if (run?.status === 'blocked' || Number(progress.failed_documents || 0) > 0) return 'WARN'
  return 'INFO'
}

function resolveLevelTone(level) {
  if (level === 'ERROR') return 'danger'
  if (level === 'WARN') return 'warning'
  if (level === 'INFO') return 'info'
  return 'muted'
}

function resolveRunProgress(run) {
  return formatAgentRunProgress(run)
}

function resolveSystemLevelTone(level) {
  if (level === 'ERROR' || level === 'CRITICAL') return 'danger'
  if (level === 'WARNING' || level === 'WARN') return 'warning'
  if (level === 'INFO') return 'info'
  return 'muted'
}

function resolveSystemOutcomeTone(outcome) {
  if (outcome === '失败') return 'danger'
  if (outcome === '异常' || outcome === '告警') return 'warning'
  if (outcome === '成功') return 'success'
  return 'muted'
}

function resolveSystemParseLabel(status) {
  return status === 'parsed' ? '已结构化' : '待人工核查'
}

function resolveSystemRecommendation(entry) {
  if (!entry) return '暂无'
  if (entry.outcome === '失败') return '优先排查并关联上下游日志'
  if (entry.outcome === '异常' || entry.outcome === '告警') return '建议继续关注同模块后续记录'
  if (entry.parse_status !== 'parsed') return '建议人工核对原始日志'
  return '无需额外处理'
}

function resolveRunElapsedLabel(run) {
  const elapsed = formatAgentRunElapsed(run, nowTick.value)
  if (elapsed === '—') {
    return elapsed
  }
  return run?.status === 'running' ? `已运行 ${elapsed}` : elapsed
}

function resolveHeartbeatAtText(heartbeat) {
  if (heartbeat?.at) {
    return `${formatDateTime(heartbeat.at)} · ${heartbeat.text}`
  }
  return heartbeat?.text || '—'
}

function resolveToolCallMeta(toolCall) {
  const toolType = String(toolCall?.tool_type || 'tool').trim()
  if (String(toolCall?.status || '').trim() === 'running') {
    const createdAt = new Date(toolCall?.created_at)
    if (!Number.isNaN(createdAt.getTime())) {
      return `${toolType} · 已运行 ${formatDurationShort(nowTick.value - createdAt.getTime())}`
    }
    return `${toolType} · 执行中`
  }

  const durationMs = Number(toolCall?.duration_ms || 0)
  if (durationMs > 0) {
    return `${toolType} · ${durationMs}ms`
  }
  return `${toolType} · 已结束`
}

function syncSelectedToolCall() {
  const calls = hermesRun.value?.tool_calls || []
  if (!calls.length) {
    selectedToolCallId.value = ''
    return
  }
  if (!calls.some((item) => item.id === selectedToolCallId.value)) {
    selectedToolCallId.value = calls[0].id
  }
}

function stopPolling() {
  if (pollTimer) {
    window.clearInterval(pollTimer)
    pollTimer = 0
  }
}

function syncPolling() {
  stopPolling()

  if (!isHermes.value || hermesRun.value?.status !== 'running') {
    return
  }

  pollTimer = window.setInterval(() => {
    nowTick.value = Date.now()
    if (!loading.value) {
      void loadDetail({ silent: true })
    }
  }, AGENT_RUN_POLL_INTERVAL_MS)
}

async function loadDetail(options = {}) {
  const silent = options.silent === true
  if (!silent) {
    loading.value = true
  }
  error.value = ''
  try {
    const id = String(route.params.logId || '')
    if (isHermes.value) {
      hermesRun.value = await fetchAgentRunDetail(id)
      systemEntry.value = null
      syncSelectedToolCall()
      return
    }
    if (isSystem.value) {
      systemEntry.value = await fetchSystemLogEntry(id)
      hermesRun.value = null
      return
    }
    throw new Error('不支持的日志类型。')
  } catch (nextError) {
    error.value = nextError?.message || '日志详情加载失败。'
  } finally {
    nowTick.value = Date.now()
    syncPolling()
    if (!silent) {
      loading.value = false
    }
  }
}

function backToLogs() {
  router.push({ name: 'app-settings', query: { section: 'systemLogs' } })
}

watch(
  () => [route.params.logKind, route.params.logId],
  () => {
    void loadDetail()
  }
)

onMounted(() => {
  void loadDetail()
})

onBeforeUnmount(() => {
  stopPolling()
})
</script>

<style scoped src="../assets/styles/views/log-detail-view.css"></style>
