import { expect, test } from "@playwright/test";
import {
  type Consent,
  installDevApiMock,
  makeClient,
  seedAuth,
} from "./helpers/devfront-fixtures";

test.describe("DevFront security and isolation", () => {
  test.beforeEach(async ({ page }) => {
    page.on("dialog", async (dialog) => {
      await dialog.accept();
    });
    await seedAuth(page);
  });

  test("tenant isolation: forbidden client shows blocked error", async ({
    page,
  }) => {
    const state = {
      clients: [makeClient("tenant-a-client", { name: "Tenant A app" })],
      consents: [] as Consent[],
      auditLogsByCursor: undefined,
    };
    await installDevApiMock(page, state);

    await page.goto("/clients/tenant-b-client");
    await expect(
      page.getByText(
        /Error loading (app|client)|앱 정보를 불러오지 못했습니다|클라이언트 정보를 불러오지 못했습니다/i,
      ),
    ).toBeVisible();
  });

  test("RBAC: user without manage_all permission should not see private apps", async ({
    page,
  }) => {
    const state = {
      clients: [
        makeClient("pkce-client", {
          name: "PKCE only app",
          type: "pkce",
        }),
      ],
      consents: [] as Consent[],
      auditLogsByCursor: undefined,
    };
    await installDevApiMock(page, state);

    await page.goto("/clients");
    await expect(page.getByText("PKCE only app")).toBeVisible();
    await expect(page.getByText("Server side App")).not.toBeVisible();
  });

  test("tenant_member user is blocked at AuthGuard", async ({ page }) => {
    await seedAuth(page, "tenant_member");

    await page.goto("/clients");
    await expect(
      page.getByText(/DevFront는 관리자 전용 화면입니다|administrator access/i),
    ).toBeVisible();
    await expect(page).toHaveURL(/\/clients$/);
  });

  test("rp_admin receives 403 on clients list and sees ForbiddenMessage", async ({
    page,
  }) => {
    await seedAuth(page, "rp_admin");

    const state = {
      clients: [] as ReturnType<typeof makeClient>[],
      consents: [] as Consent[],
      auditLogsByCursor: undefined,
    };
    await installDevApiMock(page, state);

    await page.route("**/api/v1/dev/clients", async (route) => {
      if (route.request().method() === "GET") {
        return route.fulfill({
          status: 403,
          contentType: "application/json",
          body: '{"error": "forbidden"}',
        });
      }
      return route.fallback();
    });

    await page.goto("/clients");
    await expect(
      page.getByText(/RP 관리자는|RP administrators can only access/i),
    ).toBeVisible();
  });

  test("tenant_admin receives 403 on audit logs and sees ForbiddenMessage", async ({
    page,
  }) => {
    await seedAuth(page, "tenant_admin");

    const state = {
      clients: [] as ReturnType<typeof makeClient>[],
      consents: [] as Consent[],
      auditLogsByCursor: undefined,
    };
    await installDevApiMock(page, state);

    await page.route("**/api/v1/dev/audit-logs*", async (route) => {
      if (route.request().method() === "GET") {
        return route.fulfill({
          status: 403,
          contentType: "application/json",
          body: '{"error": "forbidden"}',
        });
      }
      return route.fallback();
    });

    await page.goto("/audit-logs");
    await expect(
      page.getByText(/테넌트 관리자 권한|Tenant administrator permissions/i),
    ).toBeVisible();
  });
});
