"use client"

import { useCallback } from "react"
import { Bar, BarChart, CartesianGrid, XAxis, YAxis, Cell } from "recharts"
import { useTranslations } from "next-intl"
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
} from "@/shared/components/ui/chart"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { cn } from "@/shared/lib/utils"

import type { ClassErrorOverview } from "@/modules/error-book/types"

/** recharts 内联对象常量：避免每次渲染创建新对象触发 re-render */
const CHART_MARGIN = { left: 8, right: 8, top: 8, bottom: 8 }
const GRID_PROPS = { vertical: false, strokeDasharray: "4 4", strokeOpacity: 0.4 }
const X_AXIS_BASE_PROPS = {
  dataKey: "name",
  tickLine: false,
  axisLine: false,
  tickMargin: 8,
}
const Y_AXIS_PROPS = { tickLine: false, axisLine: false, width: 36 }
const BAR_RADIUS: [number, number, number, number] = [4, 4, 0, 0]

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

interface ClassErrorBarChartProps {
  data: ClassErrorOverview[]
  className?: string
}

interface ClassBarChartPayload {
  name: string
  totalErrorItems: number
  studentCount: number
  averageErrorPerStudent: number
  averageMasteryRate: number
  dueReviewCount: number
}

function isClassBarChartPayload(v: unknown): v is ClassBarChartPayload {
  if (typeof v !== "object" || v === null) return false
  // 从 unknown 转换：类型守卫内需要属性访问来校验字段类型
  const obj = v as Record<string, unknown>
  return (
    typeof obj.name === "string" &&
    typeof obj.totalErrorItems === "number" &&
    typeof obj.studentCount === "number" &&
    typeof obj.averageErrorPerStudent === "number" &&
    typeof obj.averageMasteryRate === "number" &&
    typeof obj.dueReviewCount === "number"
  )
}

const CHART_COLORS = [
  "var(--color-chart-1)",
  "var(--color-chart-2)",
  "var(--color-chart-3)",
  "var(--color-chart-4)",
  "var(--color-chart-5)",
]

/**
 * 班级错题数对比柱状图（教师视图）
 * 横轴：班级名称，纵轴：错题总数
 * 颜色按班级区分，tooltip 显示学生数/人均/掌握率
 */
export function ClassErrorBarChart({ data, className }: ClassErrorBarChartProps) {
  const t = useTranslations("errorBook")

  const renderTooltip = useCallback(
    (payload: unknown) => {
      if (!isClassBarChartPayload(payload)) return null
      return (
        <div className="space-y-1.5">
          <div className="font-medium">{payload.name}</div>
          <div className="text-muted-foreground">
            {t("classErrorBar.errorCount")}：
            <span className="font-medium text-foreground">{payload.totalErrorItems}</span>
          </div>
          <div className="text-muted-foreground">
            {t("classErrorBar.studentCount")}：
            <span className="font-medium text-foreground">{payload.studentCount}</span>
          </div>
          <div className="text-muted-foreground">
            {t("classErrorBar.avgPerStudent")}：
            <span className="font-medium text-foreground">{payload.averageErrorPerStudent}</span>
          </div>
          <div className="text-muted-foreground">
            {t("classErrorBar.avgMastery")}：
            <span className="font-medium text-foreground">{payload.averageMasteryRate}%</span>
          </div>
          <div className="text-muted-foreground">
            {t("classErrorBar.dueReview")}：
            <span className="font-medium text-rose-600">{payload.dueReviewCount}</span>
          </div>
        </div>
      )
    },
    [t]
  )

  if (data.length === 0) return null

  const chartData = data.map((d) => ({
    name: d.className,
    totalErrorItems: d.totalErrorItems,
    studentCount: d.studentCount,
    averageErrorPerStudent: Number(d.averageErrorPerStudent.toFixed(1)),
    averageMasteryRate: Number((d.averageMasteryRate * 100).toFixed(0)),
    dueReviewCount: d.dueReviewCount,
  }))

  const chartConfig: ChartConfig = {
    totalErrorItems: {
      label: t("classErrorBar.errorCount"),
      color: "var(--color-chart-1)",
    },
  }

  return (
    <Card className={cn("overflow-hidden", className)}>
      <CardHeader>
        <CardTitle className="text-base">{t("classErrorBar.title")}</CardTitle>
      </CardHeader>
      <CardContent>
        {/* arbitrary-value: chart canvas fixed size */}
        <ChartContainer
          config={chartConfig}
          className="h-[280px] w-full"
          aria-label={t("classErrorBar.title")}
        >
          <BarChart data={chartData} margin={CHART_MARGIN}>
            <CartesianGrid {...GRID_PROPS} />
            <XAxis
              {...X_AXIS_BASE_PROPS}
              tickFormatter={truncateTick}
            />
            <YAxis {...Y_AXIS_PROPS} />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  className="w-[220px]"
                  formatter={renderTooltip}
                />
              }
            />
            <Bar dataKey="totalErrorItems" radius={BAR_RADIUS}>
              {chartData.map((_, idx) => (
                <Cell key={idx} fill={CHART_COLORS[idx % CHART_COLORS.length]} />
              ))}
            </Bar>
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
