/**
 * Authentication Fixtures for Playwright Tests
 * 
 * Manages authentication state for different user roles.
 * Creates reusable auth states to avoid logging in for every test.
 */

import { chromium, type FullConfig } from '@playwright/test';
import { setupTestUser, supabase } from './database';
import * as fs from 'fs';
import * as path from 'path';

const TEST_USERS = {
  user: {
    email: process.env.TEST_USER_EMAIL || 'test-user@thrillwiki.test',
    password: process.env.TEST_USER_PASSWORD || 'TestUser123!',
    role: 'user' as const,
  },
  moderator: {
    email: process.env.TEST_MODERATOR_EMAIL || 'test-moderator@thrillwiki.test',
    password: process.env.TEST_MODERATOR_PASSWORD || 'TestModerator123!',
    role: 'moderator' as const,
  },
  admin: {
    email: process.env.TEST_ADMIN_EMAIL || 'test-admin@thrillwiki.test',
    password: process.env.TEST_ADMIN_PASSWORD || 'TestAdmin123!',
    role: 'admin' as const,
  },
  superuser: {
    email: process.env.TEST_SUPERUSER_EMAIL || 'test-superuser@thrillwiki.test',
    password: process.env.TEST_SUPERUSER_PASSWORD || 'TestSuperuser123!',
    role: 'superuser' as const,
  },
};

/**
 * Setup authentication states for all test users
 */
export async function setupAuthStates(config: FullConfig): Promise<void> {
  const baseURL = config.projects[0].use.baseURL || 'http://localhost:8080';
  
  // Ensure .auth directory exists
  const authDir = path.join(process.cwd(), '.auth');
  if (!fs.existsSync(authDir)) {
    fs.mkdirSync(authDir, { recursive: true });
  }

  const browser = await chromium.launch();

  for (const [roleName, userData] of Object.entries(TEST_USERS)) {
    const context = await browser.newContext();
    const page = await context.newPage();

    try {
      // Create test user if doesn't exist
      await setupTestUser(userData.email, userData.password, userData.role);

      // Navigate to login page
      await page.goto(`${baseURL}/auth`);

      // Wait for page to load
      await page.waitForLoadState('networkidle');

      // Fill login form
      await page.fill('input[type="email"]', userData.email);
      await page.fill('input[type="password"]', userData.password);

      // Click login button
      await page.click('button[type="submit"]');

      // Wait for navigation to complete
      await page.waitForURL('**/', { timeout: 10000 });

      // Save authenticated state
      const authFile = path.join(authDir, `${roleName}.json`);
      await context.storageState({ path: authFile });

      console.log(`✓ Created auth state for ${roleName}`);
    } catch (error) {
      console.error(`✗ Failed to create auth state for ${roleName}:`, error);
      throw error;
    } finally {
      await context.close();
    }
  }

  await browser.close();
}

/**
 * Get auth credentials for a specific role
 */
export function getTestUserCredentials(role: keyof typeof TEST_USERS) {
  return TEST_USERS[role];
}

/**
 * Login programmatically (for use within tests)
 */
export async function loginAsUser(
  email: string,
  password: string
): Promise<{ userId: string; accessToken: string }> {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password,
  });

  if (error) throw error;
  if (!data.user || !data.session) throw new Error('Login failed');

  return {
    userId: data.user.id,
    accessToken: data.session.access_token,
  };
}

/**
 * Logout programmatically
 */
export async function logout(): Promise<void> {
  await supabase.auth.signOut();
}
