// ChildGradeChart 组件单测（mock recharts）
// 依据：02-architecture-design.md §15.6 成绩图表设计
// 覆盖：渲染图表标题 / 数据映射 / 班级均对比线（虚线）/ classAverage 缺失时默认 0

import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import type { GradeDataPoint } from "@/types";

// mock recharts：渲染简单 div 包裹子元素，便于断言
vi.mock("recharts", () => ({
  ResponsiveContainer: ({ children }: { children: React.ReactNode }) => (
    <div data-testid="responsive-container">{children}</div>
  ),
  ComposedChart: ({
    children,
    data,
  }: {
    children: React.ReactNode;
    data: unknown[];
  }) => (
    <div data-testid="composed-chart" data-length={data.length}>
      {children}
    </div>
  ),
  Bar: ({ dataKey, fill }: { dataKey: string; fill: string }) => (
    <div data-testid="bar" data-key={dataKey} data-fill={fill} />
  ),
  Line: ({
    dataKey,
    stroke,
    strokeDasharray,
  }: {
    dataKey: string;
    stroke: string;
    strokeDasharray?: string;
  }) => (
    <div
      data-testid="line"
      data-key={dataKey}
      data-stroke={stroke}
      data-dash={strokeDasharray}
    />
  ),
  XAxis: (_props: unknown) => <div data-testid="x-axis" />,
  YAxis: (_props: unknown) => <div data-testid="y-axis" />,
  CartesianGrid: (_props: unknown) => <div data-testid="cartesian-grid" />,
  Tooltip: (_props: unknown) => <div data-testid="tooltip" />,
  Legend: (_props: unknown) => <div data-testid="legend" />,
}));

import { ChildGradeChart } from "./ChildGradeChart";

const mockGrades: GradeDataPoint[] = [
  {
    examId: "exam-001",
    examName: "期中数学",
    examDate: "2026-03-15T09:00:00Z",
    subject: "数学",
    studentScore: 92,
    classAverage: 78,
    gradeLevel: "A",
  },
  {
    examId: "exam-002",
    examName: "期中语文",
    examDate: "2026-03-16T09:00:00Z",
    subject: "语文",
    studentScore: 85,
    classAverage: 75,
    gradeLevel: "B",
  },
];

describe("ChildGradeChart 渲染", () => {
  it("渲染标题成绩对比", () => {
    render(<ChildGradeChart grades={mockGrades} />);
    expect(screen.getByText("成绩对比")).toBeInTheDocument();
  });

  it("渲染 ResponsiveContainer", () => {
    render(<ChildGradeChart grades={mockGrades} />);
    expect(screen.getByTestId("responsive-container")).toBeInTheDocument();
  });

  it("渲染 ComposedChart 并传入数据", () => {
    render(<ChildGradeChart grades={mockGrades} />);
    const chart = screen.getByTestId("composed-chart");
    expect(chart).toHaveAttribute("data-length", "2");
  });

  it("渲染 Bar（学生分数）和 Line（班级平均）", () => {
    render(<ChildGradeChart grades={mockGrades} />);
    const bars = screen.getAllByTestId("bar");
    const lines = screen.getAllByTestId("line");
    expect(bars).toHaveLength(1);
    expect(lines).toHaveLength(1);
    expect(bars[0]).toHaveAttribute("data-key", "学生分数");
    expect(lines[0]).toHaveAttribute("data-key", "班级平均");
  });

  it("班级平均线为虚线（strokeDasharray=5 5）", () => {
    render(<ChildGradeChart grades={mockGrades} />);
    const line = screen.getByTestId("line");
    expect(line).toHaveAttribute("data-dash", "5 5");
  });

  it("渲染 XAxis / YAxis / CartesianGrid / Tooltip / Legend", () => {
    render(<ChildGradeChart grades={mockGrades} />);
    expect(screen.getByTestId("x-axis")).toBeInTheDocument();
    expect(screen.getByTestId("y-axis")).toBeInTheDocument();
    expect(screen.getByTestId("cartesian-grid")).toBeInTheDocument();
    expect(screen.getByTestId("tooltip")).toBeInTheDocument();
    expect(screen.getByTestId("legend")).toBeInTheDocument();
  });
});

describe("ChildGradeChart 数据映射", () => {
  it("空 grades 数组渲染 0 条数据", () => {
    render(<ChildGradeChart grades={[]} />);
    const chart = screen.getByTestId("composed-chart");
    expect(chart).toHaveAttribute("data-length", "0");
  });

  it("classAverage 缺失时默认为 0", () => {
    const gradesWithoutAvg: GradeDataPoint[] = [
      {
        examId: "exam-003",
        examName: "测验",
        examDate: "2026-04-01T09:00:00Z",
        subject: "英语",
        studentScore: 88,
        gradeLevel: "B",
      },
    ];
    render(<ChildGradeChart grades={gradesWithoutAvg} />);
    // 仅验证不崩溃且渲染 1 条数据
    const chart = screen.getByTestId("composed-chart");
    expect(chart).toHaveAttribute("data-length", "1");
  });

  it("多条成绩数据正确映射", () => {
    const manyGrades: GradeDataPoint[] = Array.from({ length: 5 }, (_, i) => ({
      examId: `exam-${i}`,
      examName: `测验${i}`,
      examDate: "2026-03-15T09:00:00Z",
      subject: `科目${i}`,
      studentScore: 80 + i,
      classAverage: 70,
      gradeLevel: "B" as const,
    }));
    render(<ChildGradeChart grades={manyGrades} />);
    const chart = screen.getByTestId("composed-chart");
    expect(chart).toHaveAttribute("data-length", "5");
  });
});
