"use client"

import { useState } from "react"
import type { JSX } from "react"
import { BarChart3, ChevronDown, Info } 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 {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from "@/shared/components/ui/collapsible"
import { cn } from "@/shared/lib/utils"
import type { ClassComparisonItem, ClassComparisonSignificance } from "@/modules/grades/types"

interface ClassComparisonChartProps {
  data: ClassComparisonItem[]
  /**
   * P3-5: 预计算的统计显著性结果。
   * 由 data-access 层使用 stats-service.computeSignificance 计算（Welch's t-test + Cohen's d）。
   * 若提供则展示 p 值与效应量；否则回退到基于极差的经验规则。
   */
  significance?: ClassComparisonSignificance | null
}

type SignificanceLevel = "high" | "medium" | "low"

interface EmpiricalSignificanceResult {
  range: number
  level: SignificanceLevel
  topClass: ClassComparisonItem
  bottomClass: ClassComparisonItem
}

/** 经验显著性判断阈值（在 significance prop 缺失时作为回退方案） */
const MIN_SAMPLE_SIZE = 30
const HIGH_RANGE_THRESHOLD = 10
const MEDIUM_RANGE_THRESHOLD = 5

/**
 * v3-P3-5: 经验显著性分析（回退方案）。
 * 仅当 data-access 层未注入统计显著性结果时使用。
 */
function analyzeSignificance(data: ClassComparisonItem[]): EmpiricalSignificanceResult | null {
  if (data.length < 2) return null

  let topClass = data[0]
  let bottomClass = data[0]
  for (const item of data) {
    if (item.averageScore > topClass.averageScore) topClass = item
    if (item.averageScore < bottomClass.averageScore) bottomClass = item
  }

  const range = topClass.averageScore - bottomClass.averageScore
  const allSufficient = data.every((d) => d.studentCount >= MIN_SAMPLE_SIZE)

  let level: SignificanceLevel
  if (range >= HIGH_RANGE_THRESHOLD && allSufficient) {
    level = "high"
  } else if (range >= MEDIUM_RANGE_THRESHOLD) {
    level = "medium"
  } else {
    level = "low"
  }

  return { range, level, topClass, bottomClass }
}

/**
 * P3-5: 根据 Cohen's d 效应量映射到 UI 等级。
 * < 0.2 negligible → low
 * < 0.5 small → medium
 * >= 0.5 medium/large → high
 */
function effectSizeToLevel(effectSizeLabel: ClassComparisonSignificance["effectSizeLabel"]): SignificanceLevel {
  switch (effectSizeLabel) {
    case "negligible":
      return "low"
    case "small":
      return "medium"
    case "medium":
    case "large":
      return "high"
  }
}

function formatScore(score: number): string {
  return score.toFixed(1)
}

function formatPValue(p: number): string {
  if (p < 0.001) return "< 0.001"
  return p.toFixed(3)
}

export function ClassComparisonChart({
  data,
  significance,
}: ClassComparisonChartProps): JSX.Element {
  const t = useTranslations("grades")
  const [detailsOpen, setDetailsOpen] = useState(false)
  const isEmpty = !data || data.length === 0

  const chartData = isEmpty
    ? []
    : data.map((d) => ({
        name: d.className,
        averageScore: d.averageScore,
        passRate: d.passRate,
        excellentRate: d.excellentRate,
        count: d.count,
        studentCount: d.studentCount,
      }))

  // P3-5: 优先使用注入的统计显著性结果，回退到经验规则
  const empirical = isEmpty ? null : analyzeSignificance(data)
  const topClass = significance
    ? data.find((d) => d.classId === significance.topClassId) ?? empirical?.topClass
    : empirical?.topClass
  const bottomClass = significance
    ? data.find((d) => d.classId === significance.bottomClassId) ?? empirical?.bottomClass
    : empirical?.bottomClass

  const level: SignificanceLevel | null = significance
    ? effectSizeToLevel(significance.effectSizeLabel)
    : empirical?.level ?? null
  const range = topClass && bottomClass
    ? topClass.averageScore - bottomClass.averageScore
    : null

  const levelColorClass: Record<SignificanceLevel, string> = {
    high: "border-destructive/30 bg-destructive/5 text-destructive",
    medium: "border-yellow-500/30 bg-yellow-500/5 text-yellow-700 dark:text-yellow-400",
    low: "border-emerald-500/30 bg-emerald-500/5 text-emerald-700 dark:text-emerald-400",
  }

  const levelLabel: Record<SignificanceLevel, string> = {
    high: t("classComparison.significanceHigh"),
    medium: t("classComparison.significanceMedium"),
    low: t("classComparison.significanceLow"),
  }

  const levelHint: Record<SignificanceLevel, string> = {
    high: t("classComparison.significanceHighHint"),
    medium: t("classComparison.significanceMediumHint"),
    low: t("classComparison.significanceLowHint"),
  }

  return (
    <ChartCardShell
      title={t("analytics.classComparison")}
      description={
        isEmpty
          ? t("classComparison.descriptionEmpty")
          : t("classComparison.descriptionNonEmpty")
      }
      icon={BarChart3}
      isEmpty={isEmpty}
      emptyTitle={t("classComparison.emptyTitle")}
      emptyDescription={t("classComparison.emptyDescription")}
      emptyClassName="h-60"
    >
      <div role="img" aria-label={isEmpty ? t("classComparison.ariaLabelEmpty") : t("classComparison.ariaLabelNonEmpty", { count: data.length })}>
        <SimpleBarChart
          data={chartData}
          bars={[
            { dataKey: "averageScore", name: t("chart.averagePercent"), color: "hsl(var(--primary))" },
            { dataKey: "passRate", name: t("chart.passRatePercent"), color: "hsl(var(--chart-2))" },
            { dataKey: "excellentRate", name: t("chart.excellentPercent"), color: "hsl(var(--chart-3))" },
          ]}
          xKey="name"
          xTruncateLength={8}
          yDomain={[0, 100]}
          yTickFormatter={(value: number) => `${value}%`}
          yWidth={36}
          margin={{ left: 8, right: 8, top: 8, bottom: 8 }}
          showLegend
          tooltipClassName="w-60"
        />
      </div>

      {level && topClass && bottomClass ? (
        <div
          className="mt-3 space-y-2"
          aria-label={t("classComparison.significanceAriaLabel", { level: levelLabel[level] })}
        >
          <div className={cn("flex items-start gap-2 rounded-md border p-3", levelColorClass[level])}>
            <Info className="mt-0.5 h-4 w-4 shrink-0" aria-hidden="true" />
            <div className="space-y-1 text-sm">
              <div className="font-medium">
                {t("classComparison.significanceTitle")} · {levelLabel[level]}
              </div>
              {range !== null && (
                <div className="text-xs opacity-90">
                  {t("classComparison.significanceRange", { range: formatScore(range) })}
                </div>
              )}
              {significance ? (
                <div className="text-xs opacity-90">
                  {t("classComparison.significanceStats", {
                    pValue: formatPValue(significance.pValue),
                    cohensD: significance.cohensD.toFixed(2),
                    effectSize: t(`classComparison.effectSize.${significance.effectSizeLabel}`),
                  })}
                </div>
              ) : null}
              <div className="text-xs opacity-80">{levelHint[level]}</div>
            </div>
          </div>

          <Collapsible open={detailsOpen} onOpenChange={setDetailsOpen}>
            <CollapsibleTrigger asChild>
              <button
                type="button"
                className="flex w-full items-center justify-center gap-1 rounded-md border border-border/60 bg-muted/30 px-3 py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
              >
                {t("classComparison.significanceDetails")}
                <ChevronDown
                  className={cn("h-3 w-3 transition-transform", detailsOpen && "rotate-180")}
                  aria-hidden="true"
                />
              </button>
            </CollapsibleTrigger>
            <CollapsibleContent className="pt-2">
              <div className="space-y-1 rounded-md border border-border/60 bg-muted/20 p-3 text-xs text-muted-foreground">
                <div>
                  {t("classComparison.significanceTopClass", {
                    name: topClass.className,
                    score: formatScore(topClass.averageScore),
                  })}
                </div>
                <div>
                  {t("classComparison.significanceBottomClass", {
                    name: bottomClass.className,
                    score: formatScore(bottomClass.averageScore),
                  })}
                </div>
                {significance ? (
                  <div className="pt-1 text-muted-foreground/70">
                    {t("classComparison.significanceMethod", {
                      significant: significance.isSignificant
                        ? t("classComparison.significantYes")
                        : t("classComparison.significantNo"),
                    })}
                  </div>
                ) : null}
              </div>
            </CollapsibleContent>
          </Collapsible>
        </div>
      ) : null}
    </ChartCardShell>
  )
}
