/**
 * Login E2E Tests
 * 
 * Tests authentication flow, session persistence, and error handling.
 */

import { test, expect } from '@playwright/test';
import { LoginPage } from '../../helpers/page-objects/LoginPage';
import { getTestUserCredentials, logout } from '../../fixtures/auth';

// These tests run without pre-authenticated state
test.use({ storageState: { cookies: [], origins: [] } });

test.describe('Login Flow', () => {
  let loginPage: LoginPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    await loginPage.goto();
  });

  test('should login successfully with valid credentials', async ({ page }) => {
    const { email, password } = getTestUserCredentials('user');
    
    await loginPage.login(email, password);
    await loginPage.expectLoginSuccess();
    
    // Verify we're redirected to homepage
    await expect(page).toHaveURL('/');
  });

  test('should show error with invalid password', async ({ page }) => {
    const { email } = getTestUserCredentials('user');
    
    await loginPage.login(email, 'wrongpassword123');
    await loginPage.expectLoginError();
    
    // Verify we're still on auth page
    await expect(page).toHaveURL(/\/auth/);
  });

  test('should show error with non-existent email', async ({ page }) => {
    await loginPage.login('nonexistent@example.com', 'password123');
    await loginPage.expectLoginError();
  });

  test('should persist session after page refresh', async ({ page }) => {
    const { email, password } = getTestUserCredentials('user');
    
    // Login
    await loginPage.login(email, password);
    await loginPage.expectLoginSuccess();
    
    // Reload page
    await page.reload();
    
    // Should still be logged in (not redirected to /auth)
    await expect(page).not.toHaveURL(/\/auth/);
  });

  test('should clear session on logout', async ({ page }) => {
    const { email, password } = getTestUserCredentials('user');
    
    // Login
    await loginPage.login(email, password);
    await loginPage.expectLoginSuccess();
    
    // Logout
    await page.click('button:has-text("Logout")').or(page.click('[data-testid="logout"]'));
    
    // Should be redirected to auth or homepage
    // And trying to access protected route should redirect to auth
    await page.goto('/moderation/queue');
    await expect(page).toHaveURL(/\/auth/);
  });

  test('should validate email format', async ({ page }) => {
    await loginPage.login('invalid-email', 'password123');
    
    // Should show validation error
    await expect(page.getByText(/invalid.*email/i)).toBeVisible();
  });

  test('should require password', async ({ page }) => {
    const { email } = getTestUserCredentials('user');
    
    await page.fill('input[type="email"]', email);
    await page.click('button[type="submit"]');
    
    // Should show validation error
    await expect(page.getByText(/password.*required/i)).toBeVisible();
  });
});

test.describe('Role-Based Access', () => {
  test('moderator can access moderation queue', async ({ browser }) => {
    const context = await browser.newContext({ storageState: '.auth/moderator.json' });
    const page = await context.newPage();
    
    await page.goto('/moderation/queue');
    
    // Should not be redirected
    await expect(page).toHaveURL(/\/moderation\/queue/);
    
    // Page should load successfully
    await expect(page.getByText(/moderation.*queue/i)).toBeVisible();
    
    await context.close();
  });

  test('regular user cannot access moderation queue', async ({ browser }) => {
    const context = await browser.newContext({ storageState: '.auth/user.json' });
    const page = await context.newPage();
    
    await page.goto('/moderation/queue');
    
    // Should be redirected or see access denied
    await expect(page.getByText(/access denied/i).or(page.getByText(/not authorized/i))).toBeVisible();
    
    await context.close();
  });

  test('admin can access admin panel', async ({ browser }) => {
    const context = await browser.newContext({ storageState: '.auth/admin.json' });
    const page = await context.newPage();
    
    await page.goto('/admin/users');
    
    // Should not be redirected
    await expect(page).toHaveURL(/\/admin/);
    
    await context.close();
  });
});
