"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"

/**
 * 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={{ left: 8, right: 8, top: 8, bottom: 8 }}>
      <CartesianGrid vertical={false} strokeDasharray="4 4" strokeOpacity={0.4} />
      <XAxis dataKey={xKey} tickLine={false} axisLine={false} tickMargin={8} />
      <YAxis
        domain={spec.yDomain}
        allowDecimals
        tickLine={false}
        axisLine={false}
        width={36}
      />
      <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={[4, 4, 0, 0]}
        />
      ))}
    </BarChart>
  )
}

function renderLineChart(spec: AiChartSpec, series: AiChartSeries[]): React.ReactNode {
  const xKey = spec.xKey ?? "name"
  return (
    <LineChart data={spec.data} margin={{ left: 8, right: 8, top: 8, bottom: 8 }}>
      <CartesianGrid vertical={false} strokeDasharray="4 4" strokeOpacity={0.4} />
      <XAxis dataKey={xKey} tickLine={false} axisLine={false} tickMargin={8} />
      <YAxis
        domain={spec.yDomain ?? [0, 100]}
        tickLine={false}
        axisLine={false}
        width={36}
      />
      <ChartTooltip
        cursor={{
          stroke: "hsl(var(--muted-foreground))",
          strokeWidth: 1,
          strokeDasharray: "4 4",
        }}
        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={{ r: 5, strokeWidth: 0 }}
        />
      ))}
    </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={{ left: 8, right: 8, top: 8, bottom: 8 }}>
      <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={(entry: { name?: string; value?: number }) =>
          `${entry.name ?? ""}: ${entry.value ?? ""}`
        }
        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={{ left: 8, right: 8, top: 8, bottom: 8 }}>
      <PolarGrid strokeOpacity={0.4} />
      <PolarAngleAxis dataKey={angleKey} tick={{ fontSize: 12 }} />
      <PolarRadiusAxis
        domain={spec.yDomain ?? [0, 100]}
        tickFormatter={(value: number) => `${value}%`}
        tick={{ fontSize: 10 }}
        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>
  )
}
