const LOCATION_BANDS = {
  premium: ['北京', '上海', '广州', '深圳', '杭州', '南京', '苏州', '成都', '重庆', '天津'],
  remote: ['新疆', '西藏', '青海', '甘肃', '宁夏', '内蒙古', '海南', '香港', '澳门', '台湾', '海外', '国外'],
  coastal: ['上海', '广州', '深圳', '厦门', '福州', '青岛', '大连', '宁波', '舟山', '海口', '三亚', '天津']
}

const TRANSPORT_PRICE_BASE = {
  火车: { default: 360, premium: 520, remote: 900, coastal: 520 },
  飞机: { default: 600, premium: 650, remote: 1600, coastal: 700 },
  轮船: { default: 320, premium: 480, remote: 680, coastal: 520 }
}

function normalizeTransportMode(value = '') {
  const text = String(value || '').trim()
  if (/飞机|机票|航班|乘机|坐飞机/.test(text)) return '飞机'
  if (/轮船|船票|客轮|渡轮|邮轮|坐船/.test(text)) return '轮船'
  if (/火车|高铁|动车|铁路|列车/.test(text)) return '火车'
  return TRANSPORT_PRICE_BASE[text] ? text : ''
}

function resolveLocationBand(location = '') {
  const text = String(location || '').trim()
  if (LOCATION_BANDS.remote.some((keyword) => text.includes(keyword))) return 'remote'
  if (LOCATION_BANDS.premium.some((keyword) => text.includes(keyword))) return 'premium'
  if (LOCATION_BANDS.coastal.some((keyword) => text.includes(keyword))) return 'coastal'
  return 'default'
}

function roundToTen(value) {
  return Math.round(Number(value || 0) / 10) * 10
}

function parseApplicationEstimateDate(value = '') {
  const match = String(value || '').match(/(20\d{2})[年\-/.](\d{1,2})[月\-/.](\d{1,2})/)
  if (!match) return ''
  const year = Number(match[1])
  const month = Number(match[2])
  const day = Number(match[3])
  const parsed = new Date(Date.UTC(year, month - 1, day))
  if (
    Number.isNaN(parsed.getTime()) ||
    parsed.getUTCFullYear() !== year ||
    parsed.getUTCMonth() !== month - 1 ||
    parsed.getUTCDate() !== day
  ) {
    return ''
  }
  return parsed.toISOString().slice(0, 10)
}

function resolveTicketPriceFactor(queryDate = '') {
  if (!queryDate) return 1
  const parsed = new Date(`${queryDate}T00:00:00.000Z`)
  if (Number.isNaN(parsed.getTime())) return 1

  let factor = 1
  const weekday = parsed.getUTCDay()
  const month = parsed.getUTCMonth() + 1
  if (weekday === 1) factor += 0.04
  if (weekday === 5 || weekday === 0) factor += 0.08
  if ([1, 2, 7, 8, 10].includes(month)) factor += 0.06

  const jitter = (parsed.getUTCFullYear() + month * 13 + parsed.getUTCDate() * 7) % 7 - 3
  factor += jitter * 0.01
  return Math.min(1.22, Math.max(0.88, factor))
}

function resolveMockQueryLatencyMs(queryDate = '', mode = '', locationBand = '') {
  let seed = String(mode || '').length * 43 + String(locationBand || '').length * 29
  if (queryDate) {
    const parsed = new Date(`${queryDate}T00:00:00.000Z`)
    if (!Number.isNaN(parsed.getTime())) {
      seed += parsed.getUTCFullYear() + (parsed.getUTCMonth() + 1) * 17 + parsed.getUTCDate() * 31
    }
  }
  return 360 + (seed % 420)
}

export function parseApplicationEstimateMoney(value) {
  if (typeof value === 'number') return Number.isFinite(value) ? value : 0
  const normalized = String(value ?? '').replace(/,/g, '').replace(/[^\d.-]/g, '')
  const amount = Number(normalized)
  return Number.isFinite(amount) ? amount : 0
}

export function formatApplicationEstimateMoney(value) {
  const amount = parseApplicationEstimateMoney(value)
  return new Intl.NumberFormat('zh-CN', {
    minimumFractionDigits: 0,
    maximumFractionDigits: Number.isInteger(amount) ? 0 : 2
  }).format(amount)
}

export function buildMockApplicationTransportEstimate({
  transportMode = '',
  location = '',
  travelDate = '',
  time = ''
} = {}) {
  const mode = normalizeTransportMode(transportMode)
  if (!mode) return null

  const locationBand = resolveLocationBand(location)
  const queryDate = parseApplicationEstimateDate(travelDate) || parseApplicationEstimateDate(time)
  const priceFactor = resolveTicketPriceFactor(queryDate)
  const simulatedLatencyMs = resolveMockQueryLatencyMs(queryDate, mode, locationBand)
  const priceConfig = TRANSPORT_PRICE_BASE[mode] || TRANSPORT_PRICE_BASE.火车
  const oneWayAmount = priceConfig[locationBand] || priceConfig.default
  const amount = roundToTen(oneWayAmount * 2 * priceFactor)
  const amountDisplay = formatApplicationEstimateMoney(amount)
  const bandLabel = {
    premium: '一线/高频城市',
    remote: '远途地区',
    coastal: '沿海城市',
    default: '普通城市'
  }[locationBand]
  const queryLabel = queryDate || '出行日期待确认'

  return {
    mode,
    amount,
    amountDisplay,
    routeType: '往返',
    locationBand,
    queryDate,
    priceFactor,
    simulatedLatencyMs,
    source: 'fallback_transport_budget_estimate_v1',
    confidence: 'fallback',
    basisText: `预估交通费用 ${amountDisplay}元`
  }
}

export function resolveMockApplicationTransportWaitMs(estimate = null) {
  const latency = Number(estimate?.simulatedLatencyMs || 0)
  return Number.isFinite(latency) && latency > 0
    ? Math.min(320, Math.max(180, latency))
    : 0
}

export async function waitForMockApplicationTransportQuote(options = {}) {
  const estimate = buildMockApplicationTransportEstimate(options)
  const waitMs = resolveMockApplicationTransportWaitMs(estimate)
  if (waitMs > 0) {
    await new Promise((resolve) => setTimeout(resolve, waitMs))
  }
  return estimate
}

export function buildSystemApplicationEstimate({
  transportMode = '',
  location = '',
  travelDate = '',
  time = '',
  lodgingAmount = 0,
  allowanceAmount = 0
} = {}) {
  const transportEstimate = buildMockApplicationTransportEstimate({
    transportMode,
    location,
    travelDate,
    time
  })
  const transportAmount = transportEstimate?.amount || 0
  const lodging = parseApplicationEstimateMoney(lodgingAmount)
  const allowance = parseApplicationEstimateMoney(allowanceAmount)
  const totalAmount = transportAmount + lodging + allowance

  return {
    transportEstimate,
    transportAmount,
    lodgingAmount: lodging,
    allowanceAmount: allowance,
    totalAmount,
    transportAmountDisplay: transportEstimate ? transportEstimate.amountDisplay : '',
    lodgingAmountDisplay: formatApplicationEstimateMoney(lodging),
    allowanceAmountDisplay: formatApplicationEstimateMoney(allowance),
    totalAmountDisplay: formatApplicationEstimateMoney(totalAmount)
  }
}
