import { mkdir } from "node:fs/promises";
import path from "node:path";
import { expect, type Page, type TestInfo, test } from "@playwright/test";
import {
  type Consent,
  installDevApiMock,
  makeClient,
  seedAuth,
} from "./helpers/devfront-fixtures";
import { captureEvidence } from "./helpers/evidence";

const existingTenantId = "11111111-1111-4111-8111-111111111111";
const addedTenantId = "22222222-2222-4222-8222-222222222222";

async function captureTenantAccessEvidence(
  page: Page,
  testInfo: TestInfo,
  name: string,
) {
  await captureEvidence(page, testInfo, name);
  const evidenceDir = path.join(process.cwd(), "e2e-evidence");
  await mkdir(evidenceDir, { recursive: true });
  await page.screenshot({
    path: path.join(evidenceDir, `${name}.png`),
    fullPage: true,
  });
}

test.describe("DevFront client tenant access settings", () => {
  test.beforeEach(async ({ page }) => {
    page.on("dialog", async (dialog) => {
      await dialog.accept();
    });
    await seedAuth(page);
  });

  test("adds and removes allowed tenants with UUID copy evidence", async ({
    page,
  }, testInfo) => {
    await page.addInitScript(() => {
      Object.defineProperty(window, "isSecureContext", {
        configurable: true,
        value: true,
      });
      Object.defineProperty(navigator, "clipboard", {
        configurable: true,
        value: {
          writeText: async (value: string) => {
            window.localStorage.setItem("__e2e_copied_text", value);
          },
        },
      });
    });

    const state = {
      clients: [
        makeClient("client-tenant-access", {
          name: "Tenant Access App",
          scopes: ["openid", "profile", "email"],
          metadata: {
            tenant_access_restricted: true,
            allowed_tenants: [existingTenantId],
          },
        }),
      ],
      consents: [] as Consent[],
      auditLogsByCursor: undefined,
      tenants: [
        {
          id: existingTenantId,
          name: "Alpha Tenant",
          slug: "alpha",
          description: "Existing allowed tenant",
          type: "organization",
        },
        {
          id: addedTenantId,
          name: "Beta Tenant",
          slug: "beta",
          description: "Tenant added during E2E",
          type: "organization",
        },
      ],
    };
    await installDevApiMock(page, state);

    await page.goto("/clients/client-tenant-access/settings");

    await expect(
      page.getByRole("heading", { name: /테넌트 접근 제한|Tenant access/i }),
    ).toBeVisible();
    await expect(
      page.getByTestId(`allowed-tenant-${existingTenantId}`),
    ).toContainText(existingTenantId);
    await page.getByTestId(`allowed-tenant-copy-${existingTenantId}`).click();
    await expect
      .poll(() =>
        page.evaluate(() => window.localStorage.getItem("__e2e_copied_text")),
      )
      .toBe(existingTenantId);

    await page
      .getByPlaceholder(/테넌트 이름 또는 슬러그로 검색|tenant name or slug/i)
      .fill("beta");
    await page.getByRole("button", { name: /Beta Tenant/i }).click();
    await expect(
      page.getByTestId(`allowed-tenant-${addedTenantId}`),
    ).toContainText(addedTenantId);
    await captureTenantAccessEvidence(
      page,
      testInfo,
      "tenant-access-allowed-tenant-added",
    );

    await page.getByRole("button", { name: /^저장$|^Save$/i }).click();
    await expect
      .poll(() => state.clients[0]?.metadata?.allowed_tenants)
      .toEqual([existingTenantId, addedTenantId]);

    await page.getByTestId(`allowed-tenant-remove-${addedTenantId}`).click();
    await expect(
      page.getByTestId(`allowed-tenant-${addedTenantId}`),
    ).toHaveCount(0);
    await expect(
      page.getByTestId(`allowed-tenant-${existingTenantId}`),
    ).toContainText(existingTenantId);
    await captureTenantAccessEvidence(
      page,
      testInfo,
      "tenant-access-allowed-tenant-deleted",
    );

    await page.getByRole("button", { name: /^저장$|^Save$/i }).click();
    await expect
      .poll(() => state.clients[0]?.metadata?.allowed_tenants)
      .toEqual([existingTenantId]);
  });
});
