import {
  EXPENSE_TYPE_LABELS,
  formatAmountDisplay
} from './travelReimbursementReviewModel.js'

export const EXPENSE_QUERY_PAGE_SIZE = 5
export const EXPENSE_CENTER_HREF = '/app/documents'
export const ASSOCIATABLE_CLAIM_STATUSES = new Set(['draft', 'supplement', 'returned'])
const EXPENSE_STATUS_LABELS = {
  draft: '草稿',
  supplement: '待补充',
  returned: '已退回',
  submitted: '已提交',
  review: '审批中',
  approved: '已审核',
  pending_payment: '待付款',
  paid: '已付款'
}
const EXPENSE_RISK_LEVEL_LABELS = {
  high: '高风险',
  medium: '中风险',
  warning: '中风险',
  low: '低风险',
  info: '提示'
}

export function normalizeExpenseQueryRiskItem(item, index = 0) {
  if (!item || typeof item !== 'object') {
    return null
  }

  const rawLevel = String(item.level || item.severity || '').trim().toLowerCase()
  const level = EXPENSE_RISK_LEVEL_LABELS[rawLevel] ? rawLevel : 'medium'
  const summary = String(item.summary || item.message || item.content || '').trim()
  const detail = String(item.detail || item.description || summary).trim()
  if (!summary && !detail) {
    return null
  }

  return {
    key: String(item.key || `${level}-${index}`).trim() || `${level}-${index}`,
    level,
    levelLabel: String(item.level_label || item.levelLabel || EXPENSE_RISK_LEVEL_LABELS[level]).trim() || EXPENSE_RISK_LEVEL_LABELS[level],
    title: String(item.title || item.label || EXPENSE_RISK_LEVEL_LABELS[level]).trim() || EXPENSE_RISK_LEVEL_LABELS[level],
    summary: summary || detail,
    detail: detail || summary
  }
}

export function normalizeExpenseQueryStatusGroup(item) {
  if (!item || typeof item !== 'object') {
    return null
  }

  const rawCount = Number(item.count || 0)
  return {
    key: String(item.key || 'other').trim() || 'other',
    label: String(item.label || '其他状态').trim() || '其他状态',
    count: Number.isFinite(rawCount) ? Math.max(0, rawCount) : 0
  }
}

export function normalizeExpenseQueryRecord(item) {
  if (!item || typeof item !== 'object') {
    return null
  }

  const amount = Number(item.amount || 0)
  const amountValue = Number.isFinite(amount) ? amount : 0
  const expenseTypeLabel = String(item.expense_type_label || item.expense_type || '报销').trim() || '报销'
  const reason = String(item.reason || '').trim()
  const documentDate = String(item.document_date || '').trim()
  const occurredAt = String(item.occurred_at || '').trim()

  return {
    claimId: String(item.claim_id || '').trim(),
    claimNo: String(item.claim_no || '').trim() || '未编号',
    employeeName: String(item.employee_name || '').trim(),
    expenseType: String(item.expense_type || '').trim(),
    expenseTypeLabel,
    amount: amountValue,
    amountDisplay: formatAmountDisplay(amountValue),
    status: String(item.status || '').trim(),
    statusLabel: String(item.status_label || '处理中').trim() || '处理中',
    statusGroup: String(item.status_group || 'other').trim() || 'other',
    statusGroupLabel: String(item.status_group_label || '其他状态').trim() || '其他状态',
    approvalStage: String(item.approval_stage || '').trim(),
    documentDate,
    occurredAt,
    reason,
    location: String(item.location || '').trim(),
    riskItems: (Array.isArray(item.risk_flags) ? item.risk_flags : [])
      .map((riskItem, index) => normalizeExpenseQueryRiskItem(riskItem, index))
      .filter(Boolean),
    summary: reason || `${expenseTypeLabel}报销`,
    dateDisplay: documentDate || occurredAt || '待补充日期'
  }
}

export function resolveExpenseStatusGroup(status) {
  const normalized = String(status || '').trim()
  if (['draft', 'supplement', 'returned'].includes(normalized)) {
    return { key: 'draft', label: normalized === 'draft' ? '草稿' : '待完善' }
  }
  if (['submitted', 'review'].includes(normalized)) {
    return { key: 'in_progress', label: '审批中' }
  }
  if (normalized === 'pending_payment') {
    return { key: 'pending_payment', label: '待付款' }
  }
  if (normalized === 'paid') {
    return { key: 'completed', label: '已付款' }
  }
  if (['approved'].includes(normalized)) {
    return { key: 'completed', label: '已完成' }
  }
  return { key: 'other', label: '其他状态' }
}

export function formatQueryRecordDate(value) {
  const text = String(value || '').trim()
  if (!text) return ''
  return text.includes('T') ? text.split('T')[0] : text.slice(0, 10)
}

export function buildQueryRecordFromClaim(claim) {
  if (!claim || typeof claim !== 'object') {
    return null
  }
  const claimId = String(claim.id || claim.claim_id || '').trim()
  if (!claimId) {
    return null
  }

  const status = String(claim.status || '').trim()
  const statusGroup = resolveExpenseStatusGroup(status)
  return {
    claim_id: claimId,
    claim_no: String(claim.claim_no || claim.claimNo || '').trim() || '未编号',
    employee_name: String(claim.employee_name || claim.employeeName || '').trim(),
    expense_type: String(claim.expense_type || claim.expenseType || '').trim(),
    expense_type_label: EXPENSE_TYPE_LABELS[String(claim.expense_type || claim.expenseType || '').trim()] || String(claim.expense_type || claim.expenseType || '报销').trim(),
    amount: Number(claim.amount || 0),
    status,
    status_label: EXPENSE_STATUS_LABELS[status] || statusGroup.label,
    status_group: statusGroup.key,
    status_group_label: statusGroup.label,
    approval_stage: String(claim.approval_stage || claim.approvalStage || '').trim(),
    document_date: formatQueryRecordDate(claim.submitted_at || claim.submittedAt || claim.created_at || claim.createdAt || claim.occurred_at || claim.occurredAt),
    occurred_at: formatQueryRecordDate(claim.occurred_at || claim.occurredAt),
    reason: String(claim.reason || '').trim(),
    location: String(claim.location || '').trim()
  }
}

export function buildDraftAssociationQueryPayload(claims) {
  const records = (Array.isArray(claims) ? claims : [])
    .filter((claim) => ASSOCIATABLE_CLAIM_STATUSES.has(String(claim?.status || '').trim()))
    .map(buildQueryRecordFromClaim)
    .filter(Boolean)

  const statusGroups = records.reduce((groups, record) => {
    const key = String(record.status_group || 'other')
    const existing = groups.get(key) || {
      key,
      label: String(record.status_group_label || '其他状态'),
      count: 0
    }
    existing.count += 1
    groups.set(key, existing)
    return groups
  }, new Map())

  return normalizeExpenseQueryPayload({
    result_type: 'expense_claim_list',
    title: '选择关联草稿',
    scope_label: '可关联草稿',
    selection_mode: 'draft_association',
    empty_text: '当前没有可关联的草稿单据。',
    recent_window_applied: false,
    record_count: records.length,
    preview_count: records.length,
    total_amount: records.reduce((sum, record) => sum + Number(record.amount || 0), 0),
    status_groups: Array.from(statusGroups.values()),
    records
  })
}

export function normalizeExpenseQueryPayload(payload) {
  if (!payload || typeof payload !== 'object') {
    return null
  }

  const resultType = String(payload.result_type || '').trim()
  if (resultType && resultType !== 'expense_claim_list') {
    return null
  }

  const records = (Array.isArray(payload.records) ? payload.records : [])
    .map(normalizeExpenseQueryRecord)
    .filter(Boolean)
  const statusGroups = (Array.isArray(payload.status_groups) ? payload.status_groups : [])
    .map(normalizeExpenseQueryStatusGroup)
    .filter(Boolean)

  const rawRecordCount = Number(payload.record_count || 0)
  const rawPreviewCount = Number(payload.preview_count || records.length)
  const rawPreviewLimit = Number(payload.preview_limit || EXPENSE_QUERY_PAGE_SIZE)
  const rawOlderRecordCount = Number(payload.older_record_count || 0)
  const totalAmount = Number(payload.total_amount || 0)
  const rawWindowDays = Number(payload.window_days || 0)
  const windowStartDate = String(payload.window_start_date || '').trim()
  const windowEndDate = String(payload.window_end_date || '').trim()

  return {
    resultType: 'expense_claim_list',
    scopeLabel: String(payload.scope_label || '报销单').trim() || '报销单',
    selectionMode: String(payload.selection_mode || payload.selectionMode || '').trim(),
    selectionLocked: Boolean(payload.selection_locked || payload.selectionLocked),
    selectedClaimId: String(payload.selected_claim_id || payload.selectedClaimId || '').trim(),
    title: String(payload.title || '').trim(),
    emptyText: String(payload.empty_text || payload.emptyText || '').trim(),
    recentWindowApplied: Boolean(payload.recent_window_applied),
    windowDays:
      payload.window_days === null || payload.window_days === undefined || payload.window_days === ''
        ? null
        : (Number.isFinite(rawWindowDays) ? Math.max(1, rawWindowDays) : null),
    windowStartDate: windowStartDate || '',
    windowEndDate: windowEndDate || '',
    recordCount: Number.isFinite(rawRecordCount) ? Math.max(0, rawRecordCount) : 0,
    previewCount: Number.isFinite(rawPreviewCount) ? Math.max(0, rawPreviewCount) : records.length,
    previewLimit: Number.isFinite(rawPreviewLimit) ? Math.max(1, rawPreviewLimit) : EXPENSE_QUERY_PAGE_SIZE,
    olderRecordCount: Number.isFinite(rawOlderRecordCount) ? Math.max(0, rawOlderRecordCount) : 0,
    hasMoreInWindow: Boolean(payload.has_more_in_window || payload.has_more),
    totalAmount: Number.isFinite(totalAmount) ? totalAmount : 0,
    statusGroups,
    records,
    currentPage: 1
  }
}

export function buildExpenseQueryWindowLabel(queryPayload) {
  if (!queryPayload) {
    return ''
  }

  if (queryPayload.selectionMode === 'draft_association') {
    return '先选择要关联的草稿，确认后我再识别附件并归集到该单据。'
  }
  if (queryPayload.selectionMode === 'reimbursement_application_association') {
    return '先确认是否关联申请单；选择关联后我会用申请单信息生成报销草稿。'
  }

  if (queryPayload.windowStartDate && queryPayload.windowEndDate) {
    return `${queryPayload.windowStartDate} 至 ${queryPayload.windowEndDate}`
  }

  if (queryPayload.recentWindowApplied && queryPayload.windowDays) {
    return `近 ${queryPayload.windowDays} 日内`
  }

  return '当前条件下'
}

export function getExpenseQueryTotalPages(queryPayload) {
  const recordCount = Array.isArray(queryPayload?.records) ? queryPayload.records.length : 0
  return Math.max(1, Math.ceil(recordCount / EXPENSE_QUERY_PAGE_SIZE))
}

export function getExpenseQueryActivePage(queryPayload) {
  const totalPages = getExpenseQueryTotalPages(queryPayload)
  const rawPage = Number(queryPayload?.currentPage || 1)
  if (!Number.isFinite(rawPage)) {
    return 1
  }
  return Math.min(Math.max(1, Math.round(rawPage)), totalPages)
}

export function getExpenseQueryVisibleRecords(queryPayload) {
  const records = Array.isArray(queryPayload?.records) ? queryPayload.records : []
  const activePage = getExpenseQueryActivePage(queryPayload)
  const start = (activePage - 1) * EXPENSE_QUERY_PAGE_SIZE
  return records.slice(start, start + EXPENSE_QUERY_PAGE_SIZE)
}

export function buildExpenseQueryHint(queryPayload) {
  if (!queryPayload) {
    return ''
  }

  if (queryPayload.selectionMode === 'draft_association') {
    if (queryPayload.selectionLocked && queryPayload.selectedClaimId) {
      return '已选择关联草稿，附件将按该单据继续识别和归集。'
    }
    return '如果这些都不是本次要关联的单据，可以补充单号或先到单据中心新建草稿。'
  }

  const parts = []
  const previewLimit = Math.max(1, Number(queryPayload.previewLimit || EXPENSE_QUERY_PAGE_SIZE))
  const totalCount = Math.max(0, Number(queryPayload.recordCount || 0))

  if (totalCount > previewLimit) {
    parts.push(`我只会筛选出最近的 ${previewLimit} 条记录；如果想查询全部的单据，请点击 [**这里**](${EXPENSE_CENTER_HREF}) 跳转到单据中心查看。`)
  } else if (totalCount > 0) {
    parts.push(`当前已展示本次筛选命中的全部记录；如果想进入单据中心继续筛选，请点击 [**这里**](${EXPENSE_CENTER_HREF})。`)
  }

  return parts.join('。')
}
