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

import { mockCoreApis } from "@e2e/fixtures/api-mocks";
import { apiEnvelope } from "@e2e/fixtures/data/common";
import {
  clearBrowserState,
  seedEmailSession,
} from "@e2e/fixtures/test-helpers";

const facebookAndroidUserAgent =
  "Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 " +
  "(KHTML, like Gecko) Version/4.0 Chrome/126.0.0.0 Mobile Safari/537.36 " +
  "[FB_IAB/FB4A;FBAV/566.0.0.48.73;]";
const handoffToken = "checkout-handoff-token-that-is-at-least-32-characters";

test.use({
  userAgent: facebookAndroidUserAgent,
  viewport: { width: 390, height: 844 },
});

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

test("consumes the handoff, removes its token, and does not create an order", async ({
  page,
}) => {
  await mockCoreApis(page, { checkoutHandoffFlow: true });
  let createOrderRequests = 0;
  page.on("request", (request) => {
    if (request.url().includes("/api/payment/create-order")) {
      createOrderRequests += 1;
    }
  });
  const consumeRequest = page.waitForRequest(
    "**/api/auth/handoff/checkout/consume",
  );

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

  expect((await consumeRequest).postDataJSON()).toEqual({ handoffToken });
  await expect(page).toHaveURL(
    /\/subscription\?planId=vip_monthly&autoRenew=1&character=nayeli&commercialOfferId=.*&payChannel=stripe/,
  );
  expect(page.url()).not.toContain("handoffToken");
  await expect.poll(() => createOrderRequests).toBe(0);
  await expect
    .poll(() =>
      page.evaluate(() => ({
        loginProvider: localStorage.getItem("cozsweet:login_provider"),
        loginToken: localStorage.getItem("cozsweet:login_token"),
      })),
    )
    .toEqual({ loginProvider: "email", loginToken: "e2e-checkout-token" });
});

test("offers the Facebook external-browser path before creating a Stripe order", async ({
  page,
}) => {
  await mockCoreApis(page);
  let createOrderRequests = 0;
  page.on("request", (request) => {
    if (request.url().includes("/api/payment/create-order")) {
      createOrderRequests += 1;
    }
  });
  await page.route("**/api/auth/handoff/checkout", async (route) => {
    await route.fulfill({
      json: apiEnvelope({
        externalUrl:
          "https://cozsweet.com/external-entry?target=checkout&handoffToken=opaque-token",
        expiresAt: "2026-07-28T16:00:00+00:00",
      }),
    });
  });

  await seedEmailSession(page);
  await page.goto("/subscription?type=vip&payChannel=stripe&character=maya");
  await page.getByRole("button", { name: /Monthly,/i }).click();
  const externalButton = page.getByRole("button", {
    name: "Open in browser for more payment methods",
  });
  const paymentButton = page.getByRole("button", { name: "Pay and Top Up" });
  await expect(externalButton).toBeVisible();
  await expect(externalButton).toBeEnabled();
  await expect(paymentButton).toBeVisible();
  await expect(
    page.getByRole("dialog", { name: "Automatic Renewal Confirmation" }),
  ).toHaveCount(0);
  const externalBox = await externalButton.boundingBox();
  const paymentBox = await paymentButton.boundingBox();
  expect(externalBox).not.toBeNull();
  expect(paymentBox).not.toBeNull();
  expect(externalBox!.y).toBeLessThan(paymentBox!.y);
  expect(paymentBox!.y + paymentBox!.height).toBeLessThanOrEqual(844);
  const handoffRequest = page.waitForRequest("**/api/auth/handoff/checkout");
  await externalButton.click();
  expect((await handoffRequest).postDataJSON()).toMatchObject({
    planId: "vip_monthly",
    autoRenew: true,
  });
  expect(createOrderRequests).toBe(0);
});
