import { APIRequestContext } from '@playwright/test';
import { TestUser } from '../types';

/**
 * Authentication utilities for API and browser-based logins
 */
export class AuthUtils {
  /**
   * Pre-seeded Fellowship members for testing
   */
  static readonly FELLOWSHIP_MEMBERS: Record<string, TestUser> = {
    frodo: { username: 'frodo_baggins', password: 'fellowship123', character: 'Frodo Baggins' },
    sam: { username: 'samwise_gamgee', password: 'fellowship123', character: 'Samwise Gamgee' },
    aragorn: { username: 'aragorn', password: 'fellowship123', character: 'Aragorn' },
    legolas: { username: 'legolas', password: 'fellowship123', character: 'Legolas' },
    gimli: { username: 'gimli', password: 'fellowship123', character: 'Gimli' },
    gandalf: { username: 'gandalf', password: 'fellowship123', character: 'Gandalf' },
  };

  /**
   * Get a random Fellowship member for testing
   */
  static getRandomMember(): TestUser {
    const members = Object.values(this.FELLOWSHIP_MEMBERS);
    return members[Math.floor(Math.random() * members.length)];
  }

  /**
   * Get a Fellowship member by username or key
   */
  static getFellowshipMember(usernameOrKey: string): TestUser {
    // Try to find by key first (e.g., "frodo", "sam")
    if (this.FELLOWSHIP_MEMBERS[usernameOrKey]) {
      return this.FELLOWSHIP_MEMBERS[usernameOrKey];
    }

    // Try to find by username (e.g., "frodo_baggins")
    const member = Object.values(this.FELLOWSHIP_MEMBERS).find(
      m => m.username === usernameOrKey
    );

    if (member) {
      return member;
    }

    // If not found, throw an error
    throw new Error(`Fellowship member not found: ${usernameOrKey}`);
  }

  /**
   * Login via API and set cookies in page
   */
  static async loginViaApi(
    apiRequest: APIRequestContext,
    baseUrl: string,
    user: TestUser,
  ): Promise<void> {
    const response = await apiRequest.post(`${baseUrl}/api/auth/login`, {
      data: {
        username: user.username,
        password: user.password,
      },
    });

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

  /**
   * Logout via API
   */
  static async logoutViaApi(apiRequest: APIRequestContext, baseUrl: string): Promise<void> {
    const response = await apiRequest.post(`${baseUrl}/api/auth/logout`);
    if (!response.ok()) {
      console.warn(`Logout returned ${response.status()}, but continuing...`);
    }
  }

  /**
   * Verify session is authenticated
   */
  static async verifySessionAuthenticated(
    apiRequest: APIRequestContext,
    baseUrl: string,
  ): Promise<boolean> {
    try {
      const response = await apiRequest.get(`${baseUrl}/api/auth/me`);
      return response.ok();
    } catch {
      return false;
    }
  }
}
