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

test("서로 다른 유저는 /projects 에서 자신의 프로젝트만 볼 수 있어야 한다", async ({ page }) => {
  type Project = {
    id: string;
    title: string;
    slug: string;
    status: string;
    createdAt: string;
    updatedAt: string;
  };

  let currentUser: "A" | "B" = "A";
  const projectsA: Project[] = [];
  const projectsB: Project[] = [];
  let nextId = 1;

  const nowIso = () => new Date().toISOString();

  await page.route("**/api/auth/me", async (route) => {
    const email = currentUser === "A" ? "user-a@example.com" : "user-b@example.com";
    const id = currentUser === "A" ? "user-a" : "user-b";

    await route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify({ id, email, tokenVersion: 1 }),
    });
  });

  await page.route("**/api/projects*", async (route) => {
    const request = route.request();
    const url = new URL(request.url());
    const method = request.method();

    const ownerProjects = currentUser === "A" ? projectsA : projectsB;
    const otherProjects = currentUser === "A" ? projectsB : projectsA;

    if (url.pathname === "/api/projects" && method === "GET") {
      await route.fulfill({
        status: 200,
        contentType: "application/json",
        body: JSON.stringify(ownerProjects),
      });
      return;
    }

    if (url.pathname === "/api/projects" && method === "POST") {
      const bodyText = request.postData() ?? "{}";
      const body = JSON.parse(bodyText) as Partial<Project> & { title?: string; slug?: string };
      const slug = body.slug ?? "";
      const title = body.title ?? "";

      const conflict = otherProjects.find((p) => p.slug === slug);
      if (conflict) {
        await route.fulfill({
          status: 409,
          contentType: "application/json",
          body: JSON.stringify({ message: "이미 다른 사용자가 사용 중인 프로젝트 주소입니다." }),
        });
        return;
      }

      const existingIndex = ownerProjects.findIndex((p) => p.slug === slug);
      const now = nowIso();

      let project: Project;
      if (existingIndex >= 0) {
        const existing = ownerProjects[existingIndex];
        project = { ...existing, title: title || existing.title, updatedAt: now };
        ownerProjects[existingIndex] = project;
      } else {
        project = {
          id: String(nextId++),
          title: title || "제목 없음",
          slug,
          status: "DRAFT",
          createdAt: now,
          updatedAt: now,
        };
        ownerProjects.push(project);
      }

      await route.fulfill({
        status: 201,
        contentType: "application/json",
        body: JSON.stringify(project),
      });
      return;
    }

    await route.fulfill({
      status: 404,
      contentType: "application/json",
      body: JSON.stringify({ message: "Not implemented in E2E mock" }),
    });
  });

  // 1) 유저 A: 에디터에서 프로젝트를 저장하고, /projects 에서 자신의 프로젝트만 보여야 한다.
  await page.goto("/editor");

  const propertiesSidebarA = page.getByTestId("properties-sidebar");
  await propertiesSidebarA.getByLabel("프로젝트 제목").fill("유저 A 프로젝트");
  await propertiesSidebarA.getByLabel("프로젝트 주소 (slug)").fill("user-a-project");

  await page.getByRole("button", { name: "메뉴 ▼" }).click();
  await page.getByRole("button", { name: "프로젝트 저장/불러오기" }).click();
  await page.getByRole("button", { name: "저장 (로컬 + 서버)" }).click();

  await expect(page).toHaveURL(/\/_?projects/);
  await expect(page.getByText("유저 A 프로젝트")).toBeVisible();
  await expect(page.getByText("user-a-project")).toBeVisible();
  await expect(page.getByText("user-b-project")).toHaveCount(0);

  // 2) 유저 B: currentUser 전환 후 별도 프로젝트를 저장하고, /projects 에서 자신의 것만 보여야 한다.
  currentUser = "B";

  await page.goto("/editor");

  const propertiesSidebarB = page.getByTestId("properties-sidebar");
  await propertiesSidebarB.getByLabel("프로젝트 제목").fill("유저 B 프로젝트");
  await propertiesSidebarB.getByLabel("프로젝트 주소 (slug)").fill("user-b-project");

  await page.getByRole("button", { name: "메뉴 ▼" }).click();
  await page.getByRole("button", { name: "프로젝트 저장/불러오기" }).click();
  await page.getByRole("button", { name: "저장 (로컬 + 서버)" }).click();

  await expect(page).toHaveURL(/\/_?projects/);
  await expect(page.getByText("유저 B 프로젝트")).toBeVisible();
  await expect(page.getByText("user-b-project")).toBeVisible();
  await expect(page.getByText("유저 A 프로젝트")).toHaveCount(0);

  // 3) 다시 유저 A 로 전환했을 때, /projects 에서는 유저 A 의 프로젝트만 보여야 한다.
  currentUser = "A";

  await page.goto("/projects");

  await expect(page.getByText("유저 A 프로젝트")).toBeVisible();
  await expect(page.getByText("user-a-project")).toBeVisible();
  await expect(page.getByText("유저 B 프로젝트")).toHaveCount(0);
});
