import { normalizeApplicationPreview } from '../../utils/expenseApplicationPreview.js'

const APPLICATION_PREVIEW_FIELD_ONTOLOGY_KEY_MAP = {
  applicationType: 'expense_type',
  time: 'time_range',
  location: 'location',
  reason: 'reason',
  amount: 'amount',
  transportMode: 'transport_mode',
  department: 'department_name',
  applicant: 'employee_name',
  grade: 'employee_grade'
}

const APPLICATION_PREVIEW_FIELD_LABEL_MAP = {
  applicationType: '申请类型',
  time: '时间',
  location: '地点',
  reason: '事由',
  amount: '金额',
  transportMode: '出行方式',
  department: '所属部门',
  applicant: '申请人',
  grade: '职级'
}

const STEWARD_RUNTIME_FIELD_COMPLETION_RULES = [
  { fieldKey: 'reason', fieldLabel: '事由', pattern: /事由|申请事由|出差事由|原因|用途/ },
  { fieldKey: 'transportMode', fieldLabel: '出行方式', pattern: /出行方式|交通方式|交通工具|出行工具/ },
  { fieldKey: 'time', fieldLabel: '申请时间', pattern: /申请时间|发生时间|业务发生时间|出发时间|返回时间|时间/ },
  { fieldKey: 'location', fieldLabel: '地点', pattern: /地点|业务地点|发生地点|目的地/ },
  { fieldKey: 'days', fieldLabel: '天数', pattern: /天数|出差天数|申请天数/ },
  { fieldKey: 'amount', fieldLabel: '系统预估费用', pattern: /系统预估费用|用户预估费用|预估费用|预计总费用|预计费用|预计金额|申请金额|预算|金额/ }
]

const APPLICATION_TYPE_DISPLAY_MAP = {
  travel: '差旅费用申请',
  travel_application: '差旅费用申请',
  expense_application: '费用申请',
  application: '费用申请',
  transportation: '交通费用申请',
  traffic: '交通费用申请',
  transport: '交通费用申请',
  accommodation: '住宿费用申请',
  hotel: '住宿费用申请',
  meeting: '会务费用申请',
  conference: '会务费用申请',
  purchase: '采购费用申请',
  procurement: '采购费用申请',
  training: '培训费用申请',
  business_entertainment: '业务招待申请',
  entertainment: '业务招待申请',
  office: '办公费用申请'
}

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

function resolveStewardCurrentTask(continuation = null) {
  const task = continuation?.currentTask || continuation?.current_task || null
  return task && typeof task === 'object' ? task : null
}

function resolveTaskOntologyFields(task = null) {
  const fields = task?.ontology_fields || task?.ontologyFields || {}
  return fields && typeof fields === 'object' ? fields : {}
}

function resolveFieldValue(...candidates) {
  for (const candidate of candidates) {
    const value = compactValue(candidate)
    if (value && !['待补充', '待测算', '未知'].includes(value)) {
      return value
    }
  }
  return ''
}

function resolveApplicationTypeDisplay(value = '') {
  const rawValue = compactValue(value)
  if (!rawValue) return ''

  const normalizedKey = rawValue.toLowerCase()
  if (APPLICATION_TYPE_DISPLAY_MAP[normalizedKey]) {
    return APPLICATION_TYPE_DISPLAY_MAP[normalizedKey]
  }
  if (/^(?:差旅费|差旅|出差)$/.test(rawValue)) return '差旅费用申请'
  if (/^(?:交通费|交通)$/.test(rawValue)) return '交通费用申请'
  if (/^(?:住宿费|住宿|酒店)$/.test(rawValue)) return '住宿费用申请'
  if (/^(?:会务|会议|会务费)$/.test(rawValue)) return '会务费用申请'
  if (/^(?:采购|采购费|办公用品)$/.test(rawValue)) return '采购费用申请'
  return rawValue
}

function buildUpdatedTask(task = null, fieldKey = '', value = '') {
  if (!task || typeof task !== 'object') {
    return null
  }

  const canonicalKey = APPLICATION_PREVIEW_FIELD_ONTOLOGY_KEY_MAP[fieldKey] || ''
  if (!canonicalKey) {
    return { ...task }
  }

  const ontologyFields = {
    ...resolveTaskOntologyFields(task),
    [canonicalKey]: value
  }
  const sourceMissingFields = Array.isArray(task.missing_fields)
    ? task.missing_fields
    : Array.isArray(task.missingFields)
      ? task.missingFields
      : []

  return {
    ...task,
    ontology_fields: ontologyFields,
    missing_fields: sourceMissingFields.filter((field) => compactValue(field) !== canonicalKey)
  }
}

function buildFieldCompletionScopeHints(fieldKey = '', selectedValue = '') {
  const hints = [
    '本轮是对当前申请单字段的补充/更新，不是新建申请或切换任务。'
  ]
  if (fieldKey === 'reason') {
    hints.push(
      `请将“${compactValue(selectedValue)}”作为当前出差申请的事由继续处理，不要把它改判为新的 IT 部署申请。`
    )
  }
  return hints
}

function resolveFieldRuleByKey(fieldKey = '') {
  const normalizedKey = compactValue(fieldKey)
  return STEWARD_RUNTIME_FIELD_COMPLETION_RULES.find((rule) => rule.fieldKey === normalizedKey) || null
}

function resolveFieldRuleByLabel(label = '') {
  const normalizedLabel = compactValue(label)
  if (!normalizedLabel) return null
  return STEWARD_RUNTIME_FIELD_COMPLETION_RULES.find((rule) => rule.pattern.test(normalizedLabel)) || null
}

export function buildStewardFieldCompletionContinuation(continuation = null, fieldKey = '', value = '') {
  const source = continuation && typeof continuation === 'object' ? continuation : {}
  const currentTask = resolveStewardCurrentTask(source)
  const updatedTask = buildUpdatedTask(currentTask, fieldKey, value)
  if (!updatedTask) {
    return source
  }

  return {
    ...source,
    currentTask: updatedTask
  }
}

export function resolveStewardRuntimeFieldCompletion(rawText = '', runtimeState = {}) {
  const value = compactValue(rawText)
  if (!value || compactValue(runtimeState?.waiting_for) !== 'application_field_completion') {
    return null
  }

  const slotAction = runtimeState?.pending_slot_action || runtimeState?.pendingSlotAction || null
  const slotPayload = slotAction?.payload && typeof slotAction.payload === 'object' ? slotAction.payload : {}
  const slotFieldKey = compactValue(slotPayload.field_key || slotPayload.fieldKey || slotAction?.field_key || slotAction?.fieldKey)
  const slotRule = resolveFieldRuleByKey(slotFieldKey)
  if (slotRule) {
    return {
      next_action: 'fill_current_application_field',
      target_message_id: compactValue(slotAction?.message_id || slotAction?.messageId),
      field_key: slotRule.fieldKey,
      field_label: slotRule.fieldLabel,
      field_value: value
    }
  }

  const pendingApplication = runtimeState?.pending_application || runtimeState?.pendingApplication || null
  const missingFields = Array.isArray(pendingApplication?.missing_fields)
    ? pendingApplication.missing_fields
    : Array.isArray(pendingApplication?.missingFields)
      ? pendingApplication.missingFields
      : []
  if (missingFields.length !== 1) {
    return null
  }

  const rule = resolveFieldRuleByLabel(missingFields[0])
  if (!rule) {
    return null
  }

  return {
    next_action: 'fill_current_application_field',
    target_message_id: compactValue(pendingApplication?.message_id || pendingApplication?.messageId),
    field_key: rule.fieldKey,
    field_label: rule.fieldLabel,
    field_value: value
  }
}

export function buildStewardFieldCompletionRawText({
  preview = {},
  fieldKey = '',
  fieldLabel = '',
  value = '',
  continuation = null
} = {}) {
  const normalizedPreview = normalizeApplicationPreview(preview)
  const fields = normalizedPreview.fields || {}
  const currentTask = resolveStewardCurrentTask(continuation)
  const ontologyFields = resolveTaskOntologyFields(currentTask)
  const selectedLabel = compactValue(fieldLabel) || APPLICATION_PREVIEW_FIELD_LABEL_MAP[fieldKey] || '补充项'
  const selectedValue = compactValue(value)
  const transportMode = fieldKey === 'transportMode'
    ? selectedValue
    : resolveFieldValue(fields.transportMode, ontologyFields.transport_mode)

  const knownLines = [
    [
      '申请类型',
      resolveApplicationTypeDisplay(
        resolveFieldValue(fields.applicationType, ontologyFields.expense_type, '差旅费用申请')
      )
    ],
    ['时间', resolveFieldValue(fields.time, ontologyFields.time_range)],
    ['地点', resolveFieldValue(fields.location, ontologyFields.location)],
    ['事由', resolveFieldValue(fields.reason, ontologyFields.reason, currentTask?.summary)],
    ['天数', resolveFieldValue(fields.days)],
    ['出行方式', transportMode]
  ]
    .filter(([, fieldValue]) => fieldValue)
    .map(([label, fieldValue]) => `${label}：${fieldValue}`)

  return [
    '小财管家继续执行申请单字段补齐。',
    `用户已补充：${selectedLabel}：${selectedValue}。`,
    ...buildFieldCompletionScopeHints(fieldKey, selectedValue),
    currentTask?.summary ? `任务摘要：${currentTask.summary}` : '',
    '',
    '已识别信息：',
    ...knownLines,
    '',
    '处理要求：请先根据已补齐字段模拟查询交通票据和费用口径，完成系统预估金额测算，再生成申请单核对表。',
    '如果仍有缺失信息，继续向用户追问；不要替用户默认填写，也不要跳过小财管家的思考过程。'
  ].filter((line) => line !== '').join('\n')
}
