import type { AnyChartInput } from '@/types/chart'
import type { ChartPlan } from '@/lib/plan'
import {
  barFromTable,
  heatmapFromTable,
  lineFromTable,
  pieFromTable,
  type Table,
} from '@/lib/table'

/**
 * Turn an LLM ChartPlan + a {columns, data} table into
 * an ECharts-ready input for ChartRenderer.
 */
export function executePlan(table: Table, plan: ChartPlan): AnyChartInput | null {
  if (!plan) return null
  if (plan.kind === 'line') {
    const m = plan.mapping

    // LINE — grouped long format
    if ('groupBy' in m) {
      return lineFromTable(table, {
        title: plan.title,
        x: m.x,
        groupBy: {
          keyCol: m.groupBy.keyCol,
          valueCol: m.groupBy.valueCol,
          sortKeys: m.groupBy.sortKeys,
        },
        xIsDate: m.groupBy.xIsDate,
        xOrder: m.groupBy.xOrder,
        smooth: plan.smooth,
        stacked: plan.stacked,
      })
    }

    // LINE — wide format with multiple numeric columns
    if ('seriesCols' in m) {
      return lineFromTable(table, {
        title: plan.title,
        x: m.x,
        series: m.seriesCols,
        xIsDate: m.xIsDate,
        xOrder: m.xOrder,
        smooth: plan.smooth,
        stacked: plan.stacked,
      })
    }

    throw new Error('Malformed line plan: mapping must be groupBy or seriesCols')
  }

  if (plan.kind === 'pie') {
    const m = plan.mapping

    if ('labelCol' in m && 'valueCol' in m) {
      return pieFromTable(table, {
        title: plan.title,
        label: m.labelCol,
        value: m.valueCol,
        aggregate: m.aggregate ?? 'sum',
        donut: plan.donut,
      })
    }

    throw new Error('Malformed pie plan: mapping must include labelCol and valueCol')
  }
  if (plan.kind === 'bar') {
    const m = plan.mapping as any
    return barFromTable(table, {
      title: plan.title ?? undefined,
      x: m.x,
      valueCol: m.valueCol,
      groupCol: m.groupCol ?? undefined,
      stacked: plan.stacked ?? false,
      xOrder: m.xOrder ?? undefined,
    })
  }

  if (plan.kind === 'heatmap') {
    const m = plan.mapping as any
    return heatmapFromTable(table, {
      title: plan.title,
      xCol: m.xCol,
      yCol: m.yCol,
      valueCol: m.valueCol,
      xOrder: m.xOrder,
      yOrder: m.yOrder,
    })
  }

  throw new Error(`Unsupported plan kind: ${(plan as any)?.kind}`)
}

export default executePlan
