import {
  BUDGET_VISIBLE_EXPENSE_TYPE_OPTIONS,
  formatBudgetPeriod
} from '../../utils/budgetOntology.js'

export const BUDGET_SCOPE_ALL = 'all'
export const BUDGET_SCOPE_REVIEW = 'review'
export const BUDGET_SCOPE_ARCHIVE = 'archive'

export const BUDGET_SCOPE_TABS = Object.freeze([
  { value: BUDGET_SCOPE_ALL, label: '全部预算' },
  { value: BUDGET_SCOPE_REVIEW, label: '预算审核' },
  { value: BUDGET_SCOPE_ARCHIVE, label: '归档预算' }
])

export const BUDGET_PAGE_SIZE_OPTIONS = Object.freeze([8, 12, 20])

const STATUS_OPTIONS_BY_SCOPE = Object.freeze({
  [BUDGET_SCOPE_ALL]: ['全部', '正常', '预警', '管控'],
  [BUDGET_SCOPE_REVIEW]: ['全部', '待审核', '复核中', '待补充', '已驳回'],
  [BUDGET_SCOPE_ARCHIVE]: ['全部', '已归档', '已替换', '已驳回']
})

const DEPARTMENT_PROFILE = Object.freeze({
  'MARKET-DEPT': { factor: 1.22, owner: '周明悦', reviewer: '陈思远', riskShift: 12 },
  'FINANCE-DEPT': { factor: 0.74, owner: '韩清', reviewer: '沈知行', riskShift: -6 },
  'TECH-DEPT': { factor: 1.08, owner: '林子昂', reviewer: '陈思远', riskShift: 4 },
  'HR-DEPT': { factor: 0.68, owner: '许婉', reviewer: '沈知行', riskShift: 2 },
  'PRODUCTION-DEPT': { factor: 1.36, owner: '赵屿', reviewer: '陈思远', riskShift: 8 },
  'PRESIDENT-OFFICE': { factor: 0.92, owner: '孟澜', reviewer: '沈知行', riskShift: -2 }
})

const DEFAULT_PROFILE = Object.freeze({
  factor: 1,
  owner: '预算编制助手',
  reviewer: '高级财务人员',
  riskShift: 0
})

const CATEGORY_SEED = Object.freeze({
  travel: { total: 600000, used: 242300, occupied: 150000, warning: 80 },
  communication: { total: 120000, used: 38600, occupied: 18000, warning: 70 },
  meal: { total: 420000, used: 168200, occupied: 118000, warning: 80 },
  office: { total: 180000, used: 68500, occupied: 32000, warning: 70 }
})

const QUARTER_FACTOR = Object.freeze({
  Q1: 0.92,
  Q2: 1,
  Q3: 1.12,
  Q4: 1.18
})

const REVIEW_STATUS_SEQUENCE = ['待审核', '待审核', '复核中', '待补充', '待审核', '已驳回']
const ARCHIVE_STATUS_SEQUENCE = ['已归档', '已替换', '已驳回', '已归档', '已替换', '已归档']

export function currency(value) {
  return Number(value || 0).toLocaleString('zh-CN', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  })
}

export function money(value) {
  return `¥${currency(value)}`
}

export function getBudgetStatusOptions(scope) {
  return STATUS_OPTIONS_BY_SCOPE[scope] || STATUS_OPTIONS_BY_SCOPE[BUDGET_SCOPE_ALL]
}

export function buildBudgetScopeTabs(rowsByScope) {
  return BUDGET_SCOPE_TABS.map((tab) => ({
    ...tab,
    count: Array.isArray(rowsByScope?.[tab.value]) ? rowsByScope[tab.value].length : 0
  }))
}

export function buildBudgetRows({ departments = [], year = '2026', quarter = 'Q1' } = {}) {
  const scopedDepartments = Array.isArray(departments) ? departments : []
  return {
    [BUDGET_SCOPE_ALL]: scopedDepartments.map((department, index) =>
      buildActiveBudgetRow(department, index, { year, quarter })
    ),
    [BUDGET_SCOPE_REVIEW]: scopedDepartments.map((department, index) =>
      buildReviewBudgetRow(department, index, { year, quarter })
    ),
    [BUDGET_SCOPE_ARCHIVE]: scopedDepartments.map((department, index) =>
      buildArchiveBudgetRow(department, index, { year, quarter })
    )
  }
}

export function buildBudgetUsageData(row) {
  const categories = Array.isArray(row?.categoryRows) ? row.categoryRows : []
  return {
    labels: categories.map((item) => item.name),
    budget: categories.map((item) => item.amount),
    used: categories.map((item) => item.used),
    occupied: categories.map((item) => item.occupied),
    available: categories.map((item) => item.available)
  }
}

export function matchesBudgetKeyword(row, keyword) {
  const normalized = String(keyword || '').trim().toLowerCase()
  if (!normalized) return true
  return String(row?.searchText || '').includes(normalized)
}

function buildActiveBudgetRow(department, index, context) {
  const profile = resolveProfile(department)
  const categoryRows = buildCategoryRows(department, index, context)
  const totals = summarizeCategories(categoryRows)
  const risk = resolveRisk(totals.usageRate)
  const periodLabel = formatBudgetPeriod(context.year, context.quarter)
  const budgetNo = `BUD-${context.year}-${department.code || index + 1}`

  return enrichSearchText({
    id: `${budgetNo}-ACTIVE`,
    scope: BUDGET_SCOPE_ALL,
    budgetNo,
    departmentCode: department.code || '',
    departmentName: department.name || '当前部门',
    costCenter: department.costCenter || '',
    periodLabel,
    periodType: '季度预算',
    budgetYear: `${context.year}年度`,
    budgetQuarter: context.quarter,
    version: `V${index + 1}.0`,
    owner: profile.owner,
    reviewer: profile.reviewer,
    annualAmount: totals.annualAmount,
    quarterAmount: totals.total,
    monthAmount: totals.total / 3,
    usedAmount: totals.used,
    occupiedAmount: totals.occupied,
    availableAmount: totals.available,
    annualAmountLabel: money(totals.annualAmount),
    quarterAmountLabel: money(totals.total),
    monthAmountLabel: money(totals.total / 3),
    usedAmountLabel: money(totals.used),
    occupiedAmountLabel: money(totals.occupied),
    availableAmountLabel: money(totals.available),
    usageRate: totals.usageRate,
    usageRateLabel: `${totals.usageRate}%`,
    riskTone: risk.tone,
    riskLabel: risk.label,
    statusLabel: risk.tone === 'risk' ? '管控' : risk.tone === 'alert' ? '预警' : '正常',
    statusTone: risk.tone,
    updatedAt: `2026-05-${String(28 - index).padStart(2, '0')} 16:${String(20 + index).padStart(2, '0')}`,
    categoryRows,
    periodRows: buildPeriodRows(totals),
    auditSummary: '已通过高级财务审核并发布为正式预算。',
    actionLabel: '查看详情'
  })
}

function buildReviewBudgetRow(department, index, context) {
  const activeRow = buildActiveBudgetRow(department, index, context)
  const profile = resolveProfile(department)
  const statusLabel = REVIEW_STATUS_SEQUENCE[index % REVIEW_STATUS_SEQUENCE.length]
  const applyFactor = 1 + (index % 3) * 0.06 + Math.max(profile.riskShift, 0) / 200
  const requestedAmount = activeRow.quarterAmount * applyFactor
  const changeRate = Number(((requestedAmount / activeRow.quarterAmount - 1) * 100).toFixed(1))
  const risk = resolveRisk(activeRow.usageRate + profile.riskShift)
  const categoryRows = activeRow.categoryRows.map((item) => ({
    ...item,
    amount: Math.round(item.amount * applyFactor),
    amountLabel: money(Math.round(item.amount * applyFactor)),
    note: buildReviewNote(item.name, risk.tone)
  }))

  return enrichSearchText({
    ...activeRow,
    id: `${activeRow.budgetNo}-DRAFT`,
    scope: BUDGET_SCOPE_REVIEW,
    budgetNo: `DRF-${context.year}-${department.code || index + 1}`,
    periodType: '预算草案',
    version: `草案 V1.${index}`,
    compiler: profile.owner,
    submittedAt: `2026-05-${String(26 + (index % 3)).padStart(2, '0')} ${String(10 + index).padStart(2, '0')}:20`,
    requestedAmount,
    requestedAmountLabel: money(requestedAmount),
    previousAmountLabel: activeRow.quarterAmountLabel,
    changeRate,
    changeRateLabel: `${changeRate >= 0 ? '+' : ''}${changeRate}%`,
    aiScore: Math.max(68, Math.min(94, 88 - index * 2 - Math.max(profile.riskShift, 0))),
    riskTone: risk.tone,
    riskLabel: risk.label,
    statusLabel,
    statusTone: resolveReviewStatusTone(statusLabel),
    categoryRows,
    periodRows: buildPeriodRows({
      total: requestedAmount,
      annualAmount: requestedAmount * 4,
      used: activeRow.usedAmount,
      occupied: activeRow.occupiedAmount,
      available: Math.max(requestedAmount - activeRow.usedAmount - activeRow.occupiedAmount, 0),
      usageRate: percent(activeRow.usedAmount + activeRow.occupiedAmount, requestedAmount)
    }),
    auditSummary: '等待高级财务人员审核，审核通过后才能发布到正式预算中心。',
    actionLabel: '进入审核'
  })
}

function buildArchiveBudgetRow(department, index, context) {
  const activeRow = buildActiveBudgetRow(department, index, context)
  const statusLabel = ARCHIVE_STATUS_SEQUENCE[index % ARCHIVE_STATUS_SEQUENCE.length]
  const archiveFactor = statusLabel === '已驳回' ? 0.96 : 0.9

  return enrichSearchText({
    ...activeRow,
    id: `${activeRow.budgetNo}-ARCHIVE`,
    scope: BUDGET_SCOPE_ARCHIVE,
    budgetNo: `ARC-${context.year}-${department.code || index + 1}`,
    version: `历史 V${Math.max(1, index)}.${index % 3}`,
    periodType: '历史预算',
    archiveType: statusLabel === '已驳回' ? '审核驳回' : statusLabel === '已替换' ? '版本替换' : '周期归档',
    quarterAmount: activeRow.quarterAmount * archiveFactor,
    quarterAmountLabel: money(activeRow.quarterAmount * archiveFactor),
    reviewer: resolveProfile(department).reviewer,
    archivedAt: `2026-05-${String(12 + index).padStart(2, '0')} 18:00`,
    statusLabel,
    statusTone: statusLabel === '已驳回' ? 'risk' : 'archived',
    auditSummary: statusLabel === '已驳回'
      ? '该预算版本未通过审核，已保留驳回记录。'
      : '该预算版本已进入历史归档，可用于审计追溯。',
    actionLabel: '查看归档'
  })
}

function buildCategoryRows(department, index, context) {
  const profile = resolveProfile(department)
  const quarterFactor = QUARTER_FACTOR[context.quarter] || 1
  const usageShift = 1 + profile.riskShift / 100
  return BUDGET_VISIBLE_EXPENSE_TYPE_OPTIONS.map((option, categoryIndex) => {
    const seed = CATEGORY_SEED[option.value] || { total: 100000, used: 0, occupied: 0, warning: 70 }
    const amount = Math.round(seed.total * profile.factor * quarterFactor * (1 + categoryIndex * 0.015))
    const used = Math.round(seed.used * profile.factor * usageShift)
    const occupied = Math.round(seed.occupied * profile.factor * Math.max(0.8, usageShift))
    const available = Math.max(amount - used - occupied, 0)
    const usageRate = percent(used + occupied, amount)
    const thresholds = buildThresholds(seed.warning)
    const risk = resolveRisk(usageRate, thresholds)

    return {
      code: option.value,
      name: option.label,
      amount,
      used,
      occupied,
      available,
      amountLabel: money(amount),
      usedLabel: money(used),
      occupiedLabel: money(occupied),
      availableLabel: money(available),
      usageRate,
      usageRateLabel: `${usageRate}%`,
      reminderLine: `${thresholds.reminder}%`,
      alertLine: `${thresholds.alert}%`,
      riskLine: `${thresholds.risk}%`,
      riskTone: risk.tone,
      riskLabel: risk.label,
      note: buildCategoryNote(option.label, risk.tone, index)
    }
  })
}

function buildPeriodRows(totals) {
  return [
    { label: '年度预算', value: money(totals.annualAmount), desc: '按四类费用预算汇总' },
    { label: '季度预算', value: money(totals.total), desc: '当前列表筛选周期' },
    { label: '月度预算', value: money(totals.total / 3), desc: '按季度预算月均拆分' }
  ]
}

function summarizeCategories(rows) {
  const total = rows.reduce((sum, item) => sum + item.amount, 0)
  const used = rows.reduce((sum, item) => sum + item.used, 0)
  const occupied = rows.reduce((sum, item) => sum + item.occupied, 0)
  const available = Math.max(total - used - occupied, 0)
  return {
    total,
    annualAmount: total * 4,
    used,
    occupied,
    available,
    usageRate: percent(used + occupied, total)
  }
}

function resolveProfile(department) {
  return {
    ...DEFAULT_PROFILE,
    ...(DEPARTMENT_PROFILE[department?.code] || {})
  }
}

function percent(value, total) {
  if (!Number(total)) return 0
  return Number(((Number(value || 0) / Number(total)) * 100).toFixed(1))
}

function buildThresholds(warning) {
  const alert = clampPercent(warning)
  return {
    reminder: clampPercent(alert - 10),
    alert,
    risk: clampPercent(alert + 10)
  }
}

function clampPercent(value) {
  return Math.min(100, Math.max(0, Number(value) || 0))
}

function resolveRisk(value, thresholds = { reminder: 70, alert: 80, risk: 90 }) {
  const rate = Number(value || 0)
  if (rate >= thresholds.risk) return { label: '风险', tone: 'risk' }
  if (rate >= thresholds.alert) return { label: '告警', tone: 'alert' }
  if (rate >= thresholds.reminder) return { label: '提醒', tone: 'reminder' }
  return { label: '正常', tone: 'ok' }
}

function resolveReviewStatusTone(status) {
  if (status === '待补充') return 'alert'
  if (status === '已驳回') return 'risk'
  if (status === '复核中') return 'reminder'
  return 'pending'
}

function buildCategoryNote(name, tone, index) {
  if (tone === 'risk') return `${name}使用率已接近风险线，需要重点复核。`
  if (tone === 'alert') return `${name}超过告警线，建议核对业务计划和已占用金额。`
  if (tone === 'reminder') return `${name}接近提醒线，后续应持续观察。`
  return index % 2 === 0 ? `${name}预算执行稳定。` : `${name}仍在正常预算区间。`
}

function buildReviewNote(name, tone) {
  if (tone === 'risk') return `${name}预算增幅较高，审核时需要补充业务依据。`
  if (tone === 'alert') return `${name}建议结合上一季度发生额复核。`
  return `${name}建议按部门编制说明核对。`
}

function enrichSearchText(row) {
  const values = [
    row.budgetNo,
    row.departmentName,
    row.costCenter,
    row.periodLabel,
    row.periodType,
    row.version,
    row.owner,
    row.compiler,
    row.reviewer,
    row.statusLabel,
    row.riskLabel,
    row.archiveType
  ]
  return {
    ...row,
    searchText: values.filter(Boolean).join(' ').toLowerCase()
  }
}
