"use client";

/**
 * 成绩分析图表组件集（纯 SVG，无外部依赖）
 *
 * 5 个图表：
 * 1. TrendLineChart - 趋势折线图（avg/max/min 三线）
 * 2. DistributionBarChart - 分数分布柱图（5 段）
 * 3. SubjectComparisonChart - 学科对比柱图（6 学科）
 * 4. ClassComparisonChart - 班级对比柱图（含显著性 * 标记）
 * 5. KnowledgeRadarChart - 知识点掌握度雷达图（5 轴）
 *
 * 颜色使用 var(--color-*) 语义令牌（project_rules §3.10）
 *
 * 维护者：ai13（teacher-portal）
 */

import type {
  GradeTrendPoint,
  GradeDistributionBand,
  SubjectComparisonItem,
  ClassComparisonItem,
  KnowledgeMasteryItem,
} from "@/lib/graphql-p7-grades";

// ============ 1. 趋势折线图（avg/max/min 三线） ============

const TREND_PADDING = { top: 24, right: 32, bottom: 36, left: 36 };
const TREND_W = 520;
const TREND_H = 220;

export function TrendLineChart({ data }: { data: GradeTrendPoint[] }): React.ReactNode {
  if (data.length === 0) {
    return <p className="text-sm text-ink-muted">暂无趋势数据</p>;
  }
  const innerW = TREND_W - TREND_PADDING.left - TREND_PADDING.right;
  const innerH = TREND_H - TREND_PADDING.top - TREND_PADDING.bottom;

  const allValues = data.flatMap((d) => [d.avg, d.max, d.min]);
  const yMax = Math.max(100, ...allValues);
  const yMin = Math.min(0, ...allValues);
  const yRange = yMax - yMin || 1;

  const xStep = data.length > 1 ? innerW / (data.length - 1) : 0;

  const toPoint = (value: number, i: number) => ({
    x: TREND_PADDING.left + i * xStep,
    y: TREND_PADDING.top + innerH - ((value - yMin) / yRange) * innerH,
  });

  const buildPath = (key: "avg" | "max" | "min") =>
    data
      .map((d, i) => {
        const p = toPoint(d[key], i);
        return `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`;
      })
      .join(" ");

  // Y 轴网格（0 / 50 / 100）
  const gridLines = [0, 50, 100].map((v) => {
    const ratio = 1 - (v - yMin) / yRange;
    return { y: TREND_PADDING.top + innerH * ratio, value: v };
  });

  const lineColor = (key: "avg" | "max" | "min") =>
    key === "avg"
      ? "var(--color-accent)"
      : key === "max"
        ? "var(--color-success)"
        : "var(--color-danger)";

  return (
    <svg
      viewBox={`0 0 ${TREND_W} ${TREND_H}`}
      className="w-full border border-rule rounded-card bg-surface"
      role="img"
      aria-label="成绩趋势折线图"
    >
      {/* 网格线 + Y 刻度 */}
      {gridLines.map((g, i) => (
        <g key={`grid-${i}`}>
          <line
            x1={TREND_PADDING.left}
            y1={g.y}
            x2={TREND_W - TREND_PADDING.right}
            y2={g.y}
            stroke="var(--color-rule)"
            strokeWidth={1}
            strokeDasharray="3 3"
          />
          <text
            x={TREND_PADDING.left - 8}
            y={g.y + 4}
            textAnchor="end"
            fontSize="11"
            fontFamily="var(--font-family-mono)"
            fill="var(--color-ink-muted)"
          >
            {g.value}
          </text>
        </g>
      ))}
      {/* 三条线 */}
      {(["max", "avg", "min"] as const).map((key) => (
        <g key={key}>
          <path
            d={buildPath(key)}
            fill="none"
            stroke={lineColor(key)}
            strokeWidth={key === "avg" ? 2.5 : 1.5}
            strokeDasharray={key === "avg" ? undefined : "4 3"}
            strokeLinecap="round"
            strokeLinejoin="round"
          />
          {data.map((d, i) => {
            const p = toPoint(d[key], i);
            return (
              <circle
                key={`${key}-${i}`}
                cx={p.x}
                cy={p.y}
                r={key === "avg" ? 4 : 3}
                fill={lineColor(key)}
                stroke="var(--bg-paper)"
                strokeWidth={1.5}
              />
            );
          })}
        </g>
      ))}
      {/* X 轴月份标签 */}
      {data.map((d, i) => (
        <text
          key={`x-${i}`}
          x={TREND_PADDING.left + i * xStep}
          y={TREND_H - TREND_PADDING.bottom + 18}
          textAnchor="middle"
          fontSize="11"
          fontFamily="var(--font-family-sans)"
          fill="var(--color-ink-muted)"
        >
          {d.month}
        </text>
      ))}
      {/* avg 数值标签 */}
      {data.map((d, i) => {
        const p = toPoint(d.avg, i);
        return (
          <text
            key={`avg-label-${i}`}
            x={p.x}
            y={p.y - 10}
            textAnchor="middle"
            fontSize="11"
            fontFamily="var(--font-family-mono)"
            fontWeight="600"
            fill="var(--color-ink)"
          >
            {d.avg}
          </text>
        );
      })}
    </svg>
  );
}

// ============ 2. 分数分布柱图 ============

export function DistributionBarChart({
  data,
}: {
  data: GradeDistributionBand[];
}): React.ReactNode {
  if (data.length === 0) {
    return <p className="text-sm text-ink-muted">暂无分布数据</p>;
  }
  const maxCount = Math.max(1, ...data.map((d) => d.count));
  const W = 480;
  const H = 180;
  const PAD = { top: 20, right: 16, bottom: 36, left: 36 };
  const innerW = W - PAD.left - PAD.right;
  const innerH = H - PAD.top - PAD.bottom;
  const barW = innerW / data.length;

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      className="w-full border border-rule rounded-card bg-surface"
      role="img"
      aria-label="分数分布柱图"
    >
      {/* Y 轴网格 */}
      {[0, 0.5, 1].map((ratio, i) => {
        const y = PAD.top + innerH * ratio;
        const value = Math.round(maxCount * (1 - ratio));
        return (
          <g key={`grid-${i}`}>
            <line
              x1={PAD.left}
              y1={y}
              x2={W - PAD.right}
              y2={y}
              stroke="var(--color-rule)"
              strokeWidth={1}
              strokeDasharray="3 3"
            />
            <text
              x={PAD.left - 8}
              y={y + 4}
              textAnchor="end"
              fontSize="11"
              fontFamily="var(--font-family-mono)"
              fill="var(--color-ink-muted)"
            >
              {value}
            </text>
          </g>
        );
      })}
      {/* 柱子 */}
      {data.map((band, i) => {
        const barH = (band.count / maxCount) * innerH;
        const x = PAD.left + i * barW + barW * 0.2;
        const y = PAD.top + innerH - barH;
        const w = barW * 0.6;
        return (
          <g key={band.label}>
            <rect
              x={x}
              y={y}
              width={w}
              height={Math.max(0, barH)}
              fill="var(--color-accent)"
              rx={3}
            />
            <text
              x={x + w / 2}
              y={y - 6}
              textAnchor="middle"
              fontSize="11"
              fontFamily="var(--font-family-mono)"
              fontWeight="600"
              fill="var(--color-ink)"
            >
              {band.count}
            </text>
            <text
              x={x + w / 2}
              y={H - PAD.bottom + 18}
              textAnchor="middle"
              fontSize="11"
              fontFamily="var(--font-family-sans)"
              fill="var(--color-ink-muted)"
            >
              {band.label}
            </text>
          </g>
        );
      })}
    </svg>
  );
}

// ============ 3. 学科对比柱图 ============

export function SubjectComparisonChart({
  data,
}: {
  data: SubjectComparisonItem[];
}): React.ReactNode {
  if (data.length === 0) {
    return <p className="text-sm text-ink-muted">暂无学科对比数据</p>;
  }
  const maxAvg = Math.max(1, ...data.map((d) => d.avg));
  const W = 480;
  const H = 180;
  const PAD = { top: 20, right: 16, bottom: 36, left: 36 };
  const innerW = W - PAD.left - PAD.right;
  const innerH = H - PAD.top - PAD.bottom;
  const barW = innerW / data.length;

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      className="w-full border border-rule rounded-card bg-surface"
      role="img"
      aria-label="学科对比柱图"
    >
      {[0, 0.5, 1].map((ratio, i) => {
        const y = PAD.top + innerH * ratio;
        const value = Math.round(maxAvg * (1 - ratio));
        return (
          <g key={`grid-${i}`}>
            <line
              x1={PAD.left}
              y1={y}
              x2={W - PAD.right}
              y2={y}
              stroke="var(--color-rule)"
              strokeWidth={1}
              strokeDasharray="3 3"
            />
            <text
              x={PAD.left - 8}
              y={y + 4}
              textAnchor="end"
              fontSize="11"
              fontFamily="var(--font-family-mono)"
              fill="var(--color-ink-muted)"
            >
              {value}
            </text>
          </g>
        );
      })}
      {data.map((item, i) => {
        const barH = (item.avg / maxAvg) * innerH;
        const x = PAD.left + i * barW + barW * 0.2;
        const y = PAD.top + innerH - barH;
        const w = barW * 0.6;
        return (
          <g key={item.subject}>
            <rect
              x={x}
              y={y}
              width={w}
              height={Math.max(0, barH)}
              fill="var(--color-accent)"
              rx={3}
            />
            <text
              x={x + w / 2}
              y={y - 6}
              textAnchor="middle"
              fontSize="11"
              fontFamily="var(--font-family-mono)"
              fontWeight="600"
              fill="var(--color-ink)"
            >
              {item.avg}
            </text>
            <text
              x={x + w / 2}
              y={H - PAD.bottom + 18}
              textAnchor="middle"
              fontSize="11"
              fontFamily="var(--font-family-sans)"
              fill="var(--color-ink-muted)"
            >
              {item.subject}
            </text>
          </g>
        );
      })}
    </svg>
  );
}

// ============ 4. 班级对比柱图（含显著性 * 标记） ============

export function ClassComparisonChart({
  data,
}: {
  data: ClassComparisonItem[];
}): React.ReactNode {
  if (data.length === 0) {
    return <p className="text-sm text-ink-muted">暂无班级对比数据</p>;
  }
  const maxAvg = Math.max(1, ...data.map((d) => d.avg));
  const W = 480;
  const H = 200;
  const PAD = { top: 24, right: 16, bottom: 48, left: 36 };
  const innerW = W - PAD.left - PAD.right;
  const innerH = H - PAD.top - PAD.bottom;
  const barW = innerW / data.length;

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      className="w-full border border-rule rounded-card bg-surface"
      role="img"
      aria-label="班级对比柱图"
    >
      {[0, 0.5, 1].map((ratio, i) => {
        const y = PAD.top + innerH * ratio;
        const value = Math.round(maxAvg * (1 - ratio));
        return (
          <g key={`grid-${i}`}>
            <line
              x1={PAD.left}
              y1={y}
              x2={W - PAD.right}
              y2={y}
              stroke="var(--color-rule)"
              strokeWidth={1}
              strokeDasharray="3 3"
            />
            <text
              x={PAD.left - 8}
              y={y + 4}
              textAnchor="end"
              fontSize="11"
              fontFamily="var(--font-family-mono)"
              fill="var(--color-ink-muted)"
            >
              {value}
            </text>
          </g>
        );
      })}
      {data.map((item, i) => {
        const barH = (item.avg / maxAvg) * innerH;
        const x = PAD.left + i * barW + barW * 0.2;
        const y = PAD.top + innerH - barH;
        const w = barW * 0.6;
        return (
          <g key={item.classId}>
            <rect
              x={x}
              y={y}
              width={w}
              height={Math.max(0, barH)}
              fill={
                item.significant
                  ? "var(--color-warning)"
                  : "var(--color-accent)"
              }
              rx={3}
            />
            <text
              x={x + w / 2}
              y={y - 6}
              textAnchor="middle"
              fontSize="11"
              fontFamily="var(--font-family-mono)"
              fontWeight="600"
              fill="var(--color-ink)"
            >
              {item.avg}
              {item.significant ? "*" : ""}
            </text>
            <text
              x={x + w / 2}
              y={H - PAD.bottom + 14}
              textAnchor="middle"
              fontSize="10"
              fontFamily="var(--font-family-sans)"
              fill="var(--color-ink-muted)"
            >
              {item.className}
            </text>
            {item.significant && (
              <text
                x={x + w / 2}
                y={H - PAD.bottom + 28}
                textAnchor="middle"
                fontSize="9"
                fontFamily="var(--font-family-sans)"
                fill="var(--color-warning)"
              >
                显著差异
              </text>
            )}
          </g>
        );
      })}
    </svg>
  );
}

// ============ 5. 知识点掌握度雷达图 ============

export function KnowledgeRadarChart({
  data,
}: {
  data: KnowledgeMasteryItem[];
}): React.ReactNode {
  if (data.length < 3) {
    return <p className="text-sm text-ink-muted">暂无知识点掌握度数据</p>;
  }
  const W = 360;
  const H = 360;
  const cx = W / 2;
  const cy = H / 2;
  const radius = 120;
  const n = data.length;
  // 5 个层级（20/40/60/80/100）
  const rings = [0.2, 0.4, 0.6, 0.8, 1];

  // 计算顶点坐标
  const angle = (i: number) => (Math.PI * 2 * i) / n - Math.PI / 2;
  const pointAt = (i: number, r: number) => ({
    x: cx + r * Math.cos(angle(i)),
    y: cy + r * Math.sin(angle(i)),
  });

  // 数据多边形顶点
  const dataPoints = data.map((d, i) =>
    pointAt(i, (d.mastery / 100) * radius),
  );

  const dataPath = dataPoints
    .map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`)
    .join(" ") + " Z";

  return (
    <svg
      viewBox={`0 0 ${W} ${H}`}
      className="w-full max-w-sm border border-rule rounded-card bg-surface mx-auto"
      role="img"
      aria-label="知识点掌握度雷达图"
    >
      {/* 同心多边形网格 */}
      {rings.map((ratio, ri) => {
        const r = radius * ratio;
        const pts = data
          .map((_, i) => {
            const p = pointAt(i, r);
            return `${p.x},${p.y}`;
          })
          .join(" ");
        return (
          <polygon
            key={`ring-${ri}`}
            points={pts}
            fill="none"
            stroke="var(--color-rule)"
            strokeWidth={1}
            strokeDasharray={ri === rings.length - 1 ? undefined : "3 3"}
          />
        );
      })}
      {/* 轴线 */}
      {data.map((_, i) => {
        const p = pointAt(i, radius);
        return (
          <line
            key={`axis-${i}`}
            x1={cx}
            y1={cy}
            x2={p.x}
            y2={p.y}
            stroke="var(--color-rule)"
            strokeWidth={1}
          />
        );
      })}
      {/* 数据多边形 */}
      <path
        d={dataPath}
        fill="var(--color-accent)"
        fillOpacity={0.15}
        stroke="var(--color-accent)"
        strokeWidth={2}
        strokeLinejoin="round"
      />
      {/* 数据点 + 标签 */}
      {dataPoints.map((p, i) => {
        const d = data[i];
        if (!d) return null;
        const labelP = pointAt(i, radius + 24);
        return (
          <g key={`pt-${i}`}>
            <circle
              cx={p.x}
              cy={p.y}
              r={4}
              fill="var(--color-accent)"
              stroke="var(--bg-paper)"
              strokeWidth={2}
            />
            <text
              x={labelP.x}
              y={labelP.y}
              textAnchor="middle"
              fontSize="11"
              fontFamily="var(--font-family-sans)"
              fill="var(--color-ink-muted)"
            >
              {d.knowledgePoint}
            </text>
            <text
              x={labelP.x}
              y={labelP.y + 13}
              textAnchor="middle"
              fontSize="10"
              fontFamily="var(--font-family-mono)"
              fontWeight="600"
              fill="var(--color-accent)"
            >
              {d.mastery}%
            </text>
          </g>
        );
      })}
    </svg>
  );
}
