const DEFAULT_SESSION_TYPE_EXPENSE = 'expense'
const DEFAULT_SESSION_TYPE_APPLICATION = 'application'
const DEFAULT_SESSION_TYPE_APPROVAL = 'approval'
const DEFAULT_SESSION_TYPE_KNOWLEDGE = 'knowledge'

const DEFAULT_INTENT_LABELS = {
  query: '查询',
  explain: '解释',
  compare: '对比',
  risk_check: '风险检查',
  draft: '信息核对',
  operate: '动作请求'
}

const DEFAULT_SCENARIO_LABELS = {
  expense: '报销',
  accounts_receivable: '应收',
  accounts_payable: '应付',
  knowledge: '知识',
  unknown: '通用'
}

const DEFAULT_EXPENSE_TYPE_LABELS = {
  travel: '差旅费',
  hotel: '住宿费',
  transport: '交通费',
  meal: '业务招待费',
  meeting: '会务费',
  entertainment: '业务招待费',
  marketing: '市场推广费',
  office: '办公用品费',
  training: '培训费',
  software: '软件服务费',
  communication: '通讯费',
  welfare: '福利费',
  other: '其他费用'
}

export const TRANSPORT_KEYWORD_PATTERN = /交通|市内交通|出行|打车|网约车|出租车|滴滴|车费|乘车|用车|叫车|约车|的士|车票|车资|地铁|公交|停车|过路费|通行费|高速费|油费/

const FLOW_INTENT_KEYWORDS = {
  draft: ['报销', '报账', '草稿', '生成', '提交', '申请', '请走报销'],
  query: ['查询', '查一下', '多少', '明细', '统计'],
  risk_check: ['风险', '异常', '重复', '超标'],
  explain: ['为什么', '依据', '规则', '怎么']
}

const EXPLICIT_EXPENSE_INTENT_PATTERN = /报销|报账|费用|发票|票据|单据|垫付|报销单|冲销|借款/
const NON_EXPENSE_INTENT_PATTERN = /怎么部署|如何部署|部署步骤|技术方案|排期|任务|工单|需求|代码|脚本|服务器配置|运维|实施计划|项目计划|会议纪要|周报|日报|总结/
const BUSINESS_ACTIVITY_PATTERN = /去|到|赴|前往|支撑|支持|部署|实施|驻场|出差|拜访|客户|项目|现场|电力|银行|医院|学校|园区|公司|集团|服务器/

function normalizeCompactText(value) {
  return String(value || '').trim().replace(/\s+/g, '')
}

function resolveExpenseTypeLabel(type, fallbackLabel = '', expenseTypeLabels = DEFAULT_EXPENSE_TYPE_LABELS) {
  const normalized = String(type || '').trim()
  return expenseTypeLabels[normalized] || String(fallbackLabel || '').trim() || expenseTypeLabels.other
}

function resolveSemanticExpenseTypeLabel(semanticParse, expenseTypeLabels = DEFAULT_EXPENSE_TYPE_LABELS) {
  const entities = Array.isArray(semanticParse?.entities_json) ? semanticParse.entities_json : []
  const expenseTypeEntity = entities.find((item) => String(item?.type || '').trim() === 'expense_type')
  if (expenseTypeEntity) {
    return resolveExpenseTypeLabel(
      String(expenseTypeEntity.normalized_value || '').trim(),
      String(expenseTypeEntity.value || '').trim(),
      expenseTypeLabels
    )
  }

  return resolveExpenseTypeLabel(
    String(semanticParse?.expense_type || semanticParse?.expense_type_code || '').trim(),
    String(semanticParse?.expense_type_label || '').trim(),
    expenseTypeLabels
  )
}

export function inferLocalFlowCandidates(rawText) {
  const text = String(rawText || '').trim()
  const compact = normalizeCompactText(text)

  let time = ''
  const explicitTimeMatch = text.match(/发生时间[:：]?\s*([0-9]{4}[-/年][0-9]{1,2}[-/月][0-9]{1,2}日?)/)
  if (explicitTimeMatch?.[1]) {
    time = explicitTimeMatch[1].replace(/年/g, '-').replace(/月/g, '-').replace(/日/g, '').replace(/\//g, '-')
  } else {
    const dateMatch = text.match(/([0-9]{4}[-/年][0-9]{1,2}[-/月][0-9]{1,2}日?)/)
    if (dateMatch?.[1]) {
      time = dateMatch[1].replace(/年/g, '-').replace(/月/g, '-').replace(/日/g, '').replace(/\//g, '-')
    } else if (/今天|今日/.test(compact)) {
      time = '今天'
    } else if (/昨天|昨日/.test(compact)) {
      time = '昨天'
    } else if (/前天/.test(compact)) {
      time = '前天'
    }
  }

  let amount = ''
  const amountMatch = text.match(/([0-9]+(?:\.[0-9]{1,2})?)\s*(?:元|员|圆|园|块|块钱|万元|万)/)
  if (amountMatch?.[1]) {
    const numericValue = Number(amountMatch[1])
    if (Number.isFinite(numericValue)) {
      amount = Number.isInteger(numericValue) ? `${numericValue}元` : `${numericValue.toFixed(2)}元`
    }
  }

  let event = ''
  let expenseType = ''
  if (TRANSPORT_KEYWORD_PATTERN.test(compact)) {
    event = '交通出行'
    expenseType = '交通费'
  } else if (/客户.*吃饭|请客户.*吃饭|客户用餐|客户接待|商务接待|招待|宴请|请客/.test(compact)) {
    event = '业务招待'
    expenseType = '业务招待费'
  } else if (/出差|差旅|机票|飞机票|航班|高铁票|高铁|火车票|火车|动车|行程单|铁路客票/.test(compact)) {
    event = '出差行程'
    expenseType = '差旅费'
  } else if (/住宿|住宿费|酒店|酒店发票|宾馆|民宿|房费|客房/.test(compact)) {
    event = '住宿报销'
    expenseType = '住宿费'
  } else if (/餐费|工作餐|用餐|午餐|晚餐|早餐|餐饮|伙食|茶歇/.test(compact)) {
    event = '业务招待'
    expenseType = '业务招待费'
  } else if (/会务|会议费|会议|参会|会场|场地费|论坛|展会/.test(compact)) {
    event = '会务活动'
    expenseType = '会务费'
  } else if (/办公用品|办公耗材|办公设备|文具|打印纸|硒鼓|墨盒|键盘|鼠标|白板/.test(compact)) {
    event = '办公采购'
    expenseType = '办公用品费'
  } else if (/培训|讲师费|课程费|教材|认证费|考试费/.test(compact)) {
    event = '培训学习'
    expenseType = '培训费'
  } else if (/通讯费|话费|电话费|手机费|流量费|宽带费|网络费/.test(compact)) {
    event = '通讯使用'
    expenseType = '通讯费'
  } else if (/福利费|团建|慰问|节日福利|体检费|员工关怀/.test(compact)) {
    event = '员工福利'
    expenseType = '福利费'
  }

  return {
    time,
    amount,
    event,
    expenseType
  }
}

export function shouldRequestExpenseSceneSelection(rawText, options = {}) {
  const sessionType = options.sessionType || DEFAULT_SESSION_TYPE_EXPENSE
  if (sessionType !== DEFAULT_SESSION_TYPE_EXPENSE) {
    return false
  }
  if (Number(options.attachmentCount || 0) > 0) {
    return false
  }
  if (String(options.reviewAction || '').trim()) {
    return false
  }
  if (options.hasSelectedExpenseType) {
    return false
  }

  const compact = normalizeCompactText(rawText)
  if (!compact) {
    return false
  }
  const hasExpenseIntent = /报销|报账|费用|申请/.test(compact)
  if (!hasExpenseIntent) {
    return false
  }

  const candidates = inferLocalFlowCandidates(rawText)
  return !candidates.expenseType
}

export function shouldRequestExpenseIntentConfirmation(rawText, options = {}) {
  const sessionType = options.sessionType || DEFAULT_SESSION_TYPE_EXPENSE
  if (sessionType !== DEFAULT_SESSION_TYPE_EXPENSE) {
    return false
  }
  if (Number(options.attachmentCount || 0) > 0) {
    return false
  }
  if (String(options.reviewAction || '').trim()) {
    return false
  }
  if (options.hasConfirmedExpenseIntent || options.hasSelectedExpenseType) {
    return false
  }

  const compact = normalizeCompactText(rawText)
  if (!compact || compact.length < 6) {
    return false
  }
  if (EXPLICIT_EXPENSE_INTENT_PATTERN.test(compact)) {
    return false
  }
  if (NON_EXPENSE_INTENT_PATTERN.test(compact)) {
    return false
  }

  return BUSINESS_ACTIVITY_PATTERN.test(compact)
}

export function buildLocalIntentPreview(rawText, sessionType = DEFAULT_SESSION_TYPE_EXPENSE, options = {}) {
  if (sessionType === DEFAULT_SESSION_TYPE_KNOWLEDGE) {
    return '初步识别为财务知识问答，正在准备检索范围'
  }
  if (sessionType === DEFAULT_SESSION_TYPE_APPLICATION) {
    return '初步识别为费用申请事项，准备进入申请信息识别'
  }
  if (sessionType === DEFAULT_SESSION_TYPE_APPROVAL) {
    return '初步识别为审核处理事项，准备进入单据查询或风险核对'
  }

  if (shouldRequestExpenseIntentConfirmation(rawText, { ...options, sessionType })) {
    return '识别到业务事项描述，但是否发起报销尚不明确，需要先由用户确认'
  }

  if (shouldRequestExpenseSceneSelection(rawText, { ...options, sessionType })) {
    return '初步识别为报销申请，但报销场景尚未明确，需要先由用户选择场景'
  }

  const compact = normalizeCompactText(rawText)
  const intentLabels = options.intentLabels || DEFAULT_INTENT_LABELS
  const intentKey = Object.entries(FLOW_INTENT_KEYWORDS).find(([, keywords]) =>
    keywords.some((keyword) => compact.includes(keyword))
  )?.[0] || 'draft'
  const intentLabel = intentLabels[intentKey] || DEFAULT_INTENT_LABELS[intentKey] || '处理'
  const candidates = inferLocalFlowCandidates(rawText)
  const expenseTypeText = candidates.expenseType ? `，费用类型为${candidates.expenseType}` : ''
  return `初步识别为报销场景，准备进入${intentLabel}${expenseTypeText}`
}

export function buildLocalExtractionProgressMessages(rawText, options = {}) {
  const candidates = inferLocalFlowCandidates(rawText)
  const messages = []

  messages.push('正在提取发生时间...')
  messages.push(
    candidates.time
      ? `发现发生时间 ${candidates.time}，继续提取金额...`
      : '暂未定位到明确时间，继续提取金额...'
  )
  messages.push(
    candidates.amount
      ? `发现金额 ${candidates.amount}，继续识别事件类型...`
      : '暂未定位到明确金额，继续识别事件类型...'
  )

  if (candidates.event || candidates.expenseType) {
    const eventParts = [candidates.event, candidates.expenseType].filter(Boolean)
    messages.push(`识别到${eventParts.join(' / ')}，继续判断待补项...`)
  } else {
    messages.push('正在识别事件类型和费用分类...')
  }

  const attachmentHint = Number(options.attachmentCount || 0) > 0 ? '附件完整性' : '票据附件'
  const pendingSlots = ['发生时间', '金额', attachmentHint]
  if (candidates.expenseType === '业务招待费') {
    pendingSlots.splice(2, 0, '客户名称', '参与人员')
  } else if (candidates.expenseType === '住宿费') {
    pendingSlots.splice(2, 0, '酒店/商户')
  }
  messages.push(`正在判断待补项：${pendingSlots.join('、')}`)

  return messages
}

export function summarizeSemanticIntentDetail(semanticParse, options = {}) {
  if (!semanticParse || typeof semanticParse !== 'object') {
    return options.fallbackText || '意图识别完成'
  }

  const scenarioLabels = options.scenarioLabels || DEFAULT_SCENARIO_LABELS
  const intentLabels = options.intentLabels || DEFAULT_INTENT_LABELS
  const expenseTypeLabels = options.expenseTypeLabels || DEFAULT_EXPENSE_TYPE_LABELS
  const scenarioLabel = scenarioLabels[String(semanticParse.scenario || '').trim()] || String(semanticParse.scenario || '').trim() || '通用'
  const intentLabel = intentLabels[String(semanticParse.intent || '').trim()] || String(semanticParse.intent || '').trim() || '处理'
  const expenseTypeLabel = resolveSemanticExpenseTypeLabel(semanticParse, expenseTypeLabels)
  const expenseTypeText = expenseTypeLabel && expenseTypeLabel !== expenseTypeLabels.other
    ? `，费用类型为${expenseTypeLabel}`
    : ''
  return `已识别为${scenarioLabel}场景，当前目标是${intentLabel}${expenseTypeText}`
}
