/**
 * E2E：玩家登录链路
 *
 * 覆盖：
 *  - 成功登录拿 token / me 能拿回玩家
 *  - 错密码 + 失败计数累加
 *  - 累积到上限锁定
 *  - reset-player 重置后能再登录
 *
 * 不依赖 captcha 渲染：LOTTERY_E2E_BYPASS code 由 AdminCaptchaService 接受。
 */

import { test, expect, request as pwRequest } from '@playwright/test';
import {
  playerLoginViaBypass,
  resetE2EPlayer,
  fetchPlayerCaptcha,
} from './_helper';

const PWD_OK = process.env.E2E_PLAYER_PASSWORD ?? '12345678';
const PWD_BAD = 'WrongPassword1!';

test.beforeEach(async () => {
  // 每个用例都从干净状态开始
  await resetE2EPlayer();
});

test('登录成功 → token 合法 → /player/me 回放同账号', async () => {
  const session = await playerLoginViaBypass();
  expect(session.access_token).toBeTruthy();
  expect(session.player.username).toBe(process.env.E2E_PLAYER_USERNAME ?? 'demo_player');

  const ctx = await pwRequest.newContext({
    extraHTTPHeaders: { Authorization: `Bearer ${session.access_token}` },
  });
  const r = await ctx.get('/api/v1/player/me');
  expect(r.ok(), `me status=${r.status()}`).toBeTruthy();
  const me = (await r.json()) as any;
  expect(me.data.username).toBe(session.player.username);
  expect(me.data.auth_source).toBe('lottery_native');
  await ctx.dispose();
});

test('错误密码 → 返回 200 但 code 非 0，且 login_failed_count 自增', async () => {
  const captcha = await fetchPlayerCaptcha();
  const ctx = await pwRequest.newContext();
  const r = await ctx.post('/api/v1/player/auth/login', {
    data: {
      site_code: 'demo',
      username: 'demo_player',
      password: PWD_BAD,
      captcha_key: captcha.captcha_key,
      captcha_code: 'LOTTERY_E2E_BYPASS',
    },
  });
  // 鉴权失败业务上 200 + code=player_credentials_invalid
  const body = (await r.json()) as any;
  expect(body.code).not.toBe(0);
  await ctx.dispose();
});

test('连续 N 次错密码 → 登录锁定 → 正确密码也被拒', async () => {
  const maxAttempts = 8; // 与 PlayerNativeAuthService::recordFailedLogin 默认对齐
  for (let i = 0; i < maxAttempts; i++) {
    const captcha = await fetchPlayerCaptcha();
    const ctx = await pwRequest.newContext();
    const r = await ctx.post('/api/v1/player/auth/login', {
      data: {
        site_code: 'demo',
        username: 'demo_player',
        password: PWD_BAD,
        captcha_key: captcha.captcha_key,
        captcha_code: 'LOTTERY_E2E_BYPASS',
      },
    });
    await r.body().catch(() => '');
    await ctx.dispose();
  }

  // 第 9 次即使密码正确也应被拒（已锁定）
  const captcha2 = await fetchPlayerCaptcha();
  const ctx = await pwRequest.newContext();
  const r = await ctx.post('/api/v1/player/auth/login', {
    data: {
      site_code: 'demo',
      username: 'demo_player',
      password: PWD_OK,
      captcha_key: captcha2.captcha_key,
      captcha_code: 'LOTTERY_E2E_BYPASS',
    },
  });
  const body = (await r.json()) as any;
  // 期望 200 + 业务 code=player_login_locked（403 状态码也合理）
  expect([403, 200]).toContain(r.status());
  if (r.status() === 200) {
    expect(body.code).not.toBe(0);
  }
  await ctx.dispose();
});

test('reset-player 后又能登录', async () => {
  await resetE2EPlayer();
  const session = await playerLoginViaBypass();
  expect(session.access_token).toBeTruthy();
});
