import { test, expect } from "@playwright/test";

// 대시보드 E2E TDD
// - 비로그인 사용자는 /dashboard 접근 시 /login 으로 리다이렉트되어야 한다.
// - 로그인 사용자는 /dashboard 에서 요약 지표 + 프로젝트 카드 리스트를 볼 수 있어야 한다.
// - 백엔드/DB 에 의존하지 않도록 /api/dashboard/overview 를 Playwright 라우팅으로 목킹한다.

test("비로그인 사용자가 /dashboard 에 접근하면 /login 으로 리다이렉트되어야 한다", async ({ page }) => {
  await page.route("**/api/dashboard/overview", async (route) => {
    await route.fulfill({
      status: 401,
      contentType: "application/json",
      body: JSON.stringify({ message: "로그인이 필요합니다." }),
    });
  });

  await page.goto("/dashboard");

  await expect(page.getByRole("heading", { name: "Log in" })).toBeVisible();
});

test("로그인 사용자가 /dashboard 에 접근하면 요약 지표와 프로젝트 카드 리스트, 일별 그래프를 볼 수 있어야 한다", async ({ page }) => {
  await page.route("**/api/dashboard/overview", async (route) => {
    await route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify({
        summaryStats: {
          totalProjects: 2,
          totalSubmissions: 3,
          todaySubmissions: 1,
          last7DaysSubmissions: 3,
        },
        projectStats: [
          {
            projectId: "proj-1",
            title: "테스트 프로젝트 A",
            slug: "test-project-a",
            status: "DRAFT",
            totalSubmissions: 2,
            lastSubmissionAt: "2025-01-02T12:00:00.000Z",
          },
          {
            projectId: "proj-2",
            title: "테스트 프로젝트 B",
            slug: "test-project-b",
            status: "PUBLISHED",
            totalSubmissions: 1,
            lastSubmissionAt: "2025-01-03T09:30:00.000Z",
          },
        ],
        dailySubmissions: [
          { date: "2024-12-26", count: 1 },
          { date: "2025-01-02", count: 1 },
          { date: "2025-01-03", count: 1 },
        ],
      }),
    });
  });

  await page.goto("/dashboard");

  // 대시보드 헤더가 보여야 한다.
  await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();

  // 상단 헤더 내비게이션이 보여야 한다.
  const dashboardLink = page.getByRole("link", { name: "Dashboard" });
  await expect(dashboardLink).toBeVisible();

  const projectsLink = page.getByRole("link", { name: "Projects" });
  await expect(projectsLink).toBeVisible();

  const submissionsLink = page.getByRole("link", { name: "All submissions" });
  await expect(submissionsLink).toBeVisible();

  const menuButton = page.getByRole("button", { name: "Menu" });
  await expect(menuButton).toBeVisible();

  // 상단 요약 위젯의 지표들이 기대 값으로 렌더되어야 한다.
  const totalProjects = page.getByTestId("dashboard-summary-total-projects");
  await expect(totalProjects).toContainText("2");

  const totalSubmissions = page.getByTestId("dashboard-summary-total-submissions");
  await expect(totalSubmissions).toContainText("3");

  const todaySubmissions = page.getByTestId("dashboard-summary-today-submissions");
  await expect(todaySubmissions).toContainText("1");

  const last7DaysSubmissions = page.getByTestId(
    "dashboard-summary-last7days-submissions",
  );
  await expect(last7DaysSubmissions).toContainText("3");

  // 프로젝트 카드 리스트가 2개 렌더링되어야 한다.
  const projectCards = page.getByTestId("dashboard-project-card");
  await expect(projectCards).toHaveCount(2);

  await expect(projectCards.nth(0)).toContainText("테스트 프로젝트 A");
  await expect(projectCards.nth(0)).toContainText("test-project-a");
  await expect(projectCards.nth(0)).toContainText("2");

  await expect(projectCards.nth(1)).toContainText("테스트 프로젝트 B");
  await expect(projectCards.nth(1)).toContainText("test-project-b");
  await expect(projectCards.nth(1)).toContainText("1");

  // 일별 제출 수 그래프가 렌더링되어야 한다.
  const dailyChart = page.getByTestId("dashboard-daily-chart");
  await expect(dailyChart).toBeVisible();

  const dailyBars = page.getByTestId("dashboard-daily-chart-bar");
  await expect(dailyBars).toHaveCount(3);
  
  // 메뉴 버튼을 클릭하면 로그아웃 항목이 보여야 한다.
  await menuButton.click();
  await expect(page.getByRole("button", { name: "Log out" })).toBeVisible();
});

test("로그인 사용자가 / 에 접속하면 대시보드로 진입해야 한다", async ({ page }) => {
  await page.route("**/api/dashboard/overview", async (route) => {
    await route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify({
        summaryStats: {
          totalProjects: 1,
          totalSubmissions: 0,
          todaySubmissions: 0,
          last7DaysSubmissions: 0,
        },
        projectStats: [],
        dailySubmissions: [],
      }),
    });
  });

  await page.goto("/");

  await expect(page).toHaveURL(/\/dashboard/);
  await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});
