export const DEFAULT_OVERVIEW_RANGE = '近10日'

const DAY_MS = 24 * 60 * 60 * 1000
const RISK_DAILY_TREND_MAX_BUCKETS = 14

function parseLocalDate(value) {
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(value || '').trim())
  if (!match) {
    return null
  }
  const date = new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]))
  return Number.isNaN(date.getTime()) ? null : date
}

function clampWindowDays(value) {
  const days = Number(value || 0)
  if (!Number.isFinite(days) || days <= 0) {
    return 10
  }
  return Math.max(1, Math.min(Math.round(days), 90))
}

function resolveCustomRangeDays(customRange = {}) {
  const start = parseLocalDate(customRange.start)
  const end = parseLocalDate(customRange.end)
  if (!start || !end) {
    return 10
  }
  return clampWindowDays(Math.abs(end.getTime() - start.getTime()) / DAY_MS + 1)
}

export function resolveTopRangeDays(range, customRange = {}) {
  const key = String(range || DEFAULT_OVERVIEW_RANGE).trim()
  if (key === 'custom') {
    return resolveCustomRangeDays(customRange)
  }
  if (key === '\u4eca\u65e5') {
    return 1
  }
  if (key === '\u672c\u5468') {
    const today = new Date()
    const weekday = today.getDay() || 7
    return clampWindowDays(weekday)
  }
  if (key === '\u672c\u6708') {
    return clampWindowDays(new Date().getDate())
  }
  const match = key.match(/\d+/)
  return clampWindowDays(match ? Number(match[0]) : 10)
}

export function resolveTopRangeKey(range, customRange = {}) {
  const key = String(range || DEFAULT_OVERVIEW_RANGE).trim()
  if (key === 'custom') {
    return 'custom'
  }
  if (key === '\u672c\u5468' || key === '\u4eca\u65e5') {
    return `recent-${resolveTopRangeDays(key, customRange)}-days`
  }
  if (/\d+/.test(key)) {
    return `recent-${resolveTopRangeDays(key, customRange)}-days`
  }
  return key || DEFAULT_OVERVIEW_RANGE
}

function formatRiskTrendDateLabel(value) {
  const date = parseLocalDate(value)
  if (!date) {
    return String(value || '-').trim() || '-'
  }
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  return `${month}-${day}`
}

function buildRiskTrendBucketLabel(first, last) {
  const start = String(first?.date || '').trim()
  const end = String(last?.date || '').trim()
  if (!start || start === end) {
    return formatRiskTrendDateLabel(start)
  }
  return `${formatRiskTrendDateLabel(start)}~${formatRiskTrendDateLabel(end)}`
}

function normalizeRiskTrendRow(item) {
  return {
    date: String(item.date || '').trim() || '-',
    total: Number(item.total || 0),
    highOrAbove: Number(item.high_or_above ?? item.highOrAbove ?? 0)
  }
}

export function aggregateRiskDailyTrendRows(rows, maxBuckets = RISK_DAILY_TREND_MAX_BUCKETS) {
  const normalizedRows = rows
    .map(normalizeRiskTrendRow)
    .filter((item) => item.date !== '-' || item.total > 0 || item.highOrAbove > 0)

  if (normalizedRows.length <= maxBuckets) {
    return normalizedRows.map((item) => ({
      ...item,
      date: formatRiskTrendDateLabel(item.date),
      sourceStartDate: item.date,
      sourceEndDate: item.date
    }))
  }

  const bucketSize = Math.ceil(normalizedRows.length / maxBuckets)
  const buckets = []
  for (let index = 0; index < normalizedRows.length; index += bucketSize) {
    const bucketRows = normalizedRows.slice(index, index + bucketSize)
    const first = bucketRows[0]
    const last = bucketRows[bucketRows.length - 1]
    buckets.push({
      date: buildRiskTrendBucketLabel(first, last),
      sourceStartDate: first?.date || '',
      sourceEndDate: last?.date || '',
      total: bucketRows.reduce((sum, item) => sum + item.total, 0),
      highOrAbove: bucketRows.reduce((sum, item) => sum + item.highOrAbove, 0)
    })
  }
  return buckets
}
