import { request } from '@playwright/test';
import { writeFileSync } from 'fs';
import { join } from 'path';

const API_URL = process.env.E2E_API_URL || 'http://localhost:3000';

const TEST_USERS = {
  trainer: { phone: '+70000000010', password: 'trainer123' },
  coordinator: { phone: '+70000000003', password: 'admin123' },
  manager: { phone: '+70000000003', password: 'admin123' },
  receptionist: { phone: '+70000000004', password: 'admin123' },
  clubAdmin: { phone: '+70000000002', password: 'admin123' },
  superAdmin: { phone: '+70000000001', password: 'admin123' },
};

async function loginWithRetry(
  ctx: Awaited<ReturnType<typeof request.newContext>>,
  phone: string,
  password: string,
): Promise<{ accessToken: string; refreshToken: string }> {
  for (let attempt = 0; attempt < 8; attempt++) {
    const response = await ctx.post(`${API_URL}/v1/auth/login`, {
      data: { phone, password },
    });

    if (response.status() === 429) {
      const delay = (attempt + 1) * 12_000;
      await new Promise((r) => setTimeout(r, delay));
      continue;
    }

    if (!response.ok()) {
      throw new Error(`Login failed for ${phone}: ${response.status()}`);
    }

    const body = await response.json();
    return { accessToken: body.accessToken, refreshToken: body.refreshToken };
  }

  throw new Error(`Login rate limited after 8 retries for ${phone}`);
}

export default async function globalSetup() {
  const ctx = await request.newContext();

  // Login all unique users (coordinator and manager share same credentials)
  const uniqueLogins = [
    { key: 'superAdmin', ...TEST_USERS.superAdmin },
    { key: 'clubAdmin', ...TEST_USERS.clubAdmin },
    { key: 'coordinator', ...TEST_USERS.coordinator },
    { key: 'receptionist', ...TEST_USERS.receptionist },
    { key: 'trainer', ...TEST_USERS.trainer },
  ];

  const tokens: Record<string, { accessToken: string; refreshToken: string }> = {};

  for (const user of uniqueLogins) {
    tokens[user.key] = await loginWithRetry(ctx, user.phone, user.password);
  }

  // manager shares tokens with coordinator
  tokens.manager = tokens.coordinator;

  // Save to file for test consumption
  const tokenPath = join(__dirname, '.auth-tokens.json');
  writeFileSync(tokenPath, JSON.stringify(tokens, null, 2));

  await ctx.dispose();
}
