<template>
  <!-- F-AiNodeSelfReview: 任务产出 + AI 自审结果展示 -->
  <!-- 仅当 output_json 存在(经 AiNode 写产出/自审后由 df-data-changed 自动刷新出现) -->
  <!-- 从 TaskDetail.vue 抽出(L131-144 模板 + L214-262 脚本 + L643-670 样式),零行为变更。 -->
  <!-- 自包含:JSON 解析 / Markdown 渲染(复用 useMarkdown 模块单例)/ review verdict 计算 / i18n 全部内聚。 -->
  <div v-if="parsedOutput" class="info-item info-block output-block">
    <span class="label">{{ $t('taskDetail.output') }}</span>
    <div class="value output-body">
      <!-- AI 自审结论卡(若有 review 子字段) -->
      <div v-if="parsedOutput.review" class="review-card" :class="reviewVerdictClass">
        <span class="review-verdict">{{ reviewVerdictLabel }}</span>
        <span v-if="parsedOutput.review.summary" class="review-summary">{{ parsedOutput.review.summary }}</span>
        <ul v-if="reviewSuggestions.length" class="review-suggestions">
          <li v-for="(s, i) in reviewSuggestions" :key="i">{{ s }}</li>
        </ul>
      </div>
      <!-- AI 产出正文(Markdown 渲染,复用 useRendered 单例渲染器) -->
      <div v-if="parsedOutput.text" class="output-text ai-md" v-html="renderedOutput"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRendered } from '@/composables/useMarkdown'

// ============================================================
// F-AiNodeSelfReview: output_json 解析 + AI 产出 Markdown 渲染
// ------------------------------------------------------------
// output_json schema(与 df-nodes ai_node.rs 写产出现对齐):
//   { text, model?, usage?, review?: { verdict: 'pass'|'fail'|'unknown', summary?, suggestions? } }
// parsedOutput try/catch: JSON.parse 边界必要兜底(LLM 自审输出可能不合规/老数据格式漂移),
// 解析失败返回 null → v-if 守卫整块不渲染(不裸显报错)。
interface TaskOutputReview {
  verdict?: string
  summary?: string
  suggestions?: unknown
}
interface TaskOutput {
  text?: string
  model?: string
  usage?: unknown
  review?: TaskOutputReview
}

const props = defineProps<{
  // task.output_json 原始字符串;空值/解析失败时整卡不渲染
  outputJson?: string
}>()

const { t } = useI18n()

const parsedOutput = computed<TaskOutput | null>(() => {
  const raw = props.outputJson
  if (!raw) return null
  try {
    return JSON.parse(raw) as TaskOutput
  } catch {
    return null
  }
})
// AI 产出正文渲染(复用模块单例渲染器,与其他视图共享 marked/DOMPurify/缓存)
const { rendered: renderedOutput } = useRendered(
  () => parsedOutput.value?.text ?? '',
)
// review.verdict 红绿标:pass→绿(success),fail→红(danger),未知/缺失→灰(dim)
const reviewVerdictClass = computed(() => {
  const v = parsedOutput.value?.review?.verdict
  if (v === 'pass') return 'review-pass'
  if (v === 'fail') return 'review-fail'
  return 'review-unknown'
})
// review.verdict 标签(pass/fail/unknown 走 i18n,异常值兜底 unknown)
const reviewVerdictLabel = computed(() => {
  const v = parsedOutput.value?.review?.verdict
  if (v === 'pass') return t('taskDetail.review.pass')
  if (v === 'fail') return t('taskDetail.review.fail')
  return t('taskDetail.review.unknown')
})
// review.suggestions 列表(数组守卫,非数组时返回空避免 v-for 报错)
const reviewSuggestions = computed<string[]>(() => {
  const s = parsedOutput.value?.review?.suggestions
  return Array.isArray(s) ? s.map(String) : []
})
</script>

<style scoped>
/* ===== F-AiNodeSelfReview: output_json 区块(产出 + 自审结论卡) ===== */
/* 基础布局 .info-item / .info-block / .label / .value 已收敛至全局 components.css
   (DRY 收口 B-260619)。全局类对子组件内部 DOM 生效(全局非 scoped 无渗透限制),
   故本子组件无需复制等价基础布局,仅保留本组件特有的 output/review 样式。 */

.output-block .output-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* 自审结论卡:verdict 红绿标(pass 绿 / fail 红 / unknown 灰),复用全局 --df-success/danger token */
.review-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 12px;
  border-radius: var(--df-radius-sm);
  border: 0.5px solid var(--df-border);
  font-size: 13px;
}
.review-pass { background: var(--df-success-bg); border-color: rgba(61,219,160,0.3); }
.review-fail { background: var(--df-danger-bg); border-color: rgba(240,101,101,0.3); }
.review-unknown { background: var(--df-bg-card); }
.review-verdict { font-weight: 600; }
.review-pass .review-verdict { color: var(--df-success); }
.review-fail .review-verdict { color: var(--df-danger); }
.review-unknown .review-verdict { color: var(--df-text-dim); }
.review-summary { color: var(--df-text-secondary); line-height: 1.5; }
.review-suggestions { margin: 4px 0 0; padding-left: 20px; color: var(--df-text-secondary); }
.review-suggestions li { line-height: 1.6; }
/* AI 产出正文(继承全局 .ai-md 块级样式,line-height 对齐描述) */
.output-text { line-height: 1.5; }
</style>
