export interface DataPoint {
  x: number | Date
  y: number
}

export interface ChartSeries {
  label: string
  data: DataPoint[]
  color?: string
}

export interface ChartDimensions {
  width: number
  height: number
  paddingTop: number
  paddingRight: number
  paddingBottom: number
  paddingLeft: number
}

export function computeYScale(
  series: ChartSeries[],
  dims: ChartDimensions,
  threshold?: number,
) {
  const allY = series.flatMap((s) => s.data.map((d) => d.y))
  if (threshold != null) allY.push(threshold)
  const min = 0
  const max = Math.max(...allY, 1)
  const range = max - min

  const plotH = dims.height - dims.paddingTop - dims.paddingBottom
  const toY = (val: number) => dims.paddingTop + plotH - ((val - min) / range) * plotH

  return { min, max, range, toY }
}

export function computeXScale(series: ChartSeries[], dims: ChartDimensions) {
  const allX = series.flatMap((s) =>
    s.data.map((d) => (d.x instanceof Date ? d.x.getTime() : d.x)),
  )
  const minX = Math.min(...allX)
  const maxX = Math.max(...allX)
  const rangeX = maxX - minX || 1

  const plotW = dims.width - dims.paddingLeft - dims.paddingRight
  const toX = (val: number | Date) => {
    const v = val instanceof Date ? val.getTime() : val
    return dims.paddingLeft + ((v - minX) / rangeX) * plotW
  }

  return { minX, maxX, rangeX, toX }
}

export function seriesPoints(
  series: ChartSeries,
  toX: (v: number | Date) => number,
  toY: (v: number) => number,
): string {
  return series.data.map((d) => `${toX(d.x).toFixed(1)},${toY(d.y).toFixed(1)}`).join(' ')
}

export function seriesPath(
  series: ChartSeries,
  toX: (v: number | Date) => number,
  toY: (v: number) => number,
  bottomY: number,
): string {
  if (series.data.length === 0) return ''
  const pts = series.data.map((d) => `${toX(d.x).toFixed(1)},${toY(d.y).toFixed(1)}`)
  const firstX = toX(series.data[0].x).toFixed(1)
  const lastX = toX(series.data[series.data.length - 1].x).toFixed(1)
  return `M${pts.join(' L')} L${lastX},${bottomY} L${firstX},${bottomY} Z`
}

export function formatAxisLabel(val: number): string {
  if (val >= 1_000_000) return `${(val / 1_000_000).toFixed(1)}M`
  if (val >= 1000) return `${(val / 1000).toFixed(1)}k`
  if (Number.isInteger(val)) return String(val)
  return val.toFixed(1)
}

export function formatXLabel(val: number | Date, _totalPoints: number): string {
  if (val instanceof Date || (typeof val === 'number' && val > 1e10)) {
    const d = val instanceof Date ? val : new Date(val)
    return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
  }
  return formatAxisLabel(val as number)
}

// Default color tokens for series (fallback when no color given)
export const CHART_COLORS = [
  'var(--chart-1)',
  'var(--chart-2)',
  'var(--chart-3)',
  'var(--chart-4)',
  'var(--chart-5)',
  'var(--chart-6)',
  'var(--chart-7)',
  'var(--chart-8)',
]
