const RISK_LABELS = {
  critical: '重大风险',
  high: '高风险',
  medium: '中风险',
  low: '低风险'
}

const ACTION_METADATA = {
  approve: { label: '审批通过', tone: 'primary', icon: 'mdi mdi-check-circle-outline' },
  return: { label: '退回', tone: 'danger', icon: 'mdi mdi-undo' },
  delegate: { label: '委托', tone: 'neutral', icon: 'mdi mdi-account-arrow-right-outline' },
  delegation_revoke: { label: '撤销委托', tone: 'neutral', icon: 'mdi mdi-account-cancel-outline' },
  transfer: { label: '转交', tone: 'warning', icon: 'mdi mdi-swap-horizontal' },
  add_sign: { label: '加签', tone: 'neutral', icon: 'mdi mdi-account-plus-outline' },
  countersign: { label: '会签', tone: 'neutral', icon: 'mdi mdi-account-group-outline' },
  sla_escalate: { label: '立即升级', tone: 'warning', icon: 'mdi mdi-arrow-up-bold-circle-outline' }
}

function toArray(value) {
  return Array.isArray(value) ? value : []
}

function toText(value) {
  return String(value ?? '').trim()
}

function toNumber(value, fallback = 0) {
  const number = Number(value)
  return Number.isFinite(number) ? number : fallback
}

export function unwrapApprovalTaskQueueItem(item = {}) {
  return item?.task && typeof item.task === 'object' ? item.task : item
}

export function resolveApprovalTaskClaim(item = {}) {
  return item?.claim && typeof item.claim === 'object' ? item.claim : {}
}

export function resolveApprovalTaskReadOnlyReason(item = {}) {
  const task = unwrapApprovalTaskQueueItem(item)
  const explicit = toText(task.readOnlyReason ?? task.read_only_reason)
  if (explicit) {
    return explicit
  }
  const blockers = toArray(task.batchBlockReasons ?? task.batch_block_reasons_json)
    .map(toText)
    .filter(Boolean)
  return blockers.join('；')
}

export function resolveApprovalTaskActionItems(item = {}) {
  const task = unwrapApprovalTaskQueueItem(item)
  const canDecide = (task.canAct ?? task.can_act) === true
  return toArray(task.availableActions ?? task.available_actions)
    .map(toText)
    .filter((action, index, values) => action && values.indexOf(action) === index)
    .filter((action) => canDecide || !['approve', 'return'].includes(action))
    .map((action) => ACTION_METADATA[action] ? { action, ...ACTION_METADATA[action] } : null)
    .filter(Boolean)
}

export function resolveApprovalTaskSlaMeta(item = {}, now = Date.now()) {
  const task = unwrapApprovalTaskQueueItem(item)
  const dueAtText = toText(task.dueAt ?? task.due_at)
  const dueAt = dueAtText ? new Date(dueAtText) : null
  const dueTime = dueAt && !Number.isNaN(dueAt.getTime()) ? dueAt.getTime() : null
  const escalationLevel = Math.max(0, Math.trunc(toNumber(
    task.escalationLevel ?? task.escalation_level
  )))
  const nextEscalationAt = toText(task.nextEscalationAt ?? task.next_escalation_at)

  if (dueTime === null) {
    return {
      label: '未配置',
      tone: 'neutral',
      overdue: false,
      nearDue: false,
      escalationLevel,
      escalationLabel: escalationLevel ? `L${escalationLevel}` : '',
      title: '当前节点未返回 SLA 截止时间。',
      dueAt: '',
      nextEscalationAt
    }
  }

  const diffMs = dueTime - Number(now)
  const overdue = diffMs <= 0
  const absoluteMinutes = Math.max(1, Math.ceil(Math.abs(diffMs) / 60000))
  const hours = absoluteMinutes / 60
  const durationLabel = hours >= 1
    ? `${hours >= 10 ? Math.round(hours) : hours.toFixed(1)}h`
    : `${absoluteMinutes}m`
  const nearDue = !overdue && diffMs <= 2 * 60 * 60 * 1000
  const label = overdue ? `超时 ${durationLabel}` : `剩余 ${durationLabel}`
  const tone = overdue ? 'danger' : nearDue ? 'warning' : 'safe'
  const escalationLabel = escalationLevel ? `L${escalationLevel}` : ''
  const titleParts = [
    `节点截止时间：${dueAtText}`,
    escalationLabel ? `当前升级等级：${escalationLabel}` : '',
    nextEscalationAt ? `下次升级：${nextEscalationAt}` : ''
  ].filter(Boolean)
  return {
    label,
    tone,
    overdue,
    nearDue,
    escalationLevel,
    escalationLabel,
    title: titleParts.join('；'),
    dueAt: dueAtText,
    nextEscalationAt
  }
}

export function resolveApprovalTaskRow(item = {}, now = Date.now()) {
  const task = unwrapApprovalTaskQueueItem(item)
  const claim = resolveApprovalTaskClaim(item)
  const amount = toNumber(claim.amount)
  const riskLevel = toText(task.riskLevel ?? task.risk_level ?? 'low') || 'low'
  const evidenceCompleteness = Math.max(0, Math.min(
    1,
    toNumber(task.evidenceCompleteness ?? task.evidence_completeness)
  ))
  return {
    id: toText(task.id),
    claimId: toText(task.claimId ?? task.claim_id),
    claimNo: toText(claim.claim_no ?? claim.claimNo ?? task.claimId ?? task.claim_id),
    applicant: toText(claim.employee_name ?? claim.employeeName ?? claim.person ?? '未记录'),
    department: toText(claim.department_name ?? claim.departmentName ?? claim.dept ?? '未记录'),
    amountLabel: new Intl.NumberFormat('zh-CN', {
      style: 'currency',
      currency: 'CNY',
      minimumFractionDigits: Number.isInteger(amount) ? 0 : 2
    }).format(amount),
    nodeLabel: toText(task.nodeLabel ?? task.node_label ?? claim.approval_stage ?? claim.approvalStage),
    priorityScore: Math.max(0, Math.min(100, toNumber(task.priorityScore ?? task.priority_score))),
    priorityTier: toText(task.priorityTier ?? task.priority_tier ?? 'normal') || 'normal',
    riskLevel,
    riskLabel: RISK_LABELS[riskLevel] || RISK_LABELS.low,
    openRiskCount: Math.max(0, Math.trunc(toNumber(task.openRiskCount ?? task.open_risk_count))),
    evidenceLabel: `${Math.round(evidenceCompleteness * 100)}%`,
    assigneeName: toText(task.assigneeName ?? task.assignee_name ?? '未分配'),
    taskKind: toText(task.taskKind ?? task.task_kind ?? 'root') || 'root',
    coordinationMode: toText(task.coordinationMode ?? task.coordination_mode ?? 'single') || 'single',
    canAct: (task.canAct ?? task.can_act) === true,
    readOnlyReason: resolveApprovalTaskReadOnlyReason(item),
    actions: resolveApprovalTaskActionItems(item),
    sla: resolveApprovalTaskSlaMeta(item, now),
    source: item
  }
}

export function isApprovalTaskKeyboardInputTarget(target) {
  if (!target || typeof target !== 'object') {
    return false
  }
  const tagName = toText(target.tagName).toLowerCase()
  if (['input', 'textarea', 'select', 'button', 'a'].includes(tagName)) {
    return true
  }
  if (target.isContentEditable) {
    return true
  }
  return typeof target.closest === 'function'
    && Boolean(target.closest('input, textarea, select, button, a, [contenteditable="true"]'))
}

export function resolveApprovalTaskKeyboardCommand(event = {}) {
  if (isApprovalTaskKeyboardInputTarget(event.target)) {
    return ''
  }
  const rawKey = String(event.key ?? '')
  if (rawKey === ' ') return 'toggle'
  const key = rawKey.trim().toLowerCase()
  if (key === 'enter') return 'open'
  if (key === 'spacebar') return 'toggle'
  if (key === 'j' || key === 'arrowdown') return 'next'
  if (key === 'k' || key === 'arrowup') return 'previous'
  return ''
}
