import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

import {
  createRiskDispositionRequestId,
  normalizeRiskDisposition,
  normalizeRiskObservation
} from '../src/services/riskObservations.js'

const evidenceCard = readFileSync(
  fileURLToPath(new URL('../src/components/travel/RiskObservationEvidenceCard.vue', import.meta.url)),
  'utf8'
)

test('risk observation normalizes persisted json evidence and typed disposition', () => {
  const observation = normalizeRiskObservation({
    id: 'risk-1',
    contribution_scores_json: { S_rule: 90 },
    evidence_json: [{ title: '重复票据' }],
    graph_node_keys_json: ['claim:1'],
    similar_case_claim_ids_json: ['redacted-for-reviewer-only'],
    decision_trace_json: { action: 'manual_review' },
    disposition: {
      id: 'disposition-1',
      observation_id: 'risk-1',
      adjudication: 'confirmed',
      lifecycle_status: 'remediation_in_progress',
      version: 2,
      available_actions: ['request_waiver'],
      read_only_reason: null,
      events: [{ id: 'event-1', action: 'confirm', version: 1 }]
    }
  })

  assert.equal(observation.contributionScores.S_rule, 90)
  assert.equal(observation.evidence[0].title, '重复票据')
  assert.deepEqual(observation.graphNodeKeys, ['claim:1'])
  assert.equal(observation.decisionTrace.action, 'manual_review')
  assert.equal(observation.disposition.lifecycleStatus, 'remediation_in_progress')
  assert.deepEqual(observation.disposition.availableActions, ['request_waiver'])
  assert.equal(observation.disposition.readOnlyReason, '')
  assert.equal(observation.disposition.events[0].action, 'confirm')
})

test('risk disposition normalizer rejects absent projection and keeps version', () => {
  assert.equal(normalizeRiskDisposition(null), null)
  assert.equal(normalizeRiskDisposition({}), null)
  assert.equal(normalizeRiskDisposition({ id: 'd1', version: 4 }).version, 4)
})

test('risk evidence card exposes typed actions and never offers direct approval', () => {
  assert.match(evidenceCard, /executeRiskDispositionAction/)
  assert.match(evidenceCard, /确认风险/)
  assert.match(evidenceCard, /标记误报/)
  assert.match(evidenceCard, /请求补材料/)
  assert.match(evidenceCard, /启动整改/)
  assert.match(evidenceCard, /申请豁免/)
  assert.match(evidenceCard, /确认已解决/)
  assert.match(evidenceCard, /expectedVersion: currentDisposition\.value\.version/)
  assert.doesNotMatch(evidenceCard, /自动审批|直接通过|batchApprove/)
  assert.match(evidenceCard, /normalizeRiskDispositionError/)
  assert.match(evidenceCard, /currentDisposition\.value\.availableActions/)
  assert.doesNotMatch(evidenceCard, /roleCodes|role_codes|isAdmin|is_admin/)
})

test('risk action request ids bind action and observation', () => {
  const requestId = createRiskDispositionRequestId('confirm', 'risk-1')
  assert.match(requestId, /^risk:confirm:risk-1:/)
})
