// ParentDashboard 组件单测
// 依据：02-architecture-design.md §15 仪表盘设计
// 覆盖：加载态 / 错误态 / 空态 / 正常态（含 ChildSummaryCard + AttendanceCalendar）

import { describe, it, expect, beforeEach, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { ParentDashboard } from "./ParentDashboard";
import type { ChildInfo, ChildSummary, AttendanceRecord } from "@/types";

// mock useChildSwitcher
const mockUseChildSwitcher = vi.fn();
vi.mock("@/hooks/useChildSwitcher", () => ({
  useChildSwitcher: () => mockUseChildSwitcher(),
}));

// mock useChildSummary
const mockUseChildSummary = vi.fn();
vi.mock("@/hooks/useChildSummary", () => ({
  useChildSummary: () => mockUseChildSummary(),
}));

// mock useChildAttendance
const mockUseChildAttendance = vi.fn();
vi.mock("@/hooks/useChildAttendance", () => ({
  useChildAttendance: () => mockUseChildAttendance(),
}));

const mockChild: ChildInfo = {
  id: "student-001",
  name: "张小明",
  grade: "grade.7",
  schoolName: "实验中学",
  classId: "class-7-1",
  className: "初一(1)班",
};

const mockSummary: ChildSummary = {
  childId: "student-001",
  avgScore: 90,
  classRank: 5,
  classSize: 45,
  attendanceRate: 0.96,
  pendingHomeworkCount: 2,
  recentGradeTrend: "up",
  recentScores: [
    {
      examId: "exam-001",
      examName: "期中数学",
      examDate: "2026-03-15T09:00:00Z",
      subject: "数学",
      studentScore: 92,
      classAverage: 78,
      gradeLevel: "A",
    },
  ],
  upcomingEvents: [],
};

const mockAttendance: AttendanceRecord[] = [
  { id: "att-1", date: "2026-06-01", status: "present" },
  { id: "att-2", date: "2026-06-02", status: "late" },
];

beforeEach(() => {
  mockUseChildSwitcher.mockReset();
  mockUseChildSummary.mockReset();
  mockUseChildAttendance.mockReset();
});

describe("ParentDashboard 加载态", () => {
  it("summaryLoading 且无 summary 时渲染骨架屏", () => {
    mockUseChildSwitcher.mockReturnValue({
      children: [mockChild],
      currentChild: mockChild,
      currentChildId: "student-001",
      switchChild: vi.fn(),
      loading: false,
      error: undefined,
      hasMultipleChildren: false,
    });
    mockUseChildSummary.mockReturnValue({
      summary: null,
      loading: true,
      error: undefined,
    });
    mockUseChildAttendance.mockReturnValue({
      attendance: [],
      loading: false,
      error: undefined,
    });
    const { container } = render(<ParentDashboard />);
    // 骨架屏使用 .skeleton class
    const skeletons = container.querySelectorAll(".skeleton");
    expect(skeletons.length).toBeGreaterThan(0);
  });

  it("attLoading 时考勤区域显示骨架屏", () => {
    mockUseChildSwitcher.mockReturnValue({
      children: [mockChild],
      currentChild: mockChild,
      currentChildId: "student-001",
      switchChild: vi.fn(),
      loading: false,
      error: undefined,
      hasMultipleChildren: false,
    });
    mockUseChildSummary.mockReturnValue({
      summary: mockSummary,
      loading: false,
      error: undefined,
    });
    mockUseChildAttendance.mockReturnValue({
      attendance: [],
      loading: true,
      error: undefined,
    });
    const { container } = render(<ParentDashboard />);
    // 标题已渲染（summary 已加载）
    expect(screen.getByText("张小明的学习概览")).toBeInTheDocument();
    // 考勤区域为骨架屏
    const skeletons = container.querySelectorAll(".skeleton");
    expect(skeletons.length).toBeGreaterThan(0);
  });
});

describe("ParentDashboard 错误态", () => {
  it("summaryError 时渲染错误信息", () => {
    mockUseChildSwitcher.mockReturnValue({
      children: [mockChild],
      currentChild: mockChild,
      currentChildId: "student-001",
      switchChild: vi.fn(),
      loading: false,
      error: undefined,
      hasMultipleChildren: false,
    });
    const err = new Error("网络异常");
    mockUseChildSummary.mockReturnValue({
      summary: null,
      loading: false,
      error: err,
    });
    mockUseChildAttendance.mockReturnValue({
      attendance: [],
      loading: false,
      error: undefined,
    });
    render(<ParentDashboard />);
    expect(screen.getByText(/加载失败/)).toBeInTheDocument();
    expect(screen.getByText(/网络异常/)).toBeInTheDocument();
  });
});

describe("ParentDashboard 空态", () => {
  it("无 summary 时返回 null（不渲染内容）", () => {
    mockUseChildSwitcher.mockReturnValue({
      children: [mockChild],
      currentChild: mockChild,
      currentChildId: "student-001",
      switchChild: vi.fn(),
      loading: false,
      error: undefined,
      hasMultipleChildren: false,
    });
    mockUseChildSummary.mockReturnValue({
      summary: null,
      loading: false,
      error: undefined,
    });
    mockUseChildAttendance.mockReturnValue({
      attendance: [],
      loading: false,
      error: undefined,
    });
    const { container } = render(<ParentDashboard />);
    expect(container.firstChild).toBeNull();
  });

  it("无 currentChild 时返回 null", () => {
    mockUseChildSwitcher.mockReturnValue({
      children: [],
      currentChild: null,
      currentChildId: null,
      switchChild: vi.fn(),
      loading: false,
      error: undefined,
      hasMultipleChildren: false,
    });
    mockUseChildSummary.mockReturnValue({
      summary: mockSummary,
      loading: false,
      error: undefined,
    });
    mockUseChildAttendance.mockReturnValue({
      attendance: [],
      loading: false,
      error: undefined,
    });
    const { container } = render(<ParentDashboard />);
    expect(container.firstChild).toBeNull();
  });
});

describe("ParentDashboard 正常态", () => {
  beforeEach(() => {
    mockUseChildSwitcher.mockReturnValue({
      children: [mockChild],
      currentChild: mockChild,
      currentChildId: "student-001",
      switchChild: vi.fn(),
      loading: false,
      error: undefined,
      hasMultipleChildren: false,
    });
    mockUseChildSummary.mockReturnValue({
      summary: mockSummary,
      loading: false,
      error: undefined,
    });
    mockUseChildAttendance.mockReturnValue({
      attendance: mockAttendance,
      loading: false,
      error: undefined,
    });
  });

  it("渲染子女名称的标题", () => {
    render(<ParentDashboard />);
    expect(screen.getByText("张小明的学习概览")).toBeInTheDocument();
  });

  it("渲染 ChildSummaryCard 指标", () => {
    render(<ParentDashboard />);
    expect(screen.getByText("平均分")).toBeInTheDocument();
    expect(screen.getByText("90")).toBeInTheDocument();
  });

  it("渲染 AttendanceCalendar 标题", () => {
    render(<ParentDashboard />);
    // AttendanceCalendar 显示当前月份考勤标题
    expect(screen.getByText(/考勤/)).toBeInTheDocument();
  });

  it("summary 已加载但 attLoading 时不渲染考勤日历内容（渲染骨架）", () => {
    mockUseChildAttendance.mockReturnValue({
      attendance: [],
      loading: true,
      error: undefined,
    });
    const { container } = render(<ParentDashboard />);
    // 骨架屏存在
    expect(container.querySelectorAll(".skeleton").length).toBeGreaterThan(0);
  });
});
