<template>
  <article v-if="visible" class="detail-card panel risk-observation-evidence-card">
    <div class="detail-card-head">
      <div>
        <h3 class="detail-card-title-with-icon">
          <i class="mdi mdi-shield-search"></i>
          <span>风险证据链</span>
        </h3>
        <p>展示当前单据进入统一风险观察池后的评分、证据、图谱关系和反馈状态。</p>
      </div>
      <button
        class="risk-evidence-refresh"
        type="button"
        :disabled="loading"
        @click="loadObservations"
      >
        <i :class="loading ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-refresh'"></i>
        <span>刷新</span>
      </button>
    </div>

    <div v-if="loading" class="risk-evidence-state">
      <i class="mdi mdi-loading mdi-spin"></i>
      <span>正在加载风险证据链</span>
    </div>
    <div v-else-if="errorMessage" class="risk-evidence-state error">
      <i class="mdi mdi-alert-circle-outline"></i>
      <span>{{ errorMessage }}</span>
    </div>
    <template v-else-if="mainObservation">
      <div class="risk-evidence-current-head">
        <div>
          <span>当前风险观察详情</span>
          <strong>{{ mainObservation.title || formatSignal(mainObservation.riskSignal) }}</strong>
        </div>
        <em>{{ activeObservationPosition }}</em>
      </div>

      <div
        :id="detailRegionId"
        class="risk-evidence-detail-region"
        role="region"
        aria-live="polite"
      >
        <div class="risk-evidence-summary">
          <div class="risk-evidence-score" :class="mainObservation.riskLevel">
            <strong>{{ mainObservation.riskScore }}</strong>
            <span>{{ formatRiskLevel(mainObservation.riskLevel) }}</span>
          </div>
          <div class="risk-evidence-copy">
            <h4>{{ mainObservation.title || formatSignal(mainObservation.riskSignal) }}</h4>
            <p>{{ mainObservation.description || '暂无风险描述。' }}</p>
            <div class="risk-evidence-meta">
              <span>{{ formatSource(mainObservation.source) }}</span>
              <span>{{ mainObservation.algorithmVersion || '未记录算法版本' }}</span>
              <span>{{ formatFeedbackStatus(mainObservation.feedbackStatus) }}</span>
            </div>
          </div>
        </div>

        <div class="risk-evidence-grid">
          <section class="risk-evidence-section">
            <span class="risk-evidence-section-title">贡献分</span>
            <div class="risk-score-list">
              <div v-for="item in scoreItems" :key="item.key" class="risk-score-row">
                <span>{{ item.label }}</span>
                <i><b :style="{ width: item.width }"></b></i>
                <strong>{{ item.value }}</strong>
              </div>
            </div>
          </section>

          <section class="risk-evidence-section">
            <span class="risk-evidence-section-title">证据</span>
            <ul v-if="evidenceRows.length" class="risk-evidence-list">
              <li v-for="item in evidenceRows" :key="item.key">
                <strong>{{ item.title }}</strong>
                <span>{{ item.detail }}</span>
              </li>
            </ul>
            <p v-else class="risk-evidence-empty">暂无证据明细。</p>
          </section>

          <section class="risk-evidence-section">
            <span class="risk-evidence-section-title">图谱关系</span>
            <div class="risk-chip-list">
              <span v-for="item in graphItems" :key="item">{{ item }}</span>
              <em v-if="!graphItems.length">暂无图谱关系。</em>
            </div>
          </section>

          <section class="risk-evidence-section">
            <span class="risk-evidence-section-title">基线与建议</span>
            <div class="risk-chip-list">
              <span v-for="item in baselineAndDecisionItems" :key="item">{{ item }}</span>
              <em v-if="!baselineAndDecisionItems.length">暂无基线或建议动作。</em>
            </div>
          </section>

          <section class="risk-evidence-section">
            <span class="risk-evidence-section-title">制度与相似案例</span>
            <div class="risk-chip-list">
              <span v-for="item in policyAndSimilarItems" :key="item">{{ item }}</span>
              <em v-if="!policyAndSimilarItems.length">暂无制度引用或相似案例。</em>
            </div>
          </section>

          <section class="risk-evidence-section">
            <span class="risk-evidence-section-title">反馈历史</span>
            <ul v-if="feedbackRows.length" class="risk-evidence-list">
              <li v-for="item in feedbackRows" :key="item.key">
                <strong>{{ item.title }}</strong>
                <span>{{ item.detail }}</span>
              </li>
            </ul>
            <p v-else class="risk-evidence-empty">暂无人工反馈。</p>
          </section>
        </div>
      </div>

      <div v-if="observations.length > 1" class="risk-observation-list">
        <button
          v-for="(item, index) in observations"
          :key="observationIdentity(item, index)"
          type="button"
          class="risk-observation-row"
          :class="{ active: isActiveObservation(item, index) }"
          :aria-pressed="isActiveObservation(item, index)"
          :aria-controls="detailRegionId"
          @click="selectObservation(item, index)"
        >
          <span>{{ formatRiskLevel(item.riskLevel) }}</span>
          <strong>{{ item.title || formatSignal(item.riskSignal) }}</strong>
          <em>{{ item.riskScore }}</em>
        </button>
      </div>
    </template>
  </article>
</template>

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

import { fetchClaimRiskObservations } from '../../services/riskObservations.js'

const props = defineProps({
  claimId: { type: String, default: '' }
})

const observations = ref([])
const loading = ref(false)
const errorMessage = ref('')
const activeObservationKey = ref('')
const detailRegionId = 'risk-observation-active-detail'
let loadSequence = 0

const visible = computed(() =>
  loading.value || Boolean(errorMessage.value) || observations.value.length > 0
)
const mainObservation = computed(() => {
  if (!observations.value.length) {
    return null
  }
  return (
    observations.value.find((item, index) => isActiveObservation(item, index))
    || observations.value[0]
  )
})
const activeObservationPosition = computed(() => {
  if (observations.value.length <= 1) {
    return '单条观察'
  }
  const activeIndex = observations.value.findIndex((item, index) =>
    isActiveObservation(item, index)
  )
  return activeIndex >= 0 ? `${activeIndex + 1} / ${observations.value.length}` : '未选择'
})
const scoreItems = computed(() => {
  const scores = mainObservation.value?.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}%`
    }
  })
})
const evidenceRows = computed(() =>
  (mainObservation.value?.evidence || []).slice(0, 6).map((item, index) => ({
    key: `${item.code || item.title || index}`,
    title: String(item.title || item.code || item.source || `证据 ${index + 1}`).trim(),
    detail: String(item.detail || item.message || item.summary || '').trim() || '已记录证据。'
  }))
)
const graphItems = computed(() => [
  ...(mainObservation.value?.graphNodeKeys || []).slice(0, 4),
  ...(mainObservation.value?.graphEdgeKeys || []).slice(0, 4)
].map(formatChipValue).filter(Boolean))
const baselineAndDecisionItems = computed(() => [
  ...formatRecordItems(mainObservation.value?.baseline, '基线'),
  ...formatRecordItems(mainObservation.value?.decisionTrace, '建议')
])
const policyAndSimilarItems = computed(() => [
  ...(mainObservation.value?.policyRefs || [])
    .map(formatChipValue)
    .filter(Boolean)
    .map((item) => `制度：${item}`),
  ...(mainObservation.value?.similarCaseClaimIds || [])
    .map(formatChipValue)
    .filter(Boolean)
    .map((item) => `相似案例：${item}`)
])
const feedbackRows = computed(() =>
  (mainObservation.value?.feedbackItems || []).slice(0, 5).map((item, index) => {
    const feedbackType = item.feedbackType || item.feedback_type || item.type
    const actor = String(item.actor || item.createdBy || item.created_by || '未记录人员').trim()
    const createdAt = String(item.createdAt || item.created_at || '').trim()
    const comment = String(item.comment || item.remark || item.message || '').trim()
    return {
      key: `${item.id || createdAt || index}`,
      title: `${formatFeedbackType(feedbackType)} · ${actor}`,
      detail: [comment || '已记录反馈。', createdAt].filter(Boolean).join(' · ')
    }
  })
)

watch(
  () => props.claimId,
  () => {
    void loadObservations()
  },
  { immediate: true }
)

async function loadObservations() {
  const claimId = String(props.claimId || '').trim()
  const sequence = ++loadSequence
  errorMessage.value = ''
  if (!claimId) {
    observations.value = []
    activeObservationKey.value = ''
    loading.value = false
    return
  }

  loading.value = true
  try {
    const payload = await fetchClaimRiskObservations(claimId)
    if (sequence !== loadSequence) {
      return
    }
    observations.value = payload
    activeObservationKey.value = observationIdentity(payload[0], 0)
  } catch (error) {
    if (sequence === loadSequence) {
      observations.value = []
      activeObservationKey.value = ''
      errorMessage.value = error?.message || '风险证据链加载失败。'
    }
  } finally {
    if (sequence === loadSequence) {
      loading.value = false
    }
  }
}

function observationIdentity(item, index = -1) {
  const explicitKey = String(item?.observationKey || item?.id || '').trim()
  if (explicitKey) {
    return explicitKey
  }
  return [
    item?.claimId,
    item?.riskSignal,
    item?.createdAt,
    index >= 0 ? index : ''
  ].map((value) => String(value || '').trim()).filter(Boolean).join(':')
}

function isActiveObservation(item, index = -1) {
  return observationIdentity(item, index) === activeObservationKey.value
}

function selectObservation(item, index = -1) {
  const key = observationIdentity(item, index)
  if (key) {
    activeObservationKey.value = key
  }
}

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)
    .slice(0, 6)
    .map(([key, item]) => `${prefix}：${key}=${formatChipValue(item)}`)
    .filter(Boolean)
}

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

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

function formatSource(value) {
  const labels = {
    financial_risk_graph: '风险图谱',
    rule_center: '规则中心'
  }
  return labels[String(value || '').trim()] || '风险观察池'
}

function formatFeedbackType(value) {
  const labels = {
    confirm: '确认风险',
    confirmed: '确认风险',
    false_positive: '标记误报',
    ignore: '忽略',
    ignored: '忽略',
    resolve: '已处理',
    resolved: '已处理',
    comment: '备注'
  }
  return labels[String(value || '').trim()] || '人工反馈'
}

function formatFeedbackStatus(value) {
  const labels = {
    confirmed: '已确认',
    false_positive: '已标记误报',
    ignored: '已忽略',
    resolved: '已处理',
    unreviewed: '未复核'
  }
  return labels[String(value || '').trim()] || '未复核'
}
</script>

<style scoped src="../../assets/styles/components/risk-observation-evidence-card.css"></style>
