/**
 * E2E：主站 SSO JWT + 钱包 mock 异常（504 / 业务拒绝）。
 */

import { test, expect, request as pwRequest } from '@playwright/test';
import {
  configureWalletMock,
  fetchOpenDrawNo,
  mintSsoJwt,
  playerLoginViaBypass,
  resetE2EPlayer,
  resetWalletMock,
  setMockWalletMode,
} from './_helper';

const CURRENCY = (process.env.LOTTERY_DEFAULT_CURRENCY ?? 'NPR').toUpperCase();
const MOCK_BASE = `http://127.0.0.1:${process.env.E2E_MOCK_WALLET_PORT ?? '5555'}`;

test.beforeEach(async () => {
  await resetWalletMock();
  await setMockWalletMode('success');
});

test('SSO JWT 首次 /player/me 自动建档', async () => {
  const { jwt, site_player_id } = await mintSsoJwt();

  const ctx = await pwRequest.newContext({
    extraHTTPHeaders: { Authorization: `Bearer ${jwt}` },
  });
  const me = await ctx.get('/api/v1/player/me');
  expect(me.ok()).toBeTruthy();
  const body = (await me.json()) as any;
  expect(body.code).toBe(0);
  expect(body.data.site_player_id).toBe(site_player_id);
  expect(String(body.data.username)).toMatch(/^nlotto\d{6}$/);
  await ctx.dispose();
});

test('主站 mock 504 → transfer-out 1002 pending_reconcile', async () => {
  await resetE2EPlayer();
  await configureWalletMock(MOCK_BASE);
  await setMockWalletMode('504');

  const session = await playerLoginViaBypass();
  const ctx = await pwRequest.newContext({
    extraHTTPHeaders: { Authorization: `Bearer ${session.access_token}` },
  });

  const r = await ctx.post('/api/v1/wallet/transfer-out', {
    data: {
      amount: 10_000,
      currency: CURRENCY,
      idempotent_key: `e2e-mock-504-${Date.now()}`,
    },
  });
  const body = (await r.json()) as any;
  expect(Number(body.code)).toBe(1002);
  await ctx.dispose();
});

test('主站 mock reject → transfer-out 1009', async () => {
  await resetE2EPlayer();
  await configureWalletMock(MOCK_BASE);
  await setMockWalletMode('reject');

  const session = await playerLoginViaBypass();
  const ctx = await pwRequest.newContext({
    extraHTTPHeaders: { Authorization: `Bearer ${session.access_token}` },
  });

  const r = await ctx.post('/api/v1/wallet/transfer-out', {
    data: {
      amount: 10_000,
      currency: CURRENCY,
      idempotent_key: `e2e-mock-reject-${Date.now()}`,
    },
  });
  const body = (await r.json()) as any;
  expect(Number(body.code)).toBe(1009);
  await ctx.dispose();
});

test('SSO JWT + 主站 mock 成功 → transfer-in + 下注', async () => {
  test.setTimeout(120_000);

  const { jwt } = await mintSsoJwt(`e2e-sso-wallet-${Date.now()}`);
  await configureWalletMock(MOCK_BASE);
  await setMockWalletMode('success');

  const ctx = await pwRequest.newContext({
    extraHTTPHeaders: { Authorization: `Bearer ${jwt}` },
  });

  const me = await ctx.get('/api/v1/player/me');
  expect(me.ok()).toBeTruthy();
  const meBody = (await me.json()) as any;
  expect(meBody.code).toBe(0);
  expect(meBody.data.funding_mode).toBe('wallet');
  expect(meBody.data.auth_source).toBe('main_site_sso');

  const bal0 = await ctx.get('/api/v1/wallet/balance');
  const before = Number((await bal0.json()).data.balance);

  const tin = await ctx.post('/api/v1/wallet/transfer-in', {
    data: {
      amount: 30_000,
      currency: CURRENCY,
      idempotent_key: `e2e-sso-tin-${Date.now()}`,
    },
  });
  expect(tin.ok()).toBeTruthy();
  const tinBody = (await tin.json()) as any;
  expect(tinBody.code).toBe(0);
  expect(Number(tinBody.data.lottery_balance_after)).toBeGreaterThan(before);

  const drawNo = await fetchOpenDrawNo();

  const place = await ctx.post('/api/v1/ticket/place', {
    data: {
      draw_id: drawNo,
      currency_code: CURRENCY,
      client_trace_id: `e2e-sso-bet-${Date.now()}`,
      lines: [{ number: '1234', play_code: 'straight', amount: 5_000 }],
    },
  });
  expect(place.ok()).toBeTruthy();
  const placeBody = (await place.json()) as any;
  expect(placeBody.code).toBe(0);
  await ctx.dispose();
});
