"use client"

import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts"

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

/**
 * 趋势折线图：统一的 LineChart 配置（CartesianGrid + XAxis + YAxis + ChartTooltip + Line）。
 *
 * 覆盖以下重复模式（4 个文件几乎逐行相同）：
 * - GradeTrendChart（dataKey=normalizedScore, height=h-[280px]）
 * - TeacherGradeTrends（dataKey=score, height=h-[200px]）
 * - StudentGradesCard（dataKey=score, height=h-[200px]）
 * - ChildGradeSummary（dataKey=score, xKey=date, height=h-[160px]）
 *
 * 默认配置：
 * - CartesianGrid: vertical=false, strokeDasharray="4 4", strokeOpacity=0.4
 * - XAxis: tickLine=false, axisLine=false, tickMargin=8, 默认截断到 10 字符
 * - YAxis: domain=[0,100], tickLine=false, axisLine=false, 默认百分比格式化, width=36
 * - ChartTooltip: cursor 虚线, content=ChartTooltipContent indicator="line" labelKey="fullTitle"
 * - Line: type="monotone", strokeWidth=2
 */
export interface TrendLineSeries {
  /** 数据字段名（对应 data 中的 key） */
  dataKey: string
  /** 图例名称 */
  name: string
  /** 颜色（CSS 变量或 hsl 值，如 "hsl(var(--primary))"） */
  color: string
  /** 数据点半径（默认 3） */
  dotRadius?: number
  /** 激活数据点半径（默认 5） */
  activeDotRadius?: number
}

interface TrendLineChartProps {
  /** 图表数据 */
  data: Array<Record<string, string | number | undefined>>
  /** 折线系列配置（支持单条或多条） */
  series: TrendLineSeries[]
  /** X 轴数据字段名（默认 "title"） */
  xKey?: string
  /** Y 轴定义域（默认 [0, 100]） */
  yDomain?: [number, number]
  /** Y 轴刻度格式化（默认百分比 `${value}%`） */
  yTickFormatter?: (value: number) => string
  /** X 轴刻度格式化（默认截断到 10 字符；设为 null 则不格式化） */
  xTickFormatter?: ((value: string) => string) | null
  /** 图表高度类名（默认 "h-[280px]"） */
  heightClassName?: string
  /** 图表 margin（默认 { left: 8, right: 8, top: 8, bottom: 8 }） */
  margin?: { left: number; right: number; top: number; bottom: number }
  /** Y 轴宽度（默认 36） */
  yWidth?: number
  /** Tooltip 内容宽度类名（默认 "w-[220px]"） */
  tooltipClassName?: string
  /** Tooltip labelKey（默认 "fullTitle"） */
  tooltipLabelKey?: string
  /** 容器额外类名 */
  className?: string
}

const DEFAULT_X_TICK_TRUNCATE_LENGTH = 10

function defaultXTickFormatter(value: string): string {
  return value.length > DEFAULT_X_TICK_TRUNCATE_LENGTH
    ? `${value.slice(0, DEFAULT_X_TICK_TRUNCATE_LENGTH)}...`
    : value
}

function defaultYTickFormatter(value: number): string {
  return `${value}%`
}

export function TrendLineChart({
  data,
  series,
  xKey = "title",
  yDomain = [0, 100],
  yTickFormatter = defaultYTickFormatter,
  xTickFormatter = defaultXTickFormatter,
  heightClassName = "h-[280px]",
  margin = { left: 8, right: 8, top: 8, bottom: 8 },
  yWidth = 36,
  tooltipClassName = "w-[220px]",
  tooltipLabelKey = "fullTitle",
  className,
}: TrendLineChartProps) {
  const chartConfig: ChartConfig = {}
  for (const s of series) {
    chartConfig[s.dataKey] = {
      label: s.name,
      color: s.color,
    }
  }

  return (
    <ChartContainer config={chartConfig} className={cn(heightClassName, "w-full", className)}>
      <LineChart data={data} margin={margin}>
        <CartesianGrid vertical={false} strokeDasharray="4 4" strokeOpacity={0.4} />
        <XAxis
          dataKey={xKey}
          tickLine={false}
          axisLine={false}
          tickMargin={8}
          tickFormatter={xTickFormatter ?? undefined}
        />
        <YAxis
          domain={yDomain}
          tickLine={false}
          axisLine={false}
          tickFormatter={yTickFormatter}
          width={yWidth}
        />
        <ChartTooltip
          cursor={{
            stroke: "hsl(var(--muted-foreground))",
            strokeWidth: 1,
            strokeDasharray: "4 4",
          }}
          content={
            <ChartTooltipContent
              indicator="line"
              labelKey={tooltipLabelKey}
              className={tooltipClassName}
            />
          }
        />
        {series.map((s) => (
          <Line
            key={s.dataKey}
            dataKey={s.dataKey}
            type="monotone"
            stroke={`var(--color-${s.dataKey})`}
            strokeWidth={2}
            dot={{
              fill: `var(--color-${s.dataKey})`,
              r: s.dotRadius ?? 3,
              strokeWidth: 2,
            }}
            activeDot={{ r: s.activeDotRadius ?? 5, strokeWidth: 0 }}
          />
        ))}
      </LineChart>
    </ChartContainer>
  )
}
