"use client"

import { useMemo } from "react"
import { useTranslations } from "next-intl"
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  Legend,
  Line,
  LineChart,
  Pie,
  PieChart,
  PolarAngleAxis,
  PolarGrid,
  PolarRadiusAxis,
  Radar,
  RadarChart,
  XAxis,
  YAxis,
} from "recharts"

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

/** recharts 内联对象常量：避免每次渲染创建新对象触发 re-render */
const CHART_MARGIN = { left: 8, right: 8, top: 8, bottom: 8 }
const CARTESIAN_GRID_PROPS = {
  vertical: false,
  strokeDasharray: "4 4",
  strokeOpacity: 0.4,
} as const
const POLAR_GRID_PROPS = { strokeOpacity: 0.4 } as const
const BAR_X_AXIS_PROPS = {
  tickLine: false,
  axisLine: false,
  tickMargin: 8,
} as const
const BAR_Y_AXIS_PROPS = {
  allowDecimals: true,
  tickLine: false,
  axisLine: false,
  width: 36,
} as const
const LINE_Y_AXIS_PROPS = {
  tickLine: false,
  axisLine: false,
  width: 36,
} as const
const LINE_TOOLTIP_CURSOR = {
  stroke: "hsl(var(--muted-foreground))",
  strokeWidth: 1,
  strokeDasharray: "4 4",
} as const
const LINE_ACTIVE_DOT = { r: 5, strokeWidth: 0 } as const
const POLAR_ANGLE_TICK = { fontSize: 12 } as const
const POLAR_RADIUS_TICK = { fontSize: 10 } as const
const BAR_RADIUS_TOP: [number, number, number, number] = [4, 4, 0, 0]
const DEFAULT_Y_DOMAIN: [number, number] = [0, 100]

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

function formatPieLabel(entry: { name?: string; value?: number }): string {
  return `${entry.name ?? ""}: ${entry.value ?? ""}`
}

/**
 * AI 图表渲染器
 *
 * 将 AI 返回的图表 JSON 规格渲染为 recharts 图表。
 * 支持 4 种图表类型：bar / line / pie / radar。
 *
 * AI 通过在 Markdown 中返回特殊代码块触发渲染：
 *
 * ```chart:bar
 * { "title": "...", "data": [...], "series": [...] }
 * ```
 *
 * 规格格式（通用）：
 * {
 *   "title": "图表标题",          // 可选
 *   "description": "说明文字",     // 可选
 *   "data": [                     // 数据数组
 *     { "name": "数学", "score": 85, "fullTitle": "数学科目" }
 *   ],
 *   "xKey": "name",               // X 轴字段（bar/line）
 *   "series": [                   // 系列配置
 *     { "dataKey": "score", "name": "分数", "color": "hsl(221, 83%, 53%)" }
 *   ],
 *   "yDomain": [0, 100],          // 可选，Y 轴定义域
 *   "height": 280                 // 可选，高度 px
 * }
 *
 * pie 图特有：
 * {
 *   "data": [{ "name": "及格", "value": 30 }],
 *   "series": [{ "name": "分布" }]
 * }
 */

export type AiChartType = "bar" | "line" | "pie" | "radar"

export interface AiChartSeries {
  dataKey: string
  name: string
  color?: string
  /** pie: 填充透明度；radar: 填充透明度 */
  fillOpacity?: number
  /** radar: 线宽 */
  strokeWidth?: number
  /** radar: 虚线 */
  strokeDasharray?: string
}

export interface AiChartSpec {
  title?: string
  description?: string
  type?: AiChartType
  data: Array<Record<string, string | number>>
  xKey?: string
  angleKey?: string
  series: AiChartSeries[]
  yDomain?: [number, number]
  height?: number
  showLegend?: boolean
}

/** 默认调色板（色盲友好） */
const DEFAULT_PALETTE = [
  "hsl(221, 83%, 53%)",   // 蓝
  "hsl(142, 71%, 45%)",   // 绿
  "hsl(43, 96%, 56%)",    // 黄
  "hsl(0, 84%, 60%)",     // 红
  "hsl(271, 76%, 53%)",   // 紫
  "hsl(199, 89%, 48%)",   // 青
  "hsl(25, 95%, 53%)",    // 橙
  "hsl(280, 65%, 60%)",   // 品红
]

interface AiChartRendererProps {
  /** 图表类型 */
  type: AiChartType
  /** JSON 规格字符串 */
  spec: string
  className?: string
}

/**
 * 解析 JSON 规格，失败时返回 null
 *
 * 使用 Zod schema 校验，避免 as 断言。
 */
function parseSpec(spec: string): AiChartSpec | null {
  try {
    const parsed: unknown = JSON.parse(spec)
    const result = AiChartSpecSchema.safeParse(parsed)
    if (!result.success) return null
    return result.data
  } catch {
    return null
  }
}

/**
 * 为 series 补充默认颜色
 */
function withDefaultColors(series: AiChartSeries[]): AiChartSeries[] {
  return series.map((s, i) => ({
    ...s,
    color: s.color ?? DEFAULT_PALETTE[i % DEFAULT_PALETTE.length],
  }))
}

export function AiChartRenderer({
  type,
  spec,
  className,
}: AiChartRendererProps): React.ReactNode {
  const t = useTranslations("ai")
  const parsed = useMemo(() => parseSpec(spec), [spec])

  if (!parsed) {
    return (
      <div className="rounded-md border border-destructive/30 bg-destructive/5 p-3 text-xs text-destructive">
        {t("chart.parseError")}
      </div>
    )
  }

  const series = withDefaultColors(parsed.series)
  const height = parsed.height ?? 280

  // 构建 ChartConfig
  const chartConfig: ChartConfig = {}
  for (const s of series) {
    chartConfig[s.dataKey] = {
      label: s.name,
      color: s.color,
    }
  }

  return (
    <div className={cn("my-2 rounded-lg border bg-card p-3", className)}>
      {parsed.title ? (
        <div className="mb-2">
          <p className="text-sm font-medium leading-tight">{parsed.title}</p>
          {parsed.description ? (
            <p className="text-xs text-muted-foreground mt-0.5">{parsed.description}</p>
          ) : null}
        </div>
      ) : null}
      <ChartContainer
        config={chartConfig}
        className="w-full"
        style={{ height: `${height}px` }}
      >
        {renderChart(type, parsed, series)}
      </ChartContainer>
    </div>
  )
}

function renderChart(
  type: AiChartType,
  spec: AiChartSpec,
  series: AiChartSeries[]
): React.ReactNode {
  switch (type) {
    case "bar":
      return renderBarChart(spec, series)
    case "line":
      return renderLineChart(spec, series)
    case "pie":
      return renderPieChart(spec, series)
    case "radar":
      return renderRadarChart(spec, series)
    default:
      return null
  }
}

function renderBarChart(spec: AiChartSpec, series: AiChartSeries[]): React.ReactNode {
  const xKey = spec.xKey ?? "name"
  return (
    <BarChart data={spec.data} margin={CHART_MARGIN}>
      <CartesianGrid {...CARTESIAN_GRID_PROPS} />
      <XAxis dataKey={xKey} {...BAR_X_AXIS_PROPS} />
      <YAxis
        domain={spec.yDomain}
        {...BAR_Y_AXIS_PROPS}
      />
      <ChartTooltip content={<ChartTooltipContent className="w-[200px]" />} />
      {spec.showLegend ? <Legend /> : null}
      {series.map((s) => (
        <Bar
          key={s.dataKey}
          dataKey={s.dataKey}
          name={s.name}
          fill={`var(--color-${s.dataKey})`}
          radius={BAR_RADIUS_TOP}
        />
      ))}
    </BarChart>
  )
}

function renderLineChart(spec: AiChartSpec, series: AiChartSeries[]): React.ReactNode {
  const xKey = spec.xKey ?? "name"
  return (
    <LineChart data={spec.data} margin={CHART_MARGIN}>
      <CartesianGrid {...CARTESIAN_GRID_PROPS} />
      <XAxis dataKey={xKey} {...BAR_X_AXIS_PROPS} />
      <YAxis
        domain={spec.yDomain ?? DEFAULT_Y_DOMAIN}
        {...LINE_Y_AXIS_PROPS}
      />
      {/* arbitrary-value: chart canvas fixed size */}
      <ChartTooltip
        cursor={LINE_TOOLTIP_CURSOR}
        content={<ChartTooltipContent indicator="line" className="w-[220px]" />}
      />
      {spec.showLegend ? <Legend /> : null}
      {series.map((s) => (
        <Line
          key={s.dataKey}
          dataKey={s.dataKey}
          name={s.name}
          type="monotone"
          stroke={`var(--color-${s.dataKey})`}
          strokeWidth={2}
          dot={{
            fill: `var(--color-${s.dataKey})`,
            r: 3,
            strokeWidth: 2,
          }}
          activeDot={LINE_ACTIVE_DOT}
        />
      ))}
    </LineChart>
  )
}

function renderPieChart(spec: AiChartSpec, series: AiChartSeries[]): React.ReactNode {
  // Pie 图：data 中每项 { name, value }，series 仅取第一个作为图例名
  const colors = series.map((s) => s.color ?? DEFAULT_PALETTE[0])
  const dataKey = series[0]?.dataKey ?? "value"
  return (
    <PieChart margin={CHART_MARGIN}>
      <ChartTooltip content={<ChartTooltipContent className="w-[200px]" />} />
      {spec.showLegend ? <Legend /> : null}
      <Pie
        data={spec.data}
        dataKey={dataKey}
        nameKey={spec.xKey ?? "name"}
        cx="50%"
        cy="50%"
        outerRadius="75%"
        label={formatPieLabel}
        labelLine={false}
      >
        {spec.data.map((_, index) => (
          <Cell key={`cell-${index}`} fill={colors[index % colors.length]} />
        ))}
      </Pie>
    </PieChart>
  )
}

function renderRadarChart(spec: AiChartSpec, series: AiChartSeries[]): React.ReactNode {
  const angleKey = spec.angleKey ?? spec.xKey ?? "name"
  return (
    <RadarChart data={spec.data} outerRadius="75%" margin={CHART_MARGIN}>
      <PolarGrid {...POLAR_GRID_PROPS} />
      <PolarAngleAxis dataKey={angleKey} tick={POLAR_ANGLE_TICK} />
      <PolarRadiusAxis
        domain={spec.yDomain ?? DEFAULT_Y_DOMAIN}
        tickFormatter={formatPercentTick}
        tick={POLAR_RADIUS_TICK}
        axisLine={false}
      />
      <ChartTooltip content={<ChartTooltipContent className="w-[220px]" />} />
      {spec.showLegend ? <Legend /> : null}
      {series.map((s) => (
        <Radar
          key={s.dataKey}
          name={s.name}
          dataKey={s.dataKey}
          stroke={`var(--color-${s.dataKey})`}
          fill={`var(--color-${s.dataKey})`}
          fillOpacity={s.fillOpacity ?? 0.3}
          strokeWidth={s.strokeWidth}
          strokeDasharray={s.strokeDasharray}
        />
      ))}
    </RadarChart>
  )
}
