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

import { mockCoreApis } from "@e2e/fixtures/api-mocks";
import { apiEnvelope } from "@e2e/fixtures/data/common";
import { createPaidImageHistoryResponse } from "@e2e/fixtures/data/chat";
import {
  paidImageDisplayMessageId,
  paidImageMessageId,
} from "@e2e/fixtures/test-data";
import {
  clearBrowserState,
  completeVipPayment,
  defaultCharacterChatPath,
  dismissChatInterruptions,
  enterChatFromSplash,
  expectInsufficientCreditsDialog,
  expectVipChatSubscriptionUrl,
  submitEmailLogin,
  switchToEmailSignIn,
} from "@e2e/fixtures/test-helpers";

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

test("guest can unlock a paid image after email login and subscription payment", async ({
  page,
}) => {
  await enterChatFromSplash(page);
  await dismissChatInterruptions(page);

  const messageInput = page.getByRole("textbox", { name: "Message" });
  await expect(messageInput).toBeVisible({ timeout: 10_000 });
  await messageInput.fill("给我发图片");

  const sendRequestPromise = page.waitForRequest("**/api/chat/send");
  await messageInput.press("Enter");

  const sendRequest = await sendRequestPromise;
  expect(sendRequest.postDataJSON()).toMatchObject({
    message: "给我发图片",
  });

  const lockedImageCard = page.getByRole("group", {
    name: "Locked private image",
  }).last();
  await expect(lockedImageCard).toBeVisible();
  await expect(lockedImageCard.locator("img")).toHaveCount(0);
  await lockedImageCard
    .getByRole("button", { name: "Unlock private image" })
    .click();

  await expect(page).toHaveURL(/\/auth\?redirect=/);
  expect(new URL(page.url()).searchParams.get("redirect")).toBe(
    defaultCharacterChatPath,
  );

  await switchToEmailSignIn(page);
  const unlockRequestPromise = page.waitForRequest(
    "**/api/chat/unlock-private",
  );
  await submitEmailLogin(page, {
    expectedUrl: new RegExp(`${defaultCharacterChatPath}$`),
  });

  const unlockRequest = await unlockRequestPromise;
  expect(unlockRequest.postDataJSON()).toMatchObject({
    messageId: paidImageMessageId,
  });

  const insufficientCreditsDialog = await expectInsufficientCreditsDialog(page);
  await insufficientCreditsDialog
    .getByRole("button", { name: "Top up now" })
    .click();

  await expectVipChatSubscriptionUrl(page);
  await completeVipPayment(page);

  await expect(page).toHaveURL(
    new RegExp(
      `${defaultCharacterChatPath}(?:\\?image=${encodeURIComponent(paidImageDisplayMessageId)})?$`,
    ),
  );
  expect(new URL(page.url()).pathname).toBe(defaultCharacterChatPath);
  await expect(page.getByRole("textbox", { name: "Message" })).toBeVisible();
});

test("fullscreen image closes from its back button, the image, and browser history Back", async ({
  page,
}) => {
  await page.route("**/api/chat/history**", async (route) => {
    await route.fulfill({
      json: apiEnvelope(createPaidImageHistoryResponse(true)),
    });
  });
  await enterChatFromSplash(page);
  await dismissChatInterruptions(page);

  const imageButton = page.getByRole("button", {
    name: "Open image in fullscreen",
  });
  const imageDialog = page.getByRole("dialog", { name: "Fullscreen image" });

  await imageButton.click();
  await expect(imageDialog).toBeVisible();
  await imageDialog.getByRole("button", { name: "Back" }).click();
  await expect(imageDialog).toHaveCount(0);
  await expect(page).toHaveURL(defaultCharacterChatPath);

  await imageButton.click();
  await expect(imageDialog).toBeVisible();
  await imageDialog.locator("img").click();
  await expect(imageDialog).toHaveCount(0);
  await expect(page).toHaveURL(defaultCharacterChatPath);

  await imageButton.click();
  await expect(imageDialog).toBeVisible();
  await page.goBack();
  await expect(imageDialog).toHaveCount(0);
  await expect(page).toHaveURL(defaultCharacterChatPath);
});
