export type ChartType = 'pie' | 'donut' | 'line' | 'bar' | 'bar-horizontal' | 'line-bar'

export interface ChartDatasetInput {
  label: string
  data: number[]
  type?: 'line' | 'bar'
  color?: string
}

export interface BuildOptionCtx {
  palette: string[]
  legendColor: string
  fontFamily: string
  /** Resolved divider colour for axis lines, ticks and grid split lines (theme-aware). */
  axisLineColor: string
}

interface BuildProps {
  type: ChartType
  datasets: ChartDatasetInput[]
  labels: string[]
}

export function buildChartOption(props: BuildProps, ctx: BuildOptionCtx): Record<string, any> {
  const legend = {
    bottom: 0,
    icon: 'circle',
    itemWidth: 8,
    itemHeight: 8,
    textStyle: { color: ctx.legendColor, fontFamily: ctx.fontFamily, fontSize: 12 },
  }

  if (props.type === 'pie' || props.type === 'donut') {
    const first = props.datasets[0]
    return {
      color: ctx.palette,
      legend,
      tooltip: { trigger: 'item' },
      series: [{
        type: 'pie',
        radius: props.type === 'donut' ? ['40%', '70%'] : '70%',
        // Slice labels off: the bottom legend already identifies every slice, and
        // ECharts' default outside labels + leader lines clutter / clip in the
        // design system's narrow chart cards.
        label: { show: false },
        data: (first?.data ?? []).map((value, i) => ({ value, name: props.labels[i] ?? String(i) })),
      }],
    }
  }

  const isHorizontal = props.type === 'bar-horizontal'
  // Axis lines / ticks / grid split lines all use the theme-aware divider colour
  // (resolved from --line-divider-light); tick labels reuse the legend text colour.
  // Without these ECharts falls back to a built-in light grey that reads as white
  // in the dark theme.
  const axisLabel = { color: ctx.legendColor }
  const axisLine = { lineStyle: { color: ctx.axisLineColor } }
  const axisTick = { lineStyle: { color: ctx.axisLineColor } }
  const splitLine = { lineStyle: { color: ctx.axisLineColor } }
  const categoryAxis = { type: 'category', data: props.labels, axisLine, axisTick, axisLabel }
  const valueAxis = { type: 'value', axisLine, axisTick, axisLabel, splitLine }

  const series = props.datasets.map((d) => {
    const seriesType =
      props.type === 'line' ? 'line'
      : props.type === 'bar' || props.type === 'bar-horizontal' ? 'bar'
      : (d.type ?? 'bar')
    return {
      name: d.label,
      type: seriesType,
      data: d.data,
      ...(d.color ? { itemStyle: { color: d.color } } : {}),
    }
  })

  return {
    color: ctx.palette,
    legend,
    tooltip: { trigger: 'axis' },
    // containLabel lets the grid auto-reserve room for axis category labels, so
    // long labels (e.g. bar-horizontal's Y-axis categories) are never clipped by
    // the narrow chart card's left edge.
    grid: { containLabel: true },
    xAxis: isHorizontal ? valueAxis : categoryAxis,
    yAxis: isHorizontal ? categoryAxis : valueAxis,
    series,
  }
}
