"use client"

import type { ReactNode } from "react"
import { Bar, BarChart, CartesianGrid, Legend, XAxis, YAxis, Cell } from "recharts"

import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
} from "@/shared/components/ui/chart"
import { cn } from "@/shared/lib/utils"

/**
 * 柱状图：统一的 BarChart 配置（CartesianGrid + XAxis + YAxis + ChartTooltip + Bar）。
 *
 * 覆盖以下重复模式：
 * - GradeDistributionChart（单 Bar + Cell 分桶着色）
 * - ClassComparisonChart（多 Bar + Legend）
 *
 * 默认配置：
 * - CartesianGrid: vertical=false, strokeDasharray="4 4", strokeOpacity=0.4
 * - XAxis: tickLine=false, axisLine=false, tickMargin=8, 默认截断到 8 字符
 * - YAxis: tickLine=false, axisLine=false
 * - Bar: radius=[4,4,0,0]
 */
export interface BarSeries {
  /** 数据字段名 */
  dataKey: string
  /** 图例名称 */
  name: string
  /** 颜色（CSS 变量或 hsl 值） */
  color: string
  /** 圆角（默认 [4, 4, 0, 0]） */
  radius?: [number, number, number, number]
}

interface SimpleBarChartProps {
  /** 图表数据 */
  data: Array<Record<string, string | number>>
  /** 柱系列配置（单条或多条） */
  bars: BarSeries[]
  /** X 轴数据字段名 */
  xKey: string
  /** Y 轴定义域（如 [0, 100]；不传则不设置 domain） */
  yDomain?: [number, number]
  /** Y 轴是否允许小数（默认 true） */
  yAllowDecimals?: boolean
  /** Y 轴刻度格式化（如百分比） */
  yTickFormatter?: (value: number) => string
  /** X 轴刻度格式化（默认 "default"=截断到 8 字符；设为 null 则不格式化；传函数则自定义） */
  xTickFormatter?: ((value: string) => string) | "default" | null
  /** X 轴截断长度（默认 8） */
  xTruncateLength?: number
  /** Y 轴宽度（默认 36） */
  yWidth?: number
  /** 图表高度类名（默认 "h-[280px]"） */
  heightClassName?: string
  /** 图表 margin */
  margin?: { left: number; right: number; top: number; bottom: number }
  /** 是否显示 Legend（多 Bar 时建议 true） */
  showLegend?: boolean
  /** Tooltip 宽度类名（默认 "w-[200px]"） */
  tooltipClassName?: string
  /** 自定义 Tooltip formatter（用于自定义 tooltip 内容） */
  tooltipFormatter?: (payload: unknown) => ReactNode
  /** 按数据项着色的映射（key = xKey 值, value = 颜色）；用于单 Bar 分桶着色 */
  cellColors?: Record<string, string>
  /** 自定义 SVG defs（如 patterns、gradients），渲染在 BarChart 内部 */
  defs?: ReactNode
  /** 容器额外类名 */
  className?: string
}

const DEFAULT_X_TRUNCATE_LENGTH = 8

function makeXTickFormatter(truncateLength: number) {
  return (value: string): string =>
    value.length > truncateLength ? `${value.slice(0, truncateLength)}...` : value
}

export function SimpleBarChart({
  data,
  bars,
  xKey,
  yDomain,
  yAllowDecimals = true,
  yTickFormatter,
  xTickFormatter = "default",
  xTruncateLength = DEFAULT_X_TRUNCATE_LENGTH,
  yWidth = 36,
  heightClassName = "h-[280px]",
  margin = { left: 8, right: 8, top: 8, bottom: 8 },
  showLegend = false,
  tooltipClassName = "w-[200px]",
  tooltipFormatter,
  cellColors,
  defs,
  className,
}: SimpleBarChartProps) {
  const chartConfig: ChartConfig = {}
  for (const b of bars) {
    chartConfig[b.dataKey] = {
      label: b.name,
      color: b.color,
    }
  }

  const resolvedXTickFormatter =
    xTickFormatter === null
      ? undefined
      : xTickFormatter === "default"
        ? makeXTickFormatter(xTruncateLength)
        : xTickFormatter

  const hasCellColors = !!cellColors && bars.length === 1

  return (
    <ChartContainer config={chartConfig} className={cn(heightClassName, "w-full", className)}>
      <BarChart data={data} margin={margin}>
        {defs}
        <CartesianGrid vertical={false} strokeDasharray="4 4" strokeOpacity={0.4} />
        <XAxis
          dataKey={xKey}
          tickLine={false}
          axisLine={false}
          tickMargin={8}
          tickFormatter={resolvedXTickFormatter}
        />
        <YAxis
          domain={yDomain}
          allowDecimals={yAllowDecimals}
          tickLine={false}
          axisLine={false}
          tickFormatter={yTickFormatter}
          width={yWidth}
        />
        <ChartTooltip
          content={
            tooltipFormatter ? (
              <ChartTooltipContent className={tooltipClassName} formatter={tooltipFormatter} />
            ) : (
              <ChartTooltipContent className={tooltipClassName} />
            )
          }
        />
        {showLegend ? <Legend /> : null}
        {bars.map((b) => (
          <Bar
            key={b.dataKey}
            dataKey={b.dataKey}
            fill={`var(--color-${b.dataKey})`}
            radius={b.radius ?? [4, 4, 0, 0]}
          >
            {hasCellColors && cellColors
              ? data.map((entry) => {
                  const cellKey = String(entry[xKey])
                  return <Cell key={cellKey} fill={cellColors[cellKey]} />
                })
              : null}
          </Bar>
        ))}
      </BarChart>
    </ChartContainer>
  )
}
