"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 { Badge } from "@/shared/components/ui/badge"
import { cn } from "@/shared/lib/utils"

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

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

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

interface KnowledgePointWeaknessChartProps {
  data: KnowledgePointWeakness[]
  className?: string
}

interface KpChartPayload {
  name: string
  errorCount: number
  masteredCount: number
  masteryRate: number
  chapterTitle: string
}

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

/**
 * 知识点薄弱度图表
 * 横向柱状图，按错题数降序
 * 颜色按掌握率区分（红/黄/绿）
 * 显示所属章节
 */
export function KnowledgePointWeaknessChart({
  data,
  className,
}: KnowledgePointWeaknessChartProps) {
  const t = useTranslations("errorBook")

  const renderTooltip = useCallback(
    (payload: unknown) => {
      if (!isKpChartPayload(payload)) return null
      return (
        <div className="space-y-1.5">
          <div className="font-medium">{payload.name}</div>
          <div className="text-xs text-muted-foreground">
            {t("weaknessChart.chapterLabel", { title: payload.chapterTitle })}
          </div>
          <div className="text-muted-foreground">
            {t("weaknessChart.errorCount")}：
            <span className="font-medium text-foreground">{payload.errorCount}</span>
            <span className="ml-2">
              {t("weaknessChart.masteredLabel")}：
              <span className="font-medium text-emerald-600">{payload.masteredCount}</span>
            </span>
          </div>
          <div className="text-muted-foreground">
            {t("weaknessChart.masteryRateLabel")}：
            <span className="font-medium text-foreground">{payload.masteryRate}%</span>
          </div>
        </div>
      )
    },
    [t]
  )

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

  const chartData = data.map((d) => ({
    name: d.knowledgePointName,
    errorCount: d.errorCount,
    masteredCount: d.masteredCount,
    masteryRate: Number((d.masteryRate * 100).toFixed(0)),
    chapterTitle: d.chapterTitle ?? t("weaknessChart.unclassified"),
  }))

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

  return (
    <Card className={cn("overflow-hidden", className)}>
      <CardHeader>
        <CardTitle className="text-base">
          {t("weaknessChart.title", { count: data.length })}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <ChartContainer
          config={chartConfig}
          className="h-[320px] w-full"
          aria-label={t("weaknessChart.title", { count: data.length })}
        >
          <BarChart
            data={chartData}
            layout="vertical"
            margin={CHART_MARGIN}
          >
            <CartesianGrid {...GRID_PROPS} />
            <XAxis {...X_AXIS_PROPS} />
            <YAxis
              {...Y_AXIS_BASE_PROPS}
              tickFormatter={truncateTick}
            />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  className="w-60"
                  formatter={renderTooltip}
                />
              }
            />
            <Bar dataKey="errorCount" radius={BAR_RADIUS}>
              {chartData.map((entry, idx) => (
                <Cell
                  key={idx}
                  fill={
                    entry.masteryRate < 30
                      ? "var(--color-rose-500)"
                      : entry.masteryRate < 60
                        ? "var(--color-amber-500)"
                        : "var(--color-emerald-500)"
                  }
                />
              ))}
            </Bar>
          </BarChart>
        </ChartContainer>

        {/* 知识点详情列表（带章节归属） */}
        <div className="space-y-2">
          {data.slice(0, 8).map((kp) => (
            <div
              key={kp.knowledgePointId}
              className="flex items-center justify-between gap-3 rounded-lg border p-2.5"
            >
              <div className="min-w-0 flex-1">
                <div className="truncate text-sm font-medium">{kp.knowledgePointName}</div>
                {kp.chapterTitle ? (
                  <div className="truncate text-xs text-muted-foreground">
                    {kp.chapterTitle}
                  </div>
                ) : null}
              </div>
              <div className="flex shrink-0 items-center gap-2">
                <Badge
                  variant={
                    kp.masteryRate < 0.3
                      ? "destructive"
                      : kp.masteryRate < 0.6
                        ? "secondary"
                        : "outline"
                  }
                  className="text-xs"
                >
                  {Math.round(kp.masteryRate * 100)}%
                </Badge>
                <span className="text-sm font-bold text-rose-600">{kp.errorCount}</span>
              </div>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  )
}
