export const RISK_RULE_CREATE_DOMAIN_OPTIONS = [
  { value: 'expense', label: '报销' },
  { value: 'ar', label: '应收' },
  { value: 'ap', label: '应付' }
]

export const RISK_RULE_EXPENSE_CATEGORY_OPTIONS = [
  { value: 'all', label: '全部' },
  { value: 'travel', label: '差旅费' },
  { value: 'meal', label: '业务招待费' },
  { value: 'office', label: '办公用品费' },
  { value: 'communication', label: '通信费' }
]

export const RISK_RULE_BUSINESS_STAGE_OPTIONS = [
  { value: 'expense_application', label: '费用申请' },
  { value: 'reimbursement', label: '费用报销' }
]

export const RISK_RULE_LEVEL_OPTIONS = [
  { value: 'low', label: '低风险' },
  { value: 'medium', label: '中风险' },
  { value: 'high', label: '高风险' },
  { value: 'critical', label: '极高风险' }
]

const RISK_LEVEL_LABELS = {
  low: '低风险',
  medium: '中风险',
  high: '高风险',
  critical: '极高风险'
}

const RISK_SCORE_LEVEL_LABELS = RISK_LEVEL_LABELS

const CITY_ROUTE_CONDITION_SUMMARY =
  '判断公式：A=交通票行程城市∪住宿发票城市，B=申报目的地∪明细发生地点，C=员工常驻地/合理出发地。若A或B为空则要求补充识别；若A与B无交集且无合理说明，或票据路线中存在不属于B∪C的额外城市，则命中目的地不一致/中途周转异常风险。'

const CITY_ROUTE_FLOW_DECISION =
  '附件城市是否覆盖申报行程，且票据路线是否出现申报目的地和常驻地之外的中转城市'

const CITY_ROUTE_FLOW_EVIDENCE =
  '读取员工常驻地、申报目的地、明细发生地点、交通票行程城市、住宿发票城市和报销事由'

const CITY_ROUTE_SEMANTIC_TYPES = new Set([
  'travel_city_consistency',
  'travel_route_city_consistency'
])

export function createDefaultRiskRuleForm() {
  return {
    business_domain: 'expense',
    business_stage: 'reimbursement',
    expense_category: 'all',
    rule_title: '',
    requires_attachment: false,
    natural_language: ''
  }
}

export function normalizeRiskRuleText(value) {
  return String(value || '').trim()
}

export function formatRiskRuleFieldDisplay(field) {
  const key = normalizeRiskRuleText(field?.key)
  const label = normalizeRiskRuleText(field?.label || key)
  if (label && key && label !== key) {
    return `${label}[${key}]`
  }
  return label || key
}

export function resolveRiskRuleSeverity(payload) {
  const scoreLevel = resolveRiskRuleScoreLevel(payload)
  if (scoreLevel) {
    return scoreLevel
  }
  const outcomes = payload && typeof payload === 'object' ? payload.outcomes || {} : {}
  const fail = outcomes && typeof outcomes.fail === 'object' ? outcomes.fail : {}
  const severity = normalizeRiskRuleText(fail.severity || payload?.severity).toLowerCase()
  return Object.prototype.hasOwnProperty.call(RISK_LEVEL_LABELS, severity) ? severity : 'medium'
}

export function resolveRiskRuleSeverityLabel(payload) {
  return RISK_LEVEL_LABELS[resolveRiskRuleSeverity(payload)] || '中风险'
}

export function resolveRiskRuleScore(payload, fallbackConfig = {}) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  const outcomes = payload && typeof payload === 'object' ? payload.outcomes || {} : {}
  const fail = outcomes && typeof outcomes.fail === 'object' ? outcomes.fail : {}
  const candidates = [
    metadata.risk_score,
    payload?.risk_score,
    fail.risk_score,
    fallbackConfig?.risk_score,
    fallbackConfig?.riskScore
  ]
  for (const value of candidates) {
    const score = Number(value)
    if (Number.isFinite(score)) {
      return Math.max(0, Math.min(100, Math.round(score)))
    }
  }
  return null
}

export function resolveRiskRuleScoreLevel(payload, fallbackConfig = {}) {
  const score = resolveRiskRuleScore(payload, fallbackConfig)
  if (score === null) {
    return ''
  }
  if (score <= 30) return 'low'
  if (score <= 60) return 'medium'
  if (score <= 80) return 'high'
  return 'critical'
}

export function resolveRiskRuleScoreLabel(payload, fallbackConfig = {}) {
  const level = resolveRiskRuleScoreLevel(payload, fallbackConfig)
  return level ? RISK_SCORE_LEVEL_LABELS[level] : '待计算'
}

export function resolveRiskRuleScoreDetail(payload, fallbackConfig = {}) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  const detail =
    metadata.risk_score_detail ||
    payload?.risk_score_detail ||
    fallbackConfig?.risk_score_detail ||
    fallbackConfig?.riskScoreDetail
  return detail && typeof detail === 'object' ? detail : null
}

export function resolveRiskRuleFields(payload) {
  const inputs = payload && typeof payload === 'object' ? payload.inputs || {} : {}
  const fieldRows = Array.isArray(inputs.fields) ? inputs.fields : []
  if (fieldRows.length) {
    return fieldRows
      .map((item) => ({
        key: normalizeRiskRuleText(item?.key),
        label: normalizeRiskRuleText(item?.label || item?.key),
        display: formatRiskRuleFieldDisplay(item),
        source: normalizeRiskRuleText(item?.source),
        type: normalizeRiskRuleText(item?.type)
      }))
      .filter((item) => item.key || item.label)
  }

  return Object.entries(inputs)
    .map(([label, key]) => ({
      key: normalizeRiskRuleText(key),
      label: normalizeRiskRuleText(label),
      display: formatRiskRuleFieldDisplay({ key, label }),
      source: '',
      type: ''
    }))
    .filter((item) => item.key || item.label)
}

export function buildRiskRuleFieldSummary(fields) {
  const labels = fields.map(formatRiskRuleFieldDisplay).filter(Boolean)
  if (!labels.length) {
    return '未识别字段'
  }
  if (labels.length <= 4) {
    return labels.join('、')
  }
  return `${labels.slice(0, 4).join('、')} 等 ${labels.length} 项`
}

export function resolveRiskRuleCreatedAt(payload, fallback) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  return normalizeRiskRuleText(metadata.created_at || fallback)
}

export function formatRiskRuleAge(value) {
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) {
    return '未记录'
  }
  const diffMs = Date.now() - date.getTime()
  if (diffMs < 0) {
    return '刚刚创建'
  }
  const minutes = Math.floor(diffMs / 60000)
  if (minutes < 1) {
    return '刚刚创建'
  }
  if (minutes < 60) {
    return `${minutes} 分钟`
  }
  const hours = Math.floor(minutes / 60)
  if (hours < 24) {
    return `${hours} 小时`
  }
  const days = Math.floor(hours / 24)
  if (days < 30) {
    return `${days} 天`
  }
  const months = Math.floor(days / 30)
  if (months < 12) {
    return `${months} 个月`
  }
  return `${Math.floor(months / 12)} 年`
}

export function resolveRiskRuleBusinessDescription(payload, fallback) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  return (
    normalizeRiskRuleText(metadata.business_explanation) ||
    normalizeRiskRuleText(payload?.description) ||
    normalizeRiskRuleText(fallback)
  )
}

export function resolveRiskRuleFlowDiagramSvg(payload) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  const svg =
    normalizeRiskRuleText(payload?.flow_diagram_svg) ||
    normalizeRiskRuleText(metadata.flow_diagram_svg)
  if (svg && !svg.includes('data-risk-flow-detail="logic-v2"')) {
    return ''
  }
  if (isCityRouteConsistencyPayload(payload) && svg.includes('风险关键词')) {
    return ''
  }
  return svg
}

export function resolveRiskRuleConditionSummary(payload) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  const params = payload && typeof payload === 'object' ? payload.params || {} : {}
  if (isCityRouteConsistencyPayload(payload)) {
    return CITY_ROUTE_CONDITION_SUMMARY
  }
  return (
    normalizeRiskRuleText(metadata.condition_summary) ||
    normalizeRiskRuleText(params.condition_summary) ||
    '根据规则字段判断是否命中风险'
  )
}

export function resolveRiskRuleFlow(payload, fields) {
  const metadata = payload && typeof payload === 'object' ? payload.metadata || {} : {}
  const flowModel = resolveFlowModel(payload)
  const flow = metadata && typeof metadata.flow === 'object' ? metadata.flow : {}
  const fieldSummary = buildRiskRuleFieldSummary(fields)
  const conditionSummary = resolveRiskRuleConditionSummary(payload)
  const severityLabel = resolveRiskRuleSeverityLabel(payload)
  const isCityRouteRule = isCityRouteConsistencyPayload(payload)
  const modelNodes = Array.isArray(flowModel?.nodes) ? flowModel.nodes : []
  const startNode = modelNodes.find((node) => node?.type === 'start')
  const evidenceNode = modelNodes.find((node) => node?.type === 'evidence')
  const riskNode = modelNodes.find((node) => node?.type === 'risk')
  const passNode = modelNodes.find((node) => node?.type === 'pass')

  return {
    start: normalizeRiskRuleText(startNode?.description) || normalizeRiskRuleText(flow.start) || '业务单据提交',
    evidence: normalizeRiskRuleText(evidenceNode?.description) || (isCityRouteRule
      ? CITY_ROUTE_FLOW_EVIDENCE
      : normalizeRiskRuleText(flow.evidence) || `读取 ${fieldSummary}`),
    decision: isCityRouteRule
      ? CITY_ROUTE_FLOW_DECISION
      : normalizeRiskRuleText(flow.decision) || conditionSummary,
    basis: conditionSummary,
    ...resolveRiskRuleFlowDetails(payload, fields, flowModel),
    flowModel,
    pass: normalizeRiskRuleText(passNode?.description) || normalizeRiskRuleText(flow.pass) || '未命中风险，继续流转',
    fail: normalizeRiskRuleText(riskNode?.description) || normalizeRiskRuleText(flow.fail) || `命中${severityLabel}，进入人工复核`
  }
}

function resolveRiskRuleFlowDetails(payload, fields, flowModel = null) {
  const modelDetails = resolveFlowModelDetails(flowModel, fields)
  if (modelDetails) {
    return modelDetails
  }
  const params = payload && typeof payload === 'object' && payload.params && typeof payload.params === 'object'
    ? payload.params
    : {}
  const ruleIr = params.rule_ir && typeof params.rule_ir === 'object' ? params.rule_ir : {}
  const facts = Array.isArray(ruleIr.facts) ? buildFactLines(ruleIr.facts, fields) : buildFieldFactLines(fields)
  const conditions = buildConditionLines(params, fields)
  const hitLogic = formatHitLogic(params.hit_logic) || normalizeRiskRuleText(params.formula)
  return {
    facts,
    conditions,
    hitLogic
  }
}

function resolveFlowModel(payload) {
  if (!payload || typeof payload !== 'object') {
    return null
  }
  const metadata = payload.metadata && typeof payload.metadata === 'object' ? payload.metadata : {}
  const flowModel = payload.flow_model && typeof payload.flow_model === 'object'
    ? payload.flow_model
    : metadata.flow_model
  return flowModel && typeof flowModel === 'object' ? flowModel : null
}

function resolveFlowModelDetails(flowModel, fields) {
  const nodes = Array.isArray(flowModel?.nodes) ? flowModel.nodes : []
  if (!nodes.length) {
    return null
  }
  const labelByKey = buildLabelByKey(fields)
  const evidenceNodes = nodes.filter((node) => node?.type === 'evidence')
  const decisionNodes = nodes.filter((node) => node?.type === 'decision')
  const facts = evidenceNodes.flatMap((node) => {
    const keys = readStringList(node?.fields)
    const fieldText = keys.slice(0, 4).map((key) => `${labelByKey[key] || key}[${key}]`)
    return fieldText.length
      ? fieldText
      : [normalizeRiskRuleText(node?.description)]
  }).filter(Boolean)
  const conditions = decisionNodes.map((node, index) => {
    const title = normalizeRiskRuleText(node?.title || `判断 ${index + 1}`)
    const description = normalizeRiskRuleText(node?.description)
    return description ? `${title}：${description}` : title
  }).filter(Boolean)
  return {
    facts: facts.length ? facts : buildFieldFactLines(fields),
    conditions,
    hitLogic: conditions.join(' AND ')
  }
}

function buildFactLines(facts, fields) {
  const labelByKey = buildLabelByKey(fields)
  const rows = facts
    .slice(0, 4)
    .map((fact) => {
      const id = normalizeRiskRuleText(fact?.id)
      const label = normalizeRiskRuleText(fact?.label || id || '事实')
      const fieldKeys = readStringList(fact?.fields)
      const fieldText = fieldKeys.slice(0, 3).map((key) => labelByKey[key] || key).join('∪')
      return `${id ? `${id}=` : ''}${label}: ${fieldText || '规则字段'}`
    })
    .filter(Boolean)
  return rows.length ? rows : buildFieldFactLines(fields)
}

function buildFieldFactLines(fields) {
  return (Array.isArray(fields) ? fields : [])
    .slice(0, 4)
    .map((field, index) => `${String.fromCharCode(65 + index)}=${formatRiskRuleFieldDisplay(field)}`)
    .filter(Boolean)
}

function buildConditionLines(params, fields) {
  const labelByKey = buildLabelByKey(fields)
  const conditions = Array.isArray(params.conditions) ? params.conditions : []
  const rows = conditions
    .slice(0, 4)
    .map((condition, index) => formatConditionLine(condition, labelByKey, index + 1))
    .filter(Boolean)
  if (rows.length) {
    return rows
  }
  return normalizeRiskRuleText(params.condition_summary) ? [normalizeRiskRuleText(params.condition_summary)] : []
}

function formatConditionLine(condition, labelByKey, index) {
  const operator = normalizeRiskRuleText(condition?.operator)
  const id = normalizeRiskRuleText(condition?.id || `C${index}`)
  const prefix = `${id}: `
  if (['not_in_scope', 'not_in_set', 'not_overlap'].includes(operator)) {
    return `${prefix}${formatFieldGroup(condition?.left_fields, labelByKey)} ∩ ${formatFieldGroup(condition?.right_fields, labelByKey)} = ∅`
  }
  if (['in_scope', 'overlap'].includes(operator)) {
    return `${prefix}${formatFieldGroup(condition?.left_fields, labelByKey)} ∩ ${formatFieldGroup(condition?.right_fields, labelByKey)} ≠ ∅`
  }
  if (operator === 'date_outside_range') {
    return `${prefix}${formatFieldGroup(condition?.date_fields, labelByKey)} 不在 [${formatFieldGroup(condition?.range_start_fields, labelByKey)}, ${formatFieldGroup(condition?.range_end_fields, labelByKey)}]`
  }
  if (['contains_any', 'not_contains_any'].includes(operator)) {
    const verb = operator === 'not_contains_any' ? '不含' : '包含'
    const keywords = readStringList(condition?.keywords).slice(0, 4).join('、') || '关键词'
    return `${prefix}${formatFieldGroup(condition?.fields, labelByKey)} ${verb} ${keywords}`
  }
  if (['exists_any', 'exists_all', 'all_present'].includes(operator)) {
    const verb = operator === 'exists_any' ? '任一有值' : '全部有值'
    return `${prefix}${formatFieldGroup(condition?.fields, labelByKey)} ${verb}`
  }
  const left = normalizeRiskRuleText(condition?.left)
  const right = normalizeRiskRuleText(condition?.right)
  if (left || right) {
    return `${prefix}${labelByKey[left] || left} ${operator || 'compare'} ${labelByKey[right] || right}`
  }
  return `${prefix}${operator || '规则条件'}`
}

function formatFieldGroup(value, labelByKey) {
  const keys = readStringList(value)
  if (!keys.length) {
    return '字段集合'
  }
  return keys.slice(0, 3).map((key) => labelByKey[key] || key).join('∪')
}

function formatHitLogic(value) {
  if (typeof value === 'string') {
    return normalizeRiskRuleText(value)
  }
  if (Array.isArray(value)) {
    return value.map(formatHitLogic).filter(Boolean).join(' AND ')
  }
  if (!value || typeof value !== 'object') {
    return ''
  }
  if (Array.isArray(value.all)) {
    return value.all.map(wrapLogicPart).filter(Boolean).join(' AND ')
  }
  if (Array.isArray(value.any)) {
    return value.any.map(wrapLogicPart).filter(Boolean).join(' OR ')
  }
  if (Object.prototype.hasOwnProperty.call(value, 'not')) {
    const text = wrapLogicPart(value.not)
    return text ? `NOT ${text}` : ''
  }
  return ''
}

function wrapLogicPart(value) {
  const text = formatHitLogic(value)
  return value && typeof value === 'object' && !Array.isArray(value) && text ? `(${text})` : text
}

function buildLabelByKey(fields) {
  const map = {}
  ;(Array.isArray(fields) ? fields : []).forEach((field) => {
    const key = normalizeRiskRuleText(field?.key)
    if (key) {
      map[key] = normalizeRiskRuleText(field?.label || key)
    }
  })
  return map
}

function readStringList(value) {
  return Array.isArray(value) ? value.map(normalizeRiskRuleText).filter(Boolean) : []
}

function isCityRouteConsistencyPayload(payload) {
  if (!payload || typeof payload !== 'object') {
    return false
  }
  const metadata = payload.metadata && typeof payload.metadata === 'object' ? payload.metadata : {}
  const params = payload.params && typeof payload.params === 'object' ? payload.params : {}
  const semanticType = normalizeRiskRuleText(payload.semantic_type || params.semantic_type)
  if (CITY_ROUTE_SEMANTIC_TYPES.has(semanticType)) {
    return true
  }

  const text = [
    metadata.natural_language,
    params.natural_language,
    payload.description,
    metadata.condition_summary,
    params.condition_summary
  ]
    .map(normalizeRiskRuleText)
    .join('\n')
  if (looksLikeCityRouteRuleText(text)) {
    return true
  }

  const fieldKeys = new Set(resolveRiskRuleFieldKeys(payload))
  const hasAttachmentCity =
    fieldKeys.has('attachment.route_cities') || fieldKeys.has('attachment.hotel_city')
  const hasReferenceCity = fieldKeys.has('claim.location') || fieldKeys.has('item.item_location')
  return hasAttachmentCity && hasReferenceCity && text.includes('风险关键词')
}

function resolveRiskRuleFieldKeys(payload) {
  const keys = []
  const inputs = payload.inputs && typeof payload.inputs === 'object' ? payload.inputs : {}
  if (Array.isArray(inputs.fields)) {
    inputs.fields.forEach((item) => {
      const key = normalizeRiskRuleText(item?.key)
      if (key) keys.push(key)
    })
  }
  ;[payload.field_keys, payload.params?.field_keys, payload.params?.search_fields].forEach((rows) => {
    if (!Array.isArray(rows)) return
    rows.forEach((item) => {
      const key = normalizeRiskRuleText(item)
      if (key) keys.push(key)
    })
  })
  return [...new Set(keys)]
}

function looksLikeCityRouteRuleText(text) {
  const normalized = normalizeRiskRuleText(text)
  if (!normalized) {
    return false
  }
  const hasCitySubject = ['交通票', '住宿票', '住宿发票', '票据', '附件', '行程城市', '住宿城市'].some(
    (term) => normalized.includes(term)
  )
  const hasReference = ['申报目的地', '申报地点', '明细地点', '发生地点', '意图城市', '目的地'].some(
    (term) => normalized.includes(term)
  )
  const hasRelation = ['一致', '不一致', '形成一致关系', '匹配', '无法与', '对应'].some((term) =>
    normalized.includes(term)
  )
  const hasRouteAnomaly = ['绕行', '跨城', '中转', '周转', '改签'].some((term) =>
    normalized.includes(term)
  )
  return hasCitySubject && hasReference && (hasRelation || hasRouteAnomaly)
}
