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

import {
  defaultCharacterChatUrl,
  dismissChatInterruptions,
  enterChatFromSplash,
} from "@e2e/fixtures/test-helpers";

const preReleaseHost = "frontend-test.banlv-ai.com";
const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? "";

test.describe("pre-release multi-message lock types", () => {
  test.setTimeout(120_000);
  test.skip(
    !baseURL.includes(preReleaseHost),
    `Run this test only with PLAYWRIGHT_BASE_URL pointing at ${preReleaseHost}.`,
  );

  test("returns locked image, locked voice, then unlocked text", async ({
    page,
  }) => {
    await enterChatFromSplash(page, {
      expectedUrl: defaultCharacterChatUrl,
      timeout: 20_000,
      waitUntil: "domcontentloaded",
    });
    await dismissChatInterruptions(page);

    const messageInput = page.getByRole("textbox", { name: "Message" });
    await expect(messageInput).toBeEnabled({ timeout: 30_000 });

    let aiMessageCount = await page
      .locator('[aria-label="AI message"]')
      .count();

    const imageReply = await sendMessageAndWaitForAiReply(
      page,
      messageInput,
      "发个图片",
      aiMessageCount,
    );
    aiMessageCount += 1;
    await expect(
      imageReply.getByRole("button", { name: "Open image in fullscreen" }),
    ).toBeVisible();
    await expect(
      imageReply
        .getByRole("button", { name: "Open image in fullscreen" })
        .locator("img"),
    ).toHaveClass(/blur-sm/);

    const voiceReply = await sendMessageAndWaitForAiReply(
      page,
      messageInput,
      "发送语音",
      aiMessageCount,
    );
    aiMessageCount += 1;
    await expect(
      voiceReply.getByRole("button", { name: "Unlock voice message" }),
    ).toBeVisible();
    await expect(
      voiceReply.getByRole("button", { name: "Play voice message" }),
    ).toBeDisabled();

    const textReply = await sendMessageAndWaitForAiReply(
      page,
      messageInput,
      "你好",
      aiMessageCount,
    );
    await expect(
      textReply.getByRole("button", { name: "Unlock voice message" }),
    ).toHaveCount(0);
    await expect(
      textReply.getByRole("group", { name: "Locked private image" }),
    ).toHaveCount(0);
    await expect(textReply.getByRole("button", { name: /Unlock/ })).toHaveCount(0);
    await expect(textReply).toContainText(/\S/);
  });
});

async function sendMessageAndWaitForAiReply(
  page: Page,
  messageInput: Locator,
  message: string,
  previousAiMessageCount: number,
): Promise<Locator> {
  const aiMessages = page.locator('[aria-label="AI message"]');
  const sendRequestPromise = page.waitForRequest("**/api/chat/send");

  await messageInput.fill(message);
  await messageInput.press("Enter");

  const sendRequest = await sendRequestPromise;
  expect(sendRequest.postDataJSON()).toMatchObject({ message });

  await expect
    .poll(() => aiMessages.count(), { timeout: 60_000 })
    .toBeGreaterThan(previousAiMessageCount);
  const latestReply = aiMessages.last();
  await expect(latestReply).toBeVisible();
  return latestReply;
}
