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

import { mockCoreApis } from "@e2e/fixtures/api-mocks";
import { clearBrowserState } from "@e2e/fixtures/test-helpers";

const handoffToken = "e2e-handoff-token-that-is-at-least-32-characters";

test.beforeEach(async ({ baseURL, context, page }) => {
  await clearBrowserState(context, page, baseURL);
  await mockCoreApis(page, { topUpHandoffFlow: true });
});

test("user consumes a top-up handoff and opens credit packages as a formal Messenger user", async ({
  page,
}) => {
  const handoffRequestPromise = page.waitForRequest(
    "**/api/auth/handoff/topup/consume",
  );

  await page.goto(
    `/external-entry?target=topup&handoffToken=${encodeURIComponent(handoffToken)}`,
  );

  const handoffRequest = await handoffRequestPromise;
  expect(handoffRequest.method()).toBe("POST");
  expect(handoffRequest.postDataJSON()).toEqual({ handoffToken });

  await expect(page).toHaveURL("/subscription?type=topup");
  await expect(
    page.getByRole("button", { name: /Pay and Top Up/i }),
  ).toBeVisible();

  await expect
    .poll(() =>
      page.evaluate(() => ({
        loginProvider: localStorage.getItem("cozsweet:login_provider"),
        loginToken: localStorage.getItem("cozsweet:login_token"),
        refreshToken: localStorage.getItem("cozsweet:refresh_token"),
      })),
    )
    .toMatchObject({
      loginProvider: "facebookMessenger",
      loginToken: "e2e-messenger-token",
      refreshToken: "e2e-messenger-refresh-token",
    });
});

test("invalid top-up handoff does not log in and is removed from the URL", async ({
  page,
}) => {
  await page.route("**/api/auth/handoff/topup/consume", async (route) => {
    await route.fulfill({
      status: 410,
      json: {
        detail: {
          code: "HANDOFF_EXPIRED",
          message: "充值链接已过期",
        },
      },
    });
  });

  await page.goto(
    `/external-entry?target=topup&handoffToken=${encodeURIComponent(handoffToken)}`,
  );

  await expect(page).toHaveURL("/external-entry?target=topup");
  await expect(
    page.getByText(/invalid or has expired/i),
  ).toBeVisible();
  await expect
    .poll(() => page.evaluate(() => localStorage.getItem("cozsweet:login_provider")))
    .not.toBe("facebookMessenger");
});
