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

function normalizeTone(value) {
  const tone = normalizeText(value).toLowerCase()
  if (['pass', 'success', 'ok', 'normal', 'none', 'compliant', 'approved'].includes(tone)) return 'pass'
  if (tone === 'high') return 'high'
  if (tone === 'medium') return 'medium'
  if (tone === 'low') return 'low'
  return 'medium'
}

function normalizeIdList(value) {
  const rawValues = Array.isArray(value)
    ? value
    : normalizeText(value)
      ? [value]
      : []
  return [...new Set(rawValues.map((item) => normalizeText(item)).filter(Boolean))]
}

export function cardLikeText(card = {}) {
  return [
    card.label,
    card.title,
    card.risk,
    card.message,
    card.summary,
    card.suggestion,
    card.description,
    card.detail
  ].map((item) => normalizeText(item)).join(' ')
}

function resolveRiskCardItemIds(card = {}) {
  return normalizeIdList([
    card.itemId,
    card.item_id,
    ...(Array.isArray(card.itemIds) ? card.itemIds : []),
    ...(Array.isArray(card.item_ids) ? card.item_ids : [])
  ])
}

function resolveDuplicateRiskGroup(card = {}) {
  const text = cardLikeText(card)
  if (/多城市行程|中转|多地拜访|改签|多地出差|后续行程|行程终点异常|连续闭环/.test(text) && /待说明|未说明|缺少说明|原因|说明|不一致|异常/.test(text)) {
    return 'route-explanation'
  }
  return ''
}

function riskCardsReferToSameIssue(left = {}, right = {}) {
  const leftItemIds = resolveRiskCardItemIds(left)
  const rightItemIds = resolveRiskCardItemIds(right)
  if (!leftItemIds.length || !rightItemIds.length) {
    return true
  }
  return leftItemIds.some((itemId) => rightItemIds.includes(itemId))
}

function riskToneWeight(tone) {
  const normalizedTone = normalizeTone(tone)
  if (normalizedTone === 'high') return 0
  if (normalizedTone === 'medium') return 1
  if (normalizedTone === 'low') return 2
  if (normalizedTone === 'pass') return 4
  return 9
}

export function dedupeLowerSeverityRiskCards(cards = []) {
  return cards.filter((card, index) => {
    const duplicateGroup = resolveDuplicateRiskGroup(card)
    if (!duplicateGroup) {
      return true
    }
    return !cards.some((otherCard, otherIndex) => (
      otherIndex !== index
      && resolveDuplicateRiskGroup(otherCard) === duplicateGroup
      && riskToneWeight(otherCard?.tone || otherCard?.severity) < riskToneWeight(card?.tone || card?.severity)
      && riskCardsReferToSameIssue(card, otherCard)
    ))
  })
}
