/**
 * 订阅管理 E2E 测试
 *
 * 覆盖：路由守卫、订阅降级、过期处理、订阅状态检查
 */
import { expect, test, type APIRequestContext } from "@playwright/test";

const PASSWORD = "Test123456!";
const apiBase = process.env.E2E_API_BASE || "/api/v1";

function uniqueEmail(prefix: string): string {
  return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}@example.com`;
}

function uniqueUsername(prefix: string): string {
  return `${prefix}_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
}

/** 登录操作，遇到 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 },
  });
}

/** 注册并登录，返回 { headers, email, username, userId } */
async function createAuthedUser(request: APIRequestContext, label: string) {
  const email = uniqueEmail(label);
  const username = uniqueUsername(label);

  const reg = await request.post(`${apiBase}/auth/register`, {
    data: { email, password: PASSWORD, username, display_name: `E2E ${label}` },
  });
  expect(reg.ok(), `注册应成功: ${await reg.text()}`).toBeTruthy();

  const login = await loginWithRetry(request, email, PASSWORD);
  expect(login.ok(), `登录应成功: ${await login.text()}`).toBeTruthy();
  const loginData = await login.json();

  return {
    headers: { Authorization: `Bearer ${loginData.access_token}` },
    email,
    username,
  };
}

test.describe("Subscription route guard", () => {
  test.describe.configure({ timeout: 120_000 });
  test("redirects anonymous users to login", async ({ page }) => {
    await page.goto("/app/subscription");
    await expect(page).toHaveURL(/\/login/);
  });
});

test.describe("订阅信息查看", () => {
  test.describe.configure({ timeout: 120_000 });
  test("获取当前订阅信息 - 正向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-info");

    const response = await request.get(`${apiBase}/subscription/current`, {
      headers,
    });

    expect(
      response.ok(),
      `获取订阅信息应返回 2xx，实际: ${response.status()} ${await response.text()}`,
    ).toBeTruthy();

    const data = await response.json();
    expect(data.plan_id, "应返回 plan_id").toBeTruthy();
    expect(data.status, "应返回 status").toBeTruthy();
  });

  test("未登录获取订阅信息 - 反向", async ({ request }) => {
    const response = await request.get(`${apiBase}/subscription/current`);
    expect([401, 403]).toContain(response.status());
  });
});

test.describe("订阅降级", () => {
  test.describe.configure({ timeout: 120_000 });
  test("Pro 用户降级到 Standard - 正向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-downgrade");

    // 先升级到 Pro
    const upgrade = await request.post(`${apiBase}/subscription/change-plan`, {
      headers,
      data: {
        target_plan_id: "pro",
        billing_cycle: "monthly",
      },
    });
    expect(
      upgrade.ok(),
      `升级到 Pro 应成功: ${await upgrade.text()}`,
    ).toBeTruthy();

    // 降级到 Standard
    const downgrade = await request.post(
      `${apiBase}/subscription/change-plan`,
      {
        headers,
        data: {
          target_plan_id: "standard",
          billing_cycle: "monthly",
        },
      },
    );

    // 降级应成功或返回提示信息（某些业务可能限制降级）
    expect(downgrade.status(), "降级请求应返回 2xx 或 4xx").toBeLessThan(500);

    const data = await downgrade.json();
    // 成功或失败都应有明确响应
    expect(data).toBeTruthy();
  });

  test("降级到相同套餐 - 反向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-same");

    // 用户默认为 free，再次选择 free
    const response = await request.post(`${apiBase}/subscription/change-plan`, {
      headers,
      data: {
        target_plan_id: "free",
        billing_cycle: "monthly",
      },
    });

    // 相同套餐应返回 200 + success=false，或者 400
    if (response.ok()) {
      const data = await response.json();
      expect(data.success).toBe(false);
    } else {
      expect([400, 422]).toContain(response.status());
    }
  });

  test("降级到无效套餐 - 反向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-badplan");

    const response = await request.post(`${apiBase}/subscription/change-plan`, {
      headers,
      data: {
        target_plan_id: "nonexistent_plan",
        billing_cycle: "monthly",
      },
    });

    expect(response.status(), "无效套餐应返回 4xx").toBeGreaterThanOrEqual(400);
    expect(response.status()).toBeLessThan(500);
  });
});

test.describe("订阅过期处理", () => {
  test.describe.configure({ timeout: 120_000 });
  test("取消订阅 - 反向（免费用户）", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-cancel");

    // 免费用户取消订阅应返回错误
    const response = await request.post(`${apiBase}/subscription/cancel`, {
      headers,
    });

    // 免费用户可能不需要取消，返回 400 或类似错误
    if (!response.ok()) {
      const data = await response.json();
      expect(
        data.error?.message || data.detail || data.message,
        "应返回错误信息",
      ).toBeTruthy();
    }
  });

  test("未登录取消订阅 - 反向", async ({ request }) => {
    const response = await request.post(`${apiBase}/subscription/cancel`);
    expect([401, 403]).toContain(response.status());
  });

  test("切换自动续费 - 正向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-autorenew");

    // 关闭自动续费
    const disableResp = await request.post(
      `${apiBase}/subscription/toggle-auto-renew`,
      {
        headers,
        data: { enabled: false },
      },
    );
    expect(
      disableResp.ok(),
      `关闭自动续费应成功: ${await disableResp.text()}`,
    ).toBeTruthy();

    // 重新开启自动续费
    const enableResp = await request.post(
      `${apiBase}/subscription/toggle-auto-renew`,
      {
        headers,
        data: { enabled: true },
      },
    );
    expect(
      enableResp.ok(),
      `开启自动续费应成功: ${await enableResp.text()}`,
    ).toBeTruthy();
  });

  test("无效参数切换自动续费 - 反向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-autoren-bad");

    // 缺少 enabled 字段
    const response = await request.post(
      `${apiBase}/subscription/toggle-auto-renew`,
      {
        headers,
        data: {},
      },
    );

    expect([400, 422]).toContain(response.status());
  });
});

test.describe("账单记录", () => {
  test.describe.configure({ timeout: 120_000 });
  test("获取账单记录 - 正向", async ({ request }) => {
    const { headers } = await createAuthedUser(request, "sub-bills");

    const response = await request.get(
      `${apiBase}/subscription/billing-records`,
      { headers },
    );

    expect(
      response.ok(),
      `获取账单记录应返回 2xx，实际: ${response.status()}`,
    ).toBeTruthy();

    const data = await response.json();
    expect(Array.isArray(data), "账单记录应为数组").toBeTruthy();
  });

  test("未登录获取账单记录 - 反向", async ({ request }) => {
    const response = await request.get(
      `${apiBase}/subscription/billing-records`,
    );
    expect([401, 403]).toContain(response.status());
  });
});
