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

const PASSWORD = "SmokePass123!";
const apiBase = process.env.E2E_API_BASE || "/api/v1";
const apiOrigin = apiBase.endsWith("/api/v1")
  ? apiBase.slice(0, -"/api/v1".length)
  : "";

const routeBrowserApiToTestApi = async (
  page: import("@playwright/test").Page,
) => {
  if (!apiOrigin) return;
  await page.route("**/api/v1/**", async (route) => {
    const sourceUrl = new URL(route.request().url());
    const response = await route.fetch({
      url: `${apiOrigin}${sourceUrl.pathname}${sourceUrl.search}`,
    });
    await route.fulfill({ response });
  });
};

/** 登录操作，遇到 429 限流自动等待重试 */
async function loginWithRetry(
  request: APIRequestContext,
  email: string,
  password: string,
  maxRetries = 2,
) {
  for (let i = 0; i <= maxRetries; i++) {
    const response = await request.post(`${apiBase}/auth/login`, {
      data: { email, password },
    });
    if (response.status() !== 429) return response;
    console.log(`[login] 触发限流，等待 65s 后重试 (${i + 1}/${maxRetries})`);
    await new Promise((r) => setTimeout(r, 65000));
  }
  return request.post(`${apiBase}/auth/login`, {
    data: { email, password },
  });
}

test.describe("Title library flow", () => {
  test.describe.configure({ timeout: 120_000 });
  test("loads title library page and displays titles", async ({
    page,
    request,
  }) => {
    await routeBrowserApiToTestApi(page);
    const suffix = Date.now().toString(36);
    const email = `e2e-title-${suffix}@example.com`;
    const username = `e2e_title_${suffix}`;

    const register = await request.post(`${apiBase}/auth/register`, {
      data: { email, username, password: PASSWORD, display_name: username },
    });
    expect(register.status(), await register.text()).toBe(201);

    const registerData = (await register.json()) as { user_id: string };

    const login = await loginWithRetry(request, email, PASSWORD);
    expect(login.status(), await login.text()).toBe(200);
    const loginData = (await login.json()) as { access_token: string };
    const headers = { Authorization: `Bearer ${loginData.access_token}` };

    // Create a title so the titles page has at least one title card to display
    // (titles are loaded from API; new users have none by default)
    const createTitle = await request.post(`${apiBase}/titles`, {
      headers,
      data: {
        name: `E2E 测试标题 ${suffix}`,
        text: `E2E 测试标题内容 ${suffix}`,
        category: "default",
      },
    });
    expect(createTitle.status(), await createTitle.text()).toBe(201);

    await page.addInitScript(
      ({ token, user }) => {
        localStorage.setItem("access_token", token);
        localStorage.setItem(
          "auth-storage",
          JSON.stringify({
            state: { user, isAuthenticated: true },
            version: 0,
          }),
        );
      },
      {
        token: loginData.access_token,
        user: {
          id: registerData.user_id,
          user_id: registerData.user_id,
          email,
          username,
          display_name: username,
          is_email_verified: true,
          email_verified: true,
        },
      },
    );

    await page.goto("/app/titles");
    await expect(page.locator(".xx-titles-page")).toBeVisible({
      timeout: 20_000,
    });

    await expect(page.locator(".xx-title-card").first()).toBeVisible({
      timeout: 10_000,
    });

    const firstTitleText = await page
      .locator(".xx-title-card-text")
      .first()
      .textContent();
    if (firstTitleText) {
      await page.getByPlaceholder("搜索标题关键词...").fill(firstTitleText);
      await expect(page.getByText(firstTitleText)).toBeVisible();
    }

    await expect(page.locator(".xx-title-card-stat").first()).toBeVisible();
  });

  test("titles API creates and lists titles", async ({ request }) => {
    const suffix = Date.now().toString(36);
    const email = `e2e-title-api-${suffix}@example.com`;
    const username = `e2e_title_api_${suffix}`;

    const register = await request.post(`${apiBase}/auth/register`, {
      data: { email, username, password: PASSWORD, display_name: username },
    });
    expect(register.status()).toBe(201);

    const login = await loginWithRetry(request, email, PASSWORD);
    expect(login.status()).toBe(200);
    const loginData = (await login.json()) as { access_token: string };
    const headers = { Authorization: `Bearer ${loginData.access_token}` };

    const titleText = `E2E Test Title ${suffix}`;
    const createResp = await request.post(`${apiBase}/titles`, {
      headers,
      data: {
        name: titleText.slice(0, 50),
        text: titleText,
        category: "default",
      },
    });
    expect(createResp.status(), await createResp.text()).toBe(201);
    const created = (await createResp.json()) as {
      id: string;
      text: string;
    };
    expect(created.id).toBeTruthy();

    const listResp = await request.get(`${apiBase}/titles`, { headers });
    expect(listResp.status()).toBe(200);
    const listData = (await listResp.json()) as {
      items: Array<{ id: string; text: string }>;
    };
    const found = listData.items.find((t) => t.id === created.id);
    expect(found).toBeTruthy();
  });
});
