import { describe, it, expect, afterEach, vi } from "vitest";
import { render, screen, cleanup, waitFor } from "@testing-library/react";

import DashboardPage from "@/app/dashboard/page";

export const pushMock = vi.fn();

vi.mock("next/navigation", () => {
  return {
    __esModule: true,
    useRouter: () => ({ push: pushMock }),
  };
});

afterEach(() => {
  cleanup();
  vi.unstubAllGlobals();
  vi.clearAllMocks();
});

describe("DashboardPage - GNB와 테마", () => {
  it("GNB에서 현재 페이지인 '대시보드' 탭에 aria-current=\"page\"가 설정되어야 한다", async () => {
    const overview = {
      summaryStats: {
        totalProjects: 0,
        totalSubmissions: 0,
        todaySubmissions: 0,
        last7DaysSubmissions: 0,
      },
      projectStats: [],
      dailySubmissions: [],
    };

    const fetchMock = vi.fn().mockResolvedValue(
      new Response(JSON.stringify(overview), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      }),
    );

    vi.stubGlobal("fetch", fetchMock);

    render(<DashboardPage />);

    const dashboardLink = await screen.findByRole("link", { name: "Dashboard" });
    const projectsLink = await screen.findByRole("link", { name: "Projects" });
    const submissionsLink = await screen.findByRole("link", { name: "All submissions" });

    expect(dashboardLink.getAttribute("href")).toBe("/dashboard");
    expect(dashboardLink.getAttribute("aria-current")).toBe("page");

    expect(projectsLink.getAttribute("aria-current")).toBeNull();
    expect(submissionsLink.getAttribute("aria-current")).toBeNull();
  });

  it("헤더에 테마 전환 버튼이 있고 클릭 시 html 요소의 dark 클래스가 토글되어야 한다", async () => {
    const overview = {
      summaryStats: {
        totalProjects: 0,
        totalSubmissions: 0,
        todaySubmissions: 0,
        last7DaysSubmissions: 0,
      },
      projectStats: [],
      dailySubmissions: [],
    };

    const fetchMock = vi.fn().mockResolvedValue(
      new Response(JSON.stringify(overview), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      }),
    );

    vi.stubGlobal("fetch", fetchMock);

    render(<DashboardPage />);

    const html = document.documentElement;
    html.classList.remove("dark");

    const themeToggleButton = await screen.findByRole("button", { name: "Toggle theme" });

    expect(html.classList.contains("dark")).toBe(false);

    themeToggleButton.click();

    expect(html.classList.contains("dark")).toBe(true);

    themeToggleButton.click();

    expect(html.classList.contains("dark")).toBe(false);
  });

  it("대시보드 요약 카드와 프로젝트 카드가 라이트/다크 테마에서 읽기 쉬운 텍스트 색상 클래스를 사용해야 한다", async () => {
    const overview = {
      summaryStats: {
        totalProjects: 1,
        totalSubmissions: 10,
        todaySubmissions: 2,
        last7DaysSubmissions: 5,
      },
      projectStats: [
        {
          projectId: "p1",
          title: "Test project 1",
          slug: "test-project-1",
          status: "DRAFT",
          totalSubmissions: 3,
          lastSubmissionAt: "2025-01-01T00:00:00.000Z",
        },
      ],
      dailySubmissions: [],
    };

    const fetchMock = vi.fn().mockResolvedValue(
      new Response(JSON.stringify(overview), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      }),
    );

    vi.stubGlobal("fetch", fetchMock as any);

    const { container } = render(<DashboardPage />);

    // 요약 카드가 렌더링될 때까지 기다린다.
    await screen.findByTestId("dashboard-summary-total-projects");

    const summaryCard = container.querySelector(
      '[data-testid="dashboard-summary-total-projects"]',
    ) as HTMLElement | null;
    expect(summaryCard).not.toBeNull();

    const summaryLabel = summaryCard!.querySelector("span") as HTMLElement | null;
    expect(summaryLabel).not.toBeNull();
    const summaryLabelClass = summaryLabel!.className;
    expect(summaryLabelClass).toContain("text-slate-500");
    expect(summaryLabelClass).toContain("dark:text-slate-400");
  });
});
