<template>
  <EnterpriseDetailCard
    v-if="visible"
    class="run-products-card"
    title="本次任务产物"
    :description="productSubtitle"
  >
    <template #actions>
      <span class="edit-badge">{{ productBadge }}</span>
    </template>

    <div v-if="loading" class="run-product-state">
      <i class="mdi mdi-loading mdi-spin"></i>
      <span>正在读取本次运行产物</span>
    </div>
    <div v-else-if="errorMessage" class="run-product-state error">
      <i class="mdi mdi-alert-circle-outline"></i>
      <span>{{ errorMessage }}</span>
    </div>
    <template v-else>
      <div v-if="metrics.length" class="json-risk-meta-grid run-product-meta-grid">
        <div
          v-for="item in metrics"
          :key="item.label"
          class="json-risk-meta-item"
        >
          <span class="json-risk-meta-label">{{ item.label }}</span>
          <span class="json-risk-meta-value">{{ item.value }}</span>
        </div>
      </div>

      <section v-if="productKind === 'risk_graph'" class="run-product-section">
        <div class="run-product-section-head">
          <h4>风险观察</h4>
          <span>{{ observations.length }} 条</span>
        </div>
        <div v-if="observations.length" class="run-product-observation-list">
          <article
            v-for="item in observations"
            :key="item.observationKey || item.id"
            class="run-product-observation"
            :class="{ 'is-expanded': isActiveObservation(item) }"
            role="button"
            tabindex="0"
            @click="toggleObservation(item)"
            @keydown.enter.prevent="toggleObservation(item)"
            @keydown.space.prevent="toggleObservation(item)"
          >
            <div class="run-product-observation-head">
              <span class="risk-level-pill" :class="item.riskLevel">
                {{ formatRiskLevel(item.riskLevel) }}
              </span>
              <strong>{{ item.title || formatSignal(item.riskSignal) }}</strong>
              <b>{{ item.riskScore }}</b>
            </div>
            <p>{{ item.description || '暂无风险描述。' }}</p>
            <div class="run-product-tags">
              <span>单据：{{ item.claimNo || item.claimId || '-' }}</span>
              <span>证据：{{ (item.evidence || []).length }}</span>
              <span>图谱关系：{{ observationGraphCount(item) }}</span>
              <span>{{ item.algorithmVersion || '未记录算法版本' }}</span>
            </div>
            <div
              v-if="isActiveObservation(item)"
              class="run-product-observation-detail"
            >
              <section v-if="scoreRows(item).length">
                <span>贡献分</span>
                <div class="run-product-score-list">
                  <div v-for="score in scoreRows(item)" :key="score.key">
                    <em>{{ score.label }}</em>
                    <i><b :style="{ width: score.width }"></b></i>
                    <strong>{{ score.value }}</strong>
                  </div>
                </div>
              </section>
              <section v-if="evidenceRows(item).length">
                <span>关键证据</span>
                <ul class="run-product-evidence-list">
                  <li v-for="evidence in evidenceRows(item)" :key="evidence.key">
                    <strong>{{ evidence.title }}</strong>
                    <p>{{ evidence.detail }}</p>
                  </li>
                </ul>
              </section>
              <section v-if="observationGraphItems(item).length">
                <span>异常关系</span>
                <div class="run-product-tags">
                  <span
                    v-for="graphItem in observationGraphItems(item)"
                    :key="graphItem"
                  >
                    {{ graphItem }}
                  </span>
                </div>
              </section>
              <section v-if="observationDecisionItems(item).length">
                <span>制度与建议</span>
                <div class="run-product-tags">
                  <span
                    v-for="decisionItem in observationDecisionItems(item)"
                    :key="decisionItem"
                  >
                    {{ decisionItem }}
                  </span>
                </div>
              </section>
            </div>
          </article>
        </div>
        <p v-else class="run-product-inline-empty">本次运行没有生成新的风险观察。</p>
      </section>

      <section v-else-if="productKind === 'finance_snapshot'" class="run-product-section">
        <div class="run-product-section-head">
          <h4>财务经营快照</h4>
          <span>{{ summary.period || summary.month || '本期' }}</span>
        </div>
        <p class="run-product-copy">
          本次产物已刷新财务看板缓存，沉淀报销金额、预算使用、费用结构和高额单据等经营指标。
        </p>
      </section>

      <section v-else-if="productKind === 'reminder_scan'" class="run-product-section">
        <div class="run-product-section-head">
          <h4>提醒与待办沉淀</h4>
          <span>{{ summary.reminder_count || summary.reminders || 0 }} 条</span>
        </div>
        <p class="run-product-copy">
          本次产物已生成审批提醒、预算编制提醒、报销逾期提醒和差旅申请闭环提醒。
        </p>
      </section>

      <section v-else-if="productKind === 'risk_clue'" class="run-product-section">
        <div class="run-product-section-head">
          <h4>待复核线索</h4>
          <span>{{ riskClues.length }} 条</span>
        </div>
        <div v-if="riskClues.length" class="run-product-observation-list">
          <article
            v-for="item in riskClues"
            :key="item.clue_id || item.clueId"
            class="run-product-observation"
          >
            <div class="run-product-observation-head">
              <span class="risk-level-pill" :class="item.risk_level || item.riskLevel">
                {{ formatRiskLevel(item.risk_level || item.riskLevel) }}
              </span>
              <strong>{{ item.title || formatSignal(item.risk_signal || item.riskSignal) }}</strong>
              <b>{{ formatConfidence(item.confidence_score ?? item.confidenceScore) }}</b>
            </div>
            <p>{{ item.summary || '该线索需要人工复核事实和证据。' }}</p>
            <div class="run-product-tags">
              <span>单据：{{ item.claim_no || item.claimNo || '-' }}</span>
              <span>状态：待人工复核</span>
              <span v-if="item.observation_key || item.observationKey">
                观察：{{ item.observation_key || item.observationKey }}
              </span>
              <span v-if="item.feedback_status || item.feedbackStatus">
                反馈：{{ formatFeedbackStatus(item.feedback_status || item.feedbackStatus) }}
              </span>
              <span>规则命中：{{ (item.rule_hits || item.ruleHits || []).length }}</span>
              <span>证据：{{ (item.evidence_refs || item.evidenceRefs || []).length }}</span>
            </div>
            <p v-if="item.review_reason || item.reviewReason" class="run-product-muted-copy">
              {{ item.review_reason || item.reviewReason }}
            </p>
            <p v-if="item.next_action || item.nextAction" class="run-product-muted-copy">
              {{ item.next_action || item.nextAction }}
            </p>
          </article>
        </div>
        <p v-else class="run-product-inline-empty">本次运行没有整理出待复核线索。</p>

        <div v-if="feedbackRows.length" class="run-product-feedback-panel">
          <div class="run-product-section-head compact">
            <h4>反馈样本</h4>
            <span>{{ feedbackTotal }} 条</span>
          </div>
          <ul class="run-product-feedback-list">
            <li v-for="item in feedbackRows" :key="item.feedback_id || item.feedbackId">
              <strong>{{ formatFeedbackStatus(item.feedback_type || item.feedbackType) }}</strong>
              <span>{{ item.observation_key || item.observationKey || '未关联观察' }}</span>
              <em>{{ item.actor || '系统' }}</em>
            </li>
          </ul>
        </div>
      </section>

      <section v-else-if="productKind === 'employee_profile'" class="run-product-section">
        <div class="run-product-section-head">
          <h4>画像快照</h4>
          <span>{{ summary.algorithm_version || '算法版本未记录' }}</span>
        </div>
        <p class="run-product-copy">
          本次产物已写入员工行为画像快照，用于后续风险图谱、审批复核和员工行为基线分析。
        </p>
      </section>

      <section v-else-if="productKind === 'knowledge'" class="run-product-section">
        <div class="run-product-section-head">
          <h4>知识制度整理</h4>
          <span>{{ summary.status || '已提交' }}</span>
        </div>
        <p class="run-product-copy">
          {{ summary.summary || '知识制度整理任务已提交，后台会继续归纳文档并刷新知识索引。' }}
        </p>
        <div class="run-product-tags">
          <span>目录：{{ summary.folder || routeJson.folder || '全部知识库' }}</span>
          <span>文档：{{ documentCount }} 份</span>
          <span v-if="summary.agent_run_id">子任务：{{ summary.agent_run_id }}</span>
        </div>
      </section>
    </template>
  </EnterpriseDetailCard>
</template>

<script setup>
import { computed, ref, watch } from 'vue'

import EnterpriseDetailCard from '../shared/EnterpriseDetailCard.vue'
import { fetchRunRiskObservations } from '../../services/riskObservations.js'
import {
  extractWorkRecordToolSummary,
  resolveWorkRecordProductKind,
  resolveWorkRecordTaskLabel
} from '../../views/scripts/digitalEmployeeWorkRecordsModel.js'

const props = defineProps({
  run: { type: Object, default: null }
})

const observations = ref([])
const activeObservationKey = ref('')
const loading = ref(false)
const errorMessage = ref('')
let loadSequence = 0

const routeJson = computed(() =>
  props.run?.route_json && typeof props.run.route_json === 'object'
    ? props.run.route_json
    : {}
)
const runId = computed(() => String(props.run?.run_id || '').trim())
const productKind = computed(() => resolveWorkRecordProductKind(props.run))
const taskLabel = computed(() => resolveWorkRecordTaskLabel(props.run) || '数字员工任务')
const summary = computed(() => extractWorkRecordToolSummary(props.run))
const visible = computed(() =>
  Boolean(productKind.value || loading.value || errorMessage.value)
)
const productSubtitle = computed(() => {
  if (productKind.value === 'risk_graph') {
    return '展示本次巡检生成的风险观察、证据数量和图谱关系计数。'
  }
  if (productKind.value === 'finance_snapshot') {
    return '展示本次财务经营快照沉淀的预算、费用和报销统计。'
  }
  if (productKind.value === 'reminder_scan') {
    return '展示本次定时提醒扫描生成的待办和触达结果。'
  }
  if (productKind.value === 'employee_profile') {
    return '展示本次画像巡检写入的员工画像快照摘要。'
  }
  if (productKind.value === 'knowledge') {
    return '展示本次知识制度整理任务的入队结果与处理范围。'
  }
  if (productKind.value === 'risk_clue') {
    return '展示本次任务归集的事实、规则命中和待人工复核线索。'
  }
  return '展示本次数字员工任务产生的结构化结果。'
})
const productBadge = computed(() => {
  if (productKind.value === 'risk_graph') {
    return '风险观察'
  }
  if (productKind.value === 'finance_snapshot') {
    return '财务快照'
  }
  if (productKind.value === 'reminder_scan') {
    return '提醒事项'
  }
  if (productKind.value === 'employee_profile') {
    return '画像快照'
  }
  if (productKind.value === 'knowledge') {
    return '知识整理'
  }
  if (productKind.value === 'risk_clue') {
    return '线索归集'
  }
  return taskLabel.value
})
const riskClues = computed(() =>
  Array.isArray(summary.value.risk_clues) ? summary.value.risk_clues : []
)
const feedbackSummary = computed(() =>
  summary.value.feedback_summary && typeof summary.value.feedback_summary === 'object'
    ? summary.value.feedback_summary
    : {}
)
const feedbackRows = computed(() =>
  Array.isArray(feedbackSummary.value.recent) ? feedbackSummary.value.recent.slice(0, 6) : []
)
const feedbackTotal = computed(() => Number(feedbackSummary.value.total || feedbackRows.value.length || 0))
const documentCount = computed(() =>
  Array.isArray(summary.value.document_ids) ? summary.value.document_ids.length : 0
)
const metrics = computed(() => {
  const payload = summary.value || {}
  if (productKind.value === 'risk_graph') {
    return [
      buildMetric('扫描单据', payload.scanned_claim_count),
      buildMetric('风险观察', payload.risk_observation_count ?? observations.value.length),
      buildMetric('图谱节点', payload.graph_node_count),
      buildMetric('图谱关系', payload.graph_edge_count)
    ]
  }
  if (productKind.value === 'finance_snapshot') {
    return [
      buildMetric('报销单数', payload.claim_count ?? payload.claims ?? payload.total_claims),
      buildMetric(
        '报销金额',
        formatMoney(payload.claim_amount ?? payload.reimbursement_amount ?? payload.total_amount)
      ),
      buildMetric('预算使用率', formatPercent(payload.budget_usage_rate ?? payload.budget_rate)),
      buildMetric('高额单据', payload.high_value_claim_count ?? payload.high_amount_claims)
    ]
  }
  if (productKind.value === 'reminder_scan') {
    return [
      buildMetric('提醒人数', payload.recipient_count),
      buildMetric('提醒事项', payload.reminder_count),
      buildMetric('待审批', payload.approval_pending_count),
      buildMetric('逾期报销', payload.reimbursement_overdue_count)
    ]
  }
  if (productKind.value === 'employee_profile') {
    return [
      buildMetric('目标员工', payload.target_employee_count),
      buildMetric('画像快照', payload.snapshot_count),
      buildMetric('重点关注', payload.high_attention_employee_count),
      buildMetric('窗口期', formatWindowDays(payload.window_days))
    ]
  }
  if (productKind.value === 'knowledge') {
    return [
      buildMetric('处理目录', payload.folder || routeJson.value.folder || '全部知识库'),
      buildMetric('目标文档', documentCount.value),
      buildMetric('复用任务', payload.reused ? '是' : '否'),
      buildMetric('后台 Run ID', payload.agent_run_id || '-')
    ]
  }
  if (productKind.value === 'risk_clue') {
    return [
      buildMetric('事实', payload.fact_count ?? (payload.facts || []).length),
      buildMetric('规则命中', payload.rule_hit_count ?? (payload.rule_hits || []).length),
      buildMetric('待复核线索', payload.risk_clue_count ?? riskClues.value.length),
      buildMetric('反馈样本', feedbackTotal.value)
    ]
  }
  return []
})

watch(
  () => [runId.value, productKind.value],
  () => {
    void loadProducts()
  },
  { immediate: true }
)

async function loadProducts() {
  const currentRunId = runId.value
  const sequence = ++loadSequence
  errorMessage.value = ''

  if (productKind.value !== 'risk_graph') {
    observations.value = []
    loading.value = false
    return
  }

  if (!currentRunId) {
    observations.value = []
    loading.value = false
    return
  }

  loading.value = true
  try {
    const payload = await fetchRunRiskObservations(currentRunId)
    if (sequence !== loadSequence) {
      return
    }
    observations.value = payload
    activeObservationKey.value = payload[0]?.observationKey || payload[0]?.id || ''
  } catch (error) {
    if (sequence === loadSequence) {
      observations.value = []
      activeObservationKey.value = ''
      errorMessage.value = error?.message || '本次运行产物加载失败。'
    }
  } finally {
    if (sequence === loadSequence) {
      loading.value = false
    }
  }
}

function buildMetric(label, value) {
  return {
    label,
    value: formatMetricValue(value)
  }
}

function formatMetricValue(value) {
  if (Array.isArray(value)) {
    return value.length ? value.join(' / ') : '-'
  }
  if (value === null || value === undefined || value === '') {
    return '-'
  }
  return String(value)
}

function formatWindowDays(value) {
  const days = Array.isArray(value) ? value : []
  return days.length ? days.map((item) => `${item}天`).join(' / ') : '-'
}

function formatMoney(value) {
  const amount = Number(value)
  if (!Number.isFinite(amount)) {
    return '-'
  }
  return `¥${amount.toLocaleString('zh-CN', { maximumFractionDigits: 0 })}`
}

function formatPercent(value) {
  const numericValue = Number(value)
  if (!Number.isFinite(numericValue)) {
    return '-'
  }
  const percent = numericValue > 1 ? numericValue : numericValue * 100
  return `${Math.round(percent)}%`
}

function observationGraphCount(item) {
  return (item.graphNodeKeys || []).length + (item.graphEdgeKeys || []).length
}

function observationKey(item) {
  return String(item?.observationKey || item?.id || '').trim()
}

function isActiveObservation(item) {
  return observationKey(item) === activeObservationKey.value
}

function toggleObservation(item) {
  const key = observationKey(item)
  activeObservationKey.value = activeObservationKey.value === key ? '' : key
}

function scoreRows(item) {
  const scores = item?.contributionScores || {}
  return Object.entries(scores).map(([key, value]) => {
    const numericValue = Math.max(0, Math.min(Number(value || 0), 100))
    return {
      key,
      label: formatScoreLabel(key),
      value: Math.round(numericValue),
      width: `${numericValue}%`
    }
  })
}

function evidenceRows(item) {
  return (item?.evidence || []).slice(0, 4).map((evidence, index) => ({
    key: `${evidence.code || evidence.title || index}`,
    title: String(evidence.title || evidence.code || evidence.source || `证据 ${index + 1}`).trim(),
    detail: String(evidence.detail || evidence.message || evidence.summary || '').trim() || '已记录证据。'
  }))
}

function observationGraphItems(item) {
  return [
    ...(item?.graphNodeKeys || []).slice(0, 5).map((value) => `节点：${formatChipValue(value)}`),
    ...(item?.graphEdgeKeys || []).slice(0, 5).map((value) => `关系：${formatChipValue(value)}`)
  ].filter(Boolean)
}

function observationDecisionItems(item) {
  return [
    ...(item?.policyRefs || []).slice(0, 4).map((value) => `制度：${formatChipValue(value)}`),
    ...(item?.similarCaseClaimIds || []).slice(0, 4).map((value) => `相似案例：${formatChipValue(value)}`),
    ...formatRecordItems(item?.decisionTrace, '建议').slice(0, 4)
  ].filter(Boolean)
}

function formatScoreLabel(value) {
  const labels = {
    S_rule: '规则命中',
    S_anomaly: '画像偏离',
    S_graph: '图谱异常',
    S_policy: '制度约束',
    S_history: '历史反馈'
  }
  return labels[value] || value
}

function formatChipValue(value) {
  if (typeof value === 'string') {
    return value.trim()
  }
  if (value && typeof value === 'object') {
    return String(value.key || value.edge_key || value.node_key || JSON.stringify(value)).trim()
  }
  return String(value || '').trim()
}

function formatRecordItems(value, prefix) {
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    return []
  }
  return Object.entries(value)
    .map(([key, item]) => `${prefix}：${key}=${formatChipValue(item)}`)
    .filter(Boolean)
}

function formatRiskLevel(value) {
  const labels = {
    critical: '重大风险',
    high: '高风险',
    medium: '中风险',
    low: '低风险'
  }
  return labels[String(value || '').trim()] || '未知风险'
}

function formatConfidence(value) {
  const numericValue = Number(value || 0)
  if (!Number.isFinite(numericValue) || numericValue <= 0) {
    return '-'
  }
  return `${Math.round(numericValue * 100)}%`
}

function formatFeedbackStatus(value) {
  const labels = {
    unreviewed: '未复核',
    pending_review: '待复核',
    confirm: '已确认',
    confirmed: '已确认',
    false_positive: '误报',
    ignore: '已忽略',
    ignored: '已忽略',
    resolve: '已处理',
    resolved: '已处理',
    comment: '备注'
  }
  const normalized = String(value || '').trim()
  return labels[normalized] || normalized || '未复核'
}

function formatSignal(value) {
  const labels = {
    duplicate_invoice: '重复发票',
    split_billing: '拆分报销',
    frequent_small_claims: '高频小额',
    location_mismatch: '地点不一致',
    amount_outlier: '金额异常',
    preapproval_absent: '缺少事前申请'
  }
  const normalized = String(value || '').trim()
  return labels[normalized] || normalized.replace(/_/g, ' ') || '未知风险'
}
</script>

<style scoped src="../../assets/styles/components/digital-employee-run-products.css"></style>
