import { filterActionableRiskFlags, normalizeRiskFlagTone } from './riskFlags.js'
import { canViewRiskForContext } from './riskVisibility.js'
import { isApplicationDocumentNo } from './documentClassification.js'

const SYSTEM_GENERATED_EXPENSE_TYPES = new Set(['travel_allowance'])
const LOCATION_REQUIRED_EXPENSE_TYPES = new Set(['travel', 'meeting', 'entertainment'])

function isPlaceholderValue(value) {
  const text = String(value || '').trim()
  if (!text) {
    return true
  }

  return ['待补充', '暂无', '无', '未知', '处理中'].includes(text.replace(/\s+/g, ''))
}

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

function isApplicationDocumentRequest(request) {
  const documentType = String(
    request?.documentTypeCode
    || request?.document_type_code
    || request?.documentType
    || request?.document_type
    || ''
  ).trim()
  const claimNo = String(
    request?.claimNo
    || request?.claim_no
    || request?.documentNo
    || request?.id
    || ''
  ).trim().toUpperCase()
  const typeCode = normalizeExpenseType(request?.typeCode || request?.expense_type)

  return (
    documentType === 'application'
    || documentType === 'expense_application'
    || isApplicationDocumentNo(claimNo)
    || typeCode === 'application'
    || typeCode.endsWith('_application')
  )
}

function isSystemGeneratedExpenseItem(item) {
  const itemType = normalizeExpenseType(item?.itemType || item?.item_type)
  return Boolean(item?.isSystemGenerated || item?.is_system_generated || SYSTEM_GENERATED_EXPENSE_TYPES.has(itemType))
}

function hasPositiveAmount(value) {
  const amount = Number(value)
  return Number.isFinite(amount) && amount > 0
}

function getExpenseItems(request) {
  return Array.isArray(request?.expenseItems) ? request.expenseItems : []
}

export function hasMissingAttachment(request) {
  if (isApplicationDocumentRequest(request)) {
    return false
  }

  const expenseItems = getExpenseItems(request)

  if (expenseItems.length) {
    return expenseItems.some((item) => {
      if (isSystemGeneratedExpenseItem(item)) {
        return false
      }
      return !String(item?.invoiceId || item?.invoice_id || '').trim()
    })
  }

  const attachmentSummary = String(request?.attachmentSummary || '').trim()
  const secondaryStatusValue = String(request?.secondaryStatusValue || '').trim()
  return /待|缺|未/.test(attachmentSummary) || /待|缺|未/.test(secondaryStatusValue)
}

export function hasPendingInfo(request) {
  if (!request) {
    return false
  }

  const expenseItems = getExpenseItems(request).filter((item) => !isSystemGeneratedExpenseItem(item))
  const hasItemValue = (resolver) => expenseItems.some((item) => !isPlaceholderValue(resolver(item)))
  const hasItemAmount = expenseItems.some((item) => hasPositiveAmount(item?.itemAmount || item?.item_amount))
  const requestType = normalizeExpenseType(request.typeCode || request.expense_type)
  const locationRequired = LOCATION_REQUIRED_EXPENSE_TYPES.has(requestType)

  if (!hasPositiveAmount(request.amountValue) && !hasItemAmount) {
    return true
  }

  if (isPlaceholderValue(request.typeLabel) && !hasItemValue((item) => item?.itemType || item?.item_type)) {
    return true
  }

  if (isPlaceholderValue(request.reason) && !hasItemValue((item) => item?.itemReason || item?.item_reason || item?.desc)) {
    return true
  }

  if (isPlaceholderValue(request.occurredDisplay) && !hasItemValue((item) => item?.itemDate || item?.item_date || item?.time)) {
    return true
  }

  if (
    locationRequired
    && isPlaceholderValue(request.location)
    && isPlaceholderValue(request.city)
    && !hasItemValue((item) => item?.itemLocation || item?.item_location)
  ) {
    return true
  }

  return false
}

function getRiskFlags(request) {
  if (Array.isArray(request?.riskFlags)) {
    return request.riskFlags
  }
  if (Array.isArray(request?.risk_flags_json)) {
    return request.risk_flags_json
  }
  return []
}

function resolveRiskAlert(request, context = {}) {
  const flags = filterActionableRiskFlags(getRiskFlags(request))
    .filter((flag) => (
      context.currentUser
        ? canViewRiskForContext(flag, {
          request,
          currentUser: context.currentUser,
          businessStage: context.businessStage
        })
        : true
    ))
  if (!flags.length) {
    return null
  }
  const highCount = flags.filter((flag) => normalizeRiskFlagTone(flag) === 'high').length
  const mediumCount = flags.filter((flag) => normalizeRiskFlagTone(flag) === 'medium').length
  if (highCount > 0) {
    return {
      label: `高风险 ${highCount} 项`,
      tone: 'danger',
      icon: 'mdi mdi-alert-octagon-outline'
    }
  }
  if (mediumCount > 0) {
    return {
      label: `中风险 ${mediumCount} 项`,
      tone: 'warning',
      icon: 'mdi mdi-alert-circle-outline'
    }
  }
  return null
}

function parseNonNegativeInteger(value) {
  const nextValue = Number(value)
  return Number.isFinite(nextValue) && nextValue > 0 ? Math.floor(nextValue) : 0
}

function resolveSlaReminderCount(request) {
  const directCount = [
    request?.slaReminderCount,
    request?.sla_reminder_count,
    request?.slaUrgeCount,
    request?.sla_urge_count,
    request?.urgeCount,
    request?.urge_count,
    request?.reminderCount,
    request?.reminder_count
  ].reduce((max, value) => Math.max(max, parseNonNegativeInteger(value)), 0)

  if (directCount > 0) {
    return directCount
  }

  return getRiskFlags(request).reduce((count, flag) => {
    if (!flag || typeof flag !== 'object') {
      return count
    }

    const explicitCount = [
      flag.slaReminderCount,
      flag.sla_reminder_count,
      flag.slaUrgeCount,
      flag.sla_urge_count,
      flag.urgeCount,
      flag.urge_count,
      flag.reminderCount,
      flag.reminder_count
    ].reduce((max, value) => Math.max(max, parseNonNegativeInteger(value)), 0)

    if (explicitCount > 0) {
      return count + explicitCount
    }

    const signal = [
      flag.source,
      flag.event_type,
      flag.eventType,
      flag.action,
      flag.type,
      flag.label,
      flag.message
    ].join(' ')

    return /sla|remind|reminder|urge|催单/i.test(signal) ? count + 1 : count
  }, 0)
}

export function buildDetailAlerts(request, context = {}) {
  if (!request) {
    return []
  }

  const alerts = []
  const slaReminderCount = resolveSlaReminderCount(request)
  const riskAlert = resolveRiskAlert(request, context)

  if (riskAlert) {
    alerts.push(riskAlert)
  }

  alerts.push({
    label: `SLA 催单次数 ${slaReminderCount}`,
    tone: slaReminderCount > 0 ? 'warning' : 'neutral',
    icon: 'mdi mdi-bell-ring-outline'
  })

  if (hasMissingAttachment(request)) {
    alerts.push({ label: '缺少票据', tone: 'warning' })
  }

  if (hasPendingInfo(request)) {
    alerts.push({ label: '待补信息', tone: 'warning' })
  }

  return alerts.filter((item, index, list) => list.findIndex((entry) => entry.label === item.label) === index).slice(0, 3)
}
