import { describe, it, expect } from 'vitest'
import { buildChartOption } from '../src/components/Chart/build-chart-option'

const ctx = { palette: ['#c1', '#c2', '#c3'], legendColor: '#leg', fontFamily: 'Roboto', axisLineColor: '#div' }
const ds = [{ label: 'A', data: [1, 2, 3] }]

describe('buildChartOption', () => {
  it('pie → single pie series, data mapped to {value,name} via labels', () => {
    const o: any = buildChartOption({ type: 'pie', datasets: ds, labels: ['x', 'y', 'z'] }, ctx)
    expect(o.series[0].type).toBe('pie')
    expect(o.series[0].radius).toBe('70%')
    expect(o.series[0].data).toEqual([{ value: 1, name: 'x' }, { value: 2, name: 'y' }, { value: 3, name: 'z' }])
    expect(o.color).toBe(ctx.palette)
  })
  it('donut → pie series with ring radius', () => {
    const o: any = buildChartOption({ type: 'donut', datasets: ds, labels: ['x', 'y', 'z'] }, ctx)
    expect(o.series[0].type).toBe('pie')
    expect(o.series[0].radius).toEqual(['40%', '70%'])
  })
  it('bar → category xAxis + value yAxis + bar series', () => {
    const o: any = buildChartOption({ type: 'bar', datasets: ds, labels: ['x', 'y', 'z'] }, ctx)
    expect(o.xAxis.type).toBe('category')
    expect(o.xAxis.data).toEqual(['x', 'y', 'z'])
    expect(o.yAxis.type).toBe('value')
    expect(o.series[0].type).toBe('bar')
    expect(o.series[0].data).toEqual([1, 2, 3])
  })
  it('bar-horizontal → axes swapped (value x / category y)', () => {
    const o: any = buildChartOption({ type: 'bar-horizontal', datasets: ds, labels: ['x', 'y', 'z'] }, ctx)
    expect(o.xAxis.type).toBe('value')
    expect(o.yAxis.type).toBe('category')
    expect(o.series[0].type).toBe('bar')
  })
  it('line → line series on category axis', () => {
    const o: any = buildChartOption({ type: 'line', datasets: ds, labels: ['x'] }, ctx)
    expect(o.series[0].type).toBe('line')
  })
  it('line-bar → per-dataset type decides line vs bar', () => {
    const mixed = [{ label: 'L', data: [1], type: 'line' as const }, { label: 'B', data: [2], type: 'bar' as const }]
    const o: any = buildChartOption({ type: 'line-bar', datasets: mixed, labels: ['x'] }, ctx)
    expect(o.series[0].type).toBe('line')
    expect(o.series[1].type).toBe('bar')
  })
  it('legend uses circle icon 8px + token colour + font', () => {
    const o: any = buildChartOption({ type: 'bar', datasets: ds, labels: ['x'] }, ctx)
    expect(o.legend.icon).toBe('circle')
    expect(o.legend.itemWidth).toBe(8)
    expect(o.legend.textStyle.color).toBe('#leg')
    expect(o.legend.textStyle.fontFamily).toBe('Roboto')
    expect(o.legend.textStyle.fontSize).toBe(12)
  })
  it('dataset.color overrides palette for that series', () => {
    const o: any = buildChartOption({ type: 'bar', datasets: [{ label: 'A', data: [1], color: '#zzz' }], labels: ['x'] }, ctx)
    expect(o.series[0].itemStyle.color).toBe('#zzz')
  })

  it('pie/donut hide slice labels (legend-only, avoids leader-line clutter in narrow cards)', () => {
    for (const type of ['pie', 'donut'] as const) {
      const o: any = buildChartOption({ type, datasets: ds, labels: ['x', 'y', 'z'] }, ctx)
      expect(o.series[0].label).toEqual({ show: false })
    }
  })

  it('cartesian charts set grid.containLabel so axis category labels are never clipped', () => {
    for (const type of ['bar', 'bar-horizontal', 'line', 'line-bar'] as const) {
      const o: any = buildChartOption({ type, datasets: ds, labels: ['x', 'y', 'z'] }, ctx)
      expect(o.grid.containLabel).toBe(true)
    }
    // pie/donut have no cartesian grid
    const pieOpt: any = buildChartOption({ type: 'pie', datasets: ds, labels: ['x'] }, ctx)
    expect(pieOpt.grid).toBeUndefined()
  })

  it('cartesian axes are token-driven (splitLine/axisLine use divider colour, labels use text colour)', () => {
    const o: any = buildChartOption({ type: 'bar', datasets: ds, labels: ['x'] }, ctx)
    // value axis carries the horizontal grid split lines (the ones that showed white in dark mode)
    expect(o.yAxis.splitLine.lineStyle.color).toBe('#div')
    // category axis carries the base axis line
    expect(o.xAxis.axisLine.lineStyle.color).toBe('#div')
    // tick labels reuse the resolved text colour (same token as the legend)
    expect(o.xAxis.axisLabel.color).toBe('#leg')
    expect(o.yAxis.axisLabel.color).toBe('#leg')
  })

  it('bar-horizontal value xAxis carries the (previously white) split lines, token-driven', () => {
    const o: any = buildChartOption({ type: 'bar-horizontal', datasets: ds, labels: ['x'] }, ctx)
    expect(o.xAxis.splitLine.lineStyle.color).toBe('#div')
  })
})
