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

import { mockCoreApis } from "@e2e/fixtures/api-mocks";
import {
  clearBrowserState,
  defaultCharacterProfilePath,
  dismissChatInterruptions,
  enterChatFromSplash,
  submitEmailLogin,
  switchToEmailSignIn,
} from "@e2e/fixtures/test-helpers";

const characters = [
  { slug: "elio", displayName: "Elio Silvestri" },
  { slug: "maya", displayName: "Maya Tan" },
  { slug: "nayeli", displayName: "Nayeli Cervantes" },
] as const;

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

test("guest user avatar returns to Profile after sign-in", async ({
  page,
}) => {
  await enterChatFromSplash(page, { timeout: 30_000 });
  await sendMessage(page, "Open my profile");

  await page.getByRole("button", { name: "Open profile" }).click();

  await expect(page).toHaveURL(/\/auth\?redirect=/);
  expect(new URL(page.url()).searchParams.get("redirect")).toBe(
    defaultCharacterProfilePath,
  );
  await switchToEmailSignIn(page);
  await submitEmailLogin(page, {
    expectedUrl: new RegExp(
      `${defaultCharacterProfilePath.replace("?", "\\?")}$`,
    ),
  });
});

for (const character of characters) {
  test(`${character.displayName} avatar opens the matching Private Zone`, async ({
    page,
  }) => {
    await enterCharacterChat(page, character.slug);
    await sendMessage(page, `Hello ${character.displayName}`);

    await page
      .getByRole("button", {
        name: `Open ${character.displayName}'s private zone`,
      })
      .last()
      .click();

    await expect(page).toHaveURL(
      new RegExp(`/characters/${character.slug}/private-zone(?:\\?.*)?$`),
    );
  });
}

async function enterCharacterChat(page: Page, characterSlug: string) {
  const chatPath = `/characters/${characterSlug}/chat`;

  await page.goto(`/characters/${characterSlug}/splash`);
  await page.getByRole("button", { name: "Start Chatting" }).click();
  await expect(page).toHaveURL(new RegExp(`${chatPath}(?:\\?.*)?$`));
  await dismissChatInterruptions(page);
  await expect(page.getByRole("textbox", { name: "Message" })).toBeEnabled({
    timeout: 20_000,
  });
}

async function sendMessage(page: Page, message: string) {
  await dismissChatInterruptions(page);
  const messageInput = page.getByRole("textbox", { name: "Message" });

  await expect(messageInput).toBeEnabled({ timeout: 20_000 });
  await messageInput.fill(message);
  await messageInput.press("Enter");
  await expect(page.getByRole("button", { name: "Open profile" })).toBeVisible({
    timeout: 10_000,
  });
}
