"use client"

import type { JSX } from "react"
import { PieChart as PieChartIcon } from "lucide-react"
import { useTranslations } from "next-intl"

import { ChartCardShell } from "@/shared/components/charts/chart-card-shell"
import { SimpleBarChart } from "@/shared/components/charts/simple-bar-chart"
import type { GradeDistributionResult } from "@/modules/grades/types"

/**
 * v4-P3-4: 色盲友好的双重编码。
 * 每个分数段使用不同的 SVG pattern（条纹/点状/交叉线等）+ 颜色，
 * 确保色觉障碍用户能通过纹理区分各分数段。
 */
const BUCKET_FILLS: Record<string, string> = {
  "90-100": "url(#grade-pattern-90-100)",
  "80-89": "url(#grade-pattern-80-89)",
  "70-79": "url(#grade-pattern-70-79)",
  "60-69": "url(#grade-pattern-60-69)",
  "<60": "url(#grade-pattern-lt60)",
}

/** v4-P3-4: SVG 图案定义，为每个分数段提供独特的纹理 */
const PATTERN_DEFS = (
  <defs>
    {/* 90-100: 正向斜条纹 */}
    <pattern
      id="grade-pattern-90-100"
      patternUnits="userSpaceOnUse"
      width="8"
      height="8"
      patternTransform="rotate(45)"
    >
      <rect width="8" height="8" fill="hsl(142, 71%, 45%)" />
      <line x1="0" y1="0" x2="0" y2="8" stroke="hsl(142, 71%, 25%)" strokeWidth="3" />
    </pattern>
    {/* 80-89: 圆点 */}
    <pattern
      id="grade-pattern-80-89"
      patternUnits="userSpaceOnUse"
      width="10"
      height="10"
    >
      <rect width="10" height="10" fill="hsl(217, 91%, 60%)" />
      <circle cx="5" cy="5" r="2.5" fill="hsl(217, 91%, 35%)" />
    </pattern>
    {/* 70-79: 交叉线 */}
    <pattern
      id="grade-pattern-70-79"
      patternUnits="userSpaceOnUse"
      width="8"
      height="8"
    >
      <rect width="8" height="8" fill="hsl(43, 96%, 56%)" />
      <path d="M0,0 L8,8 M8,0 L0,8" stroke="hsl(43, 96%, 31%)" strokeWidth="1.5" />
    </pattern>
    {/* 60-69: 反向斜条纹 */}
    <pattern
      id="grade-pattern-60-69"
      patternUnits="userSpaceOnUse"
      width="8"
      height="8"
      patternTransform="rotate(-45)"
    >
      <rect width="8" height="8" fill="hsl(25, 95%, 53%)" />
      <line x1="0" y1="0" x2="0" y2="8" stroke="hsl(25, 95%, 33%)" strokeWidth="3" />
    </pattern>
    {/* <60: 网格 */}
    <pattern
      id="grade-pattern-lt60"
      patternUnits="userSpaceOnUse"
      width="8"
      height="8"
    >
      <rect width="8" height="8" fill="hsl(0, 84%, 60%)" />
      <path d="M0,0 L8,0 M0,0 L0,8" stroke="hsl(0, 84%, 40%)" strokeWidth="1.5" />
    </pattern>
  </defs>
)

interface GradeDistributionChartProps {
  data: GradeDistributionResult | null
  /**
   * P3-9: 需要高亮的桶索引（用于学生视角的"你的位置"标注）。
   * -1 或 undefined 表示不高亮任何桶。
   */
  highlightBucketIndex?: number
  /** P3-9: 学生归一化分数（用于显示"你的分数"标签） */
  studentScore?: number | null
}

interface DistributionTooltipItem {
  label: string
  count: number
  percentage: number
}

interface DistributionTooltipPayload {
  payload?: DistributionTooltipItem
}

function isDistributionTooltipPayload(v: unknown): v is DistributionTooltipPayload {
  if (typeof v !== "object" || v === null) return false
  const obj = v as Record<string, unknown>
  const inner = obj.payload
  if (inner === undefined || inner === null) return true
  if (typeof inner !== "object") return false
  const item = inner as Record<string, unknown>
  return (
    typeof item.label === "string" &&
    typeof item.count === "number" &&
    typeof item.percentage === "number"
  )
}

export function GradeDistributionChart({
  data,
  highlightBucketIndex,
  studentScore,
}: GradeDistributionChartProps): JSX.Element {
  const t = useTranslations("grades")
  const isEmpty = !data || data.totalCount === 0

  const chartData = isEmpty
    ? []
    : data.buckets.map((b, i) => ({
        label: b.label,
        count: b.count,
        percentage:
          data.totalCount > 0
            ? Math.round((b.count / data.totalCount) * 1000) / 10
            : 0,
        isHighlighted: highlightBucketIndex === i ? 1 : 0,
      }))

  return (
    <ChartCardShell
      title={t("distribution.title")}
      description={
        isEmpty
          ? t("distribution.descriptionEmpty")
          : t("distribution.descriptionNonEmpty", { count: data.totalCount })
      }
      icon={PieChartIcon}
      isEmpty={isEmpty}
      emptyTitle={t("distribution.emptyTitle")}
      emptyDescription={t("distribution.emptyDescription")}
      emptyClassName="h-60"
    >
      <div role="img" aria-label={isEmpty ? t("distribution.ariaLabelEmpty") : t("distribution.ariaLabelNonEmpty", { count: data.totalCount })}>
        <SimpleBarChart
          data={chartData}
          bars={[
            {
              dataKey: "count",
              name: t("chart.students"),
              color: "hsl(var(--primary))",
            },
          ]}
          xKey="label"
          xTickFormatter={null}
          yAllowDecimals={false}
          yWidth={32}
          margin={{ left: 8, right: 8, top: 8, bottom: 8 }}
          defs={PATTERN_DEFS}
          cellColors={BUCKET_FILLS}
          tooltipFormatter={(payload: unknown) => {
            if (!isDistributionTooltipPayload(payload)) return null
            const item = payload.payload
            if (!item) return null
            return (
              <div className="flex w-full flex-col gap-0.5">
                <span className="text-sm font-medium">
                  {item.label}: {t("distribution.tooltipStudents", { count: item.count })}
                </span>
                <span className="text-xs text-muted-foreground">{t("distribution.tooltipOfTotal", { percentage: item.percentage })}</span>
              </div>
            )
          }}
        />
      </div>

      {highlightBucketIndex !== undefined && highlightBucketIndex >= 0 && studentScore !== null && studentScore !== undefined && data ? (
        <div
          className="mt-3 flex items-center gap-2 rounded-md border border-primary/30 bg-primary/5 p-2 text-xs"
          role="status"
          aria-label={t("distribution.yourPositionAriaLabel", {
            score: studentScore.toFixed(1),
          })}
        >
          <span
            className="inline-block h-2 w-2 shrink-0 rounded-full bg-primary"
            aria-hidden="true"
          />
          <span className="text-primary">
            {t("distribution.yourPosition", {
              score: studentScore.toFixed(1),
              bucket: data.buckets[highlightBucketIndex]?.label ?? "",
            })}
          </span>
        </div>
      ) : null}
    </ChartCardShell>
  )
}
