<template>
  <div class="debug-page">
    <div class="page-title">报告智能体单步调试</div>
    <el-alert
      title="该工具仅发起临时智能体调用，不会写入或覆盖正式报告的阶段状态、输入、输出和产物。"
      type="warning"
      :closable="false"
      show-icon
    />

    <el-card class="search-card" shadow="never">
      <el-form :inline="true" @submit.native.prevent>
        <el-form-item label="报告 ID">
          <el-input v-model.trim="reportId" clearable placeholder="请输入报告 ID" style="width: 360px" @keyup.enter.native="loadReport" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="loading" @click="loadReport">加载调试数据</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <template v-if="detail">
      <el-card class="report-card" shadow="never">
        <div>报告 ID：{{ detail.reportId }}</div>
        <div class="thread">正式流程线程：{{ detail.persistedThreadId || '尚未创建' }}</div>
      </el-card>

      <el-card v-for="stage in detail.stages" :key="stage.stageNo" class="stage-card" shadow="never">
        <div class="stage-header">
          <div>
            <strong>阶段 {{ stage.stageNo }}：{{ stage.stageCode }}</strong>
            <span class="agent-key">{{ stage.agentKey || '非智能体阶段' }}</span>
          </div>
          <div>
            <el-tag size="small">正式状态：{{ stage.status }}</el-tag>
            <el-button
              v-if="stage.agentKey && stage.currentInput"
              type="primary"
              size="small"
              :loading="runningStageNo === stage.stageNo"
              @click="startStage(stage)"
            >单步触发</el-button>
            <el-tooltip v-else-if="stage.agentKey" effect="dark" :content="stage.inputError || '当前无法组装输入'">
              <el-button size="small" disabled>无法触发</el-button>
            </el-tooltip>
          </div>
        </div>

        <el-alert v-if="stage.inputError" class="input-error" type="error" :closable="false" :title="`当前输入组装失败：${stage.inputError}`" />
        <el-collapse>
          <el-collapse-item title="本次将发送的输入" name="current-input">
            <pre v-if="stage.currentInput">{{ pretty(stage.currentInput) }}</pre>
            <span v-else class="empty">当前阶段没有可组装的智能体输入。</span>
          </el-collapse-item>
          <el-collapse-item title="正式流程已保存的输入快照" name="saved-input">
            <pre v-if="stage.storedInputManifest">{{ prettyJson(stage.storedInputManifest) }}</pre>
            <span v-else class="empty">暂无</span>
          </el-collapse-item>
          <el-collapse-item title="正式流程已保存的输出" name="saved-output">
            <pre v-if="stage.storedOutputJson">{{ prettyJson(stage.storedOutputJson) }}</pre>
            <span v-else class="empty">暂无</span>
          </el-collapse-item>
        </el-collapse>
      </el-card>
    </template>

    <el-card v-if="job" class="job-card" shadow="never">
      <div class="stage-header">
        <strong>临时调试任务：{{ job.stageCode }}</strong>
        <el-tag :type="jobTagType">{{ job.status }}</el-tag>
      </div>
      <p>任务 ID：{{ job.jobId }}</p>
      <p>线程 ID：{{ job.threadId || '创建中' }}　运行 ID：{{ job.runId || '提交中' }}</p>
      <el-alert v-if="job.errorMessage" type="error" :closable="false" :title="job.errorMessage" />
      <el-collapse v-if="job.input || job.output">
        <el-collapse-item title="调试任务输入" name="job-input"><pre>{{ pretty(job.input) }}</pre></el-collapse-item>
        <el-collapse-item title="智能体原始输出" name="job-output"><pre>{{ pretty(job.output) }}</pre></el-collapse-item>
      </el-collapse>
    </el-card>
  </div>
</template>

<script>
import {
  getReportPipelineDebug,
  getReportPipelineDebugJob,
  startReportPipelineDebugStage
} from '@/api/agent'

export default {
  name: 'ReportAgentDebug',
  data () {
    return {
      reportId: '',
      loading: false,
      detail: null,
      job: null,
      runningStageNo: null,
      pollTimer: null
    }
  },
  computed: {
    jobTagType () {
      if (!this.job) return ''
      if (this.job.status === 'SUCCEEDED') return 'success'
      if (this.job.status === 'FAILED') return 'danger'
      return 'warning'
    }
  },
  beforeDestroy () {
    this.clearPoll()
  },
  methods: {
    pretty (value) {
      return value == null ? '暂无数据' : JSON.stringify(value, null, 2)
    },
    prettyJson (value) {
      try {
        return JSON.stringify(JSON.parse(value), null, 2)
      } catch (error) {
        return value
      }
    },
    showError (message) {
      this.$message.error(message || '请求失败')
    },
    async loadReport () {
      if (!/^\d+$/.test(this.reportId)) return this.showError('请输入有效的报告 ID')
      this.loading = true
      try {
        const response = await getReportPipelineDebug(this.reportId)
        if (!response || response.code !== 0) return this.showError(response && response.msg)
        this.detail = response.data
      } finally {
        this.loading = false
      }
    },
    async startStage (stage) {
      this.clearPoll()
      this.runningStageNo = stage.stageNo
      try {
        const response = await startReportPipelineDebugStage(this.detail.reportId, stage.stageNo)
        if (!response || response.code !== 0) {
          this.runningStageNo = null
          return this.showError(response && response.msg)
        }
        this.job = response.data
        this.pollJob()
      } catch (error) {
        this.runningStageNo = null
        this.showError('启动调试任务失败')
      }
    },
    async pollJob () {
      if (!this.job || !this.job.jobId) return
      try {
        const response = await getReportPipelineDebugJob(this.job.jobId)
        if (!response || response.code !== 0) {
          this.clearPoll()
          return this.showError(response && response.msg)
        }
        this.job = response.data
        if (this.job.status === 'RUNNING') {
          this.pollTimer = window.setTimeout(this.pollJob, 1500)
        } else {
          this.runningStageNo = null
          this.loadReport()
        }
      } catch (error) {
        this.clearPoll()
        this.runningStageNo = null
        this.showError('获取调试任务状态失败')
      }
    },
    clearPoll () {
      if (this.pollTimer) window.clearTimeout(this.pollTimer)
      this.pollTimer = null
    }
  }
}
</script>

<style scoped lang="scss">
.debug-page { padding: 24px; background: #f5f7fa; min-height: calc(100vh - 64px); }
.page-title { font-size: 20px; font-weight: 600; margin-bottom: 16px; color: #303133; }
.search-card, .report-card, .stage-card, .job-card { margin-top: 16px; }
.report-card { display: flex; gap: 32px; color: #606266; }
.thread { word-break: break-all; }
.stage-header { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.agent-key { margin-left: 12px; color: #909399; font-size: 13px; }
.input-error { margin: 14px 0; }
pre { margin: 0; padding: 14px; max-height: 420px; overflow: auto; background: #1e293b; color: #e2e8f0; border-radius: 4px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.empty { color: #909399; }
.job-card p { font-size: 13px; color: #606266; word-break: break-all; }
</style>
