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

const BACKEND_BASE_URL = "http://127.0.0.1:5150";
const FRONTEND_BASE_URL = "http://127.0.0.1:4321";

type AdminSubscriptionRecord = {
  id: number;
  channel_type: string;
  target: string;
};

type AdminSubscriptionListResponse = {
  subscriptions: AdminSubscriptionRecord[];
};

declare global {
  interface Window {
    __termiPushMessages?: unknown[];
    __termiSubscriptionPopupReady?: boolean;
  }
}

test("浏览器订阅后可以收到测试推送", async ({ request }, testInfo) => {
  const context = await chromium.launchPersistentContext(
    testInfo.outputPath("web-push-user-data"),
    {
      headless: true,
      viewport: { width: 1280, height: 800 },
    },
  );

  try {
    await context.grantPermissions(["notifications"], {
      origin: FRONTEND_BASE_URL,
    });

    const page = context.pages()[0] ?? (await context.newPage());

    await page.addInitScript(() => {
      window.__termiPushMessages = [];
      navigator.serviceWorker?.addEventListener("message", (event) => {
        if (event.data?.type === "termi:web-push-received") {
          window.__termiPushMessages?.push(event.data.payload ?? null);
        }
      });
    });

    await page.goto(`${FRONTEND_BASE_URL}/maintenance?returnTo=%2F`);
    await page.getByLabel("访问口令").fill("termi");
    await page.getByRole("button", { name: "进入站点" }).click();
    await page.waitForURL(`${FRONTEND_BASE_URL}/`);

    await page.waitForFunction(
      () => window.__termiSubscriptionPopupReady === true,
    );

    await page.locator("[data-subscription-popup-open]").click();

    const subscribeResponsePromise = page.waitForResponse(
      (response) =>
        response.url().includes("/api/subscriptions/combined") &&
        response.request().method() === "POST",
    );

    await page.locator("[data-subscription-popup-submit]").click();

    const subscribeResponse = await subscribeResponsePromise;
    expect(subscribeResponse.ok()).toBeTruthy();
    await expect(
      page.locator('[data-subscription-popup-status][data-state="success"]'),
    ).toBeVisible();

    const endpoint = await page.evaluate(async () => {
      const registration = await navigator.serviceWorker.ready;
      const subscription = await registration.pushManager.getSubscription();
      return subscription?.endpoint ?? null;
    });

    expect(endpoint).toBeTruthy();

    const loginResponse = await request.post(
      `${BACKEND_BASE_URL}/api/admin/session/login`,
      {
        data: {
          username: "admin",
          password: "admin123",
        },
      },
    );
    expect(loginResponse.ok()).toBeTruthy();

    const subscriptionsResponse = await request.get(
      `${BACKEND_BASE_URL}/api/admin/subscriptions`,
    );
    expect(subscriptionsResponse.ok()).toBeTruthy();
    const subscriptionsPayload =
      (await subscriptionsResponse.json()) as AdminSubscriptionListResponse;
    const subscription = subscriptionsPayload.subscriptions.find(
      (item) => item.channel_type === "web_push" && item.target === endpoint,
    );

    expect(subscription).toBeTruthy();

    const testResponse = await request.post(
      `${BACKEND_BASE_URL}/api/admin/subscriptions/${subscription?.id}/test`,
    );
    expect(testResponse.ok()).toBeTruthy();

    await page.waitForFunction(
      () =>
        Array.isArray(window.__termiPushMessages) &&
        window.__termiPushMessages.length > 0,
      undefined,
      { timeout: 45_000 },
    );

    const messages = await page.evaluate(() => window.__termiPushMessages ?? []);
    expect(messages.length).toBeGreaterThan(0);
  } finally {
    await context.close();
  }
});
