// apps/web/e2e/fixtures/auth.fixture.ts
import { test as base, type Page } from '@playwright/test';
import { ApiClient } from './api-client';

const API_BASE = process.env.E2E_API_URL || 'http://localhost:3000/api/v1';

type E2eFixtures = {
  api: ApiClient;
  authenticatedPage: Page;
};

interface LoginResult {
  access_token: string;
  refresh_token: string;
  user: object;
}

async function login(): Promise<LoginResult> {
  for (let attempt = 0; attempt < 5; attempt++) {
    try {
      const res = await fetch(`${API_BASE}/auth/login`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          username: process.env.E2E_ADMIN_USER || 'admin',
          password: process.env.E2E_ADMIN_PASS || 'Admin@2026',
        }),
      });
      if (!res.ok) {
        const text = await res.text().catch(() => '');
        throw new Error(`HTTP ${res.status}: ${text.slice(0, 100)}`);
      }
      const json = await res.json();
      if (json.success) return json.data;
      throw new Error(`Login unsuccessful: ${json.error ?? 'unknown'}`);
    } catch (err) {
      if (attempt === 4) throw err;
      await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
    }
  }
  throw new Error('Login failed after 5 attempts');
}

export const test = base.extend<E2eFixtures>({
  api: async ({}, use) => {
    const { access_token } = await login();
    const client = new ApiClient();
    client['token'] = access_token;
    await use(client);
  },

  authenticatedPage: async ({ page }, use) => {
    const { access_token, refresh_token, user } = await login();
    await page.addInitScript((args) => {
      localStorage.setItem('access_token', args.token);
      localStorage.setItem('refresh_token', args.refresh);
      localStorage.setItem('user', JSON.stringify(args.userData));
    }, { token: access_token, refresh: refresh_token, userData: user });
    await use(page);
  },

  page: async ({ page }, use) => {
    const { access_token, refresh_token, user } = await login();
    await page.addInitScript((args) => {
      localStorage.setItem('access_token', args.token);
      localStorage.setItem('refresh_token', args.refresh);
      localStorage.setItem('user', JSON.stringify(args.userData));
    }, { token: access_token, refresh: refresh_token, userData: user });
    await use(page);
  },
});

export { expect } from '@playwright/test';
