import { test, expect } from '@playwright/test';

/**
 * IPW Staging Login Tests
 * Tests the login functionality for the IPW staging website
 * 
 * Test Credentials:
 * - Username: jason@overdrive.co.za
 * - Password: test
 */

// Test data
const TEST_CREDENTIALS = {
  username: 'jason@overdrive.co.za',
  password: 'test'
};

// Selectors - these may need to be updated based on actual page structure
const SELECTORS = {
  loginLink: 'a:has-text("Login")',
  usernameField: 'input[name="email"], input[name="username"], input[type="email"]',
  passwordField: 'input[name="password"], input[type="password"]',
  loginButton: 'button[type="submit"], input[type="submit"], button:has-text("Login")',
  logoutButton: 'a:has-text("Logout"), button:has-text("Logout")',
  errorMessage: '.error, .alert, .message, [class*="error"], [class*="alert"]',
  successMessage: '.success, .message, [class*="success"]',
  userMenu: '.user-menu, .profile-menu, [class*="user"], [class*="profile"]'
};

test.describe('IPW Staging Login Tests', () => {
  
  test.beforeEach(async ({ page }) => {
    // Navigate to the homepage before each test
    await page.goto('/');
    
    // Wait for the page to load
    await page.waitForLoadState('networkidle');
  });

  test('should display login link on homepage', async ({ page }) => {
    // Check if login link is visible on the homepage
    const loginLink = page.locator(SELECTORS.loginLink);
    await expect(loginLink).toBeVisible();
    
    // Verify the login link is clickable
    await expect(loginLink).toBeEnabled();
  });

  test('should navigate to login page when login link is clicked', async ({ page }) => {
    // Click on the login link
    await page.click(SELECTORS.loginLink);
    
    // Wait for navigation
    await page.waitForLoadState('networkidle');
    
    // Verify we're on a login page (check for login form elements)
    const usernameField = page.locator(SELECTORS.usernameField);
    const passwordField = page.locator(SELECTORS.passwordField);
    const loginButton = page.locator(SELECTORS.loginButton);
    
    // At least one of these elements should be present
    await expect(usernameField.or(passwordField).or(loginButton)).toBeVisible();
  });

  test('should display login form with required fields', async ({ page }) => {
    // Navigate to login page
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    // Check for username/email field
    const usernameField = page.locator(SELECTORS.usernameField);
    await expect(usernameField).toBeVisible();
    
    // Check for password field
    const passwordField = page.locator(SELECTORS.passwordField);
    await expect(passwordField).toBeVisible();
    
    // Check for login button
    const loginButton = page.locator(SELECTORS.loginButton);
    await expect(loginButton).toBeVisible();
    
    // Verify password field is of type password
    await expect(passwordField).toHaveAttribute('type', 'password');
  });

  test('should successfully login with valid credentials', async ({ page }) => {
    // Navigate to login page
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    // Fill in login credentials
    await page.fill(SELECTORS.usernameField, TEST_CREDENTIALS.username);
    await page.fill(SELECTORS.passwordField, TEST_CREDENTIALS.password);
    
    // Submit the form
    await page.click(SELECTORS.loginButton);
    
    // Wait for navigation after login
    await page.waitForLoadState('networkidle');
    
    // Verify successful login by checking for logout button or user menu
    const logoutButton = page.locator(SELECTORS.logoutButton);
    const userMenu = page.locator(SELECTORS.userMenu);
    
    // At least one of these should be visible after successful login
    await expect(logoutButton.or(userMenu)).toBeVisible({ timeout: 10000 });
    
    // Verify we're no longer on the login page
    const loginButton = page.locator(SELECTORS.loginButton);
    await expect(loginButton).not.toBeVisible();
  });

  test('should show error message with invalid credentials', async ({ page }) => {
    // Navigate to login page
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    // Fill in invalid credentials
    await page.fill(SELECTORS.usernameField, 'invalid@email.com');
    await page.fill(SELECTORS.passwordField, 'wrongpassword');
    
    // Submit the form
    await page.click(SELECTORS.loginButton);
    
    // Wait for error message to appear
    await page.waitForLoadState('networkidle');
    
    // Check for error message
    const errorMessage = page.locator(SELECTORS.errorMessage);
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
    
    // Verify we're still on the login page
    const loginButton = page.locator(SELECTORS.loginButton);
    await expect(loginButton).toBeVisible();
  });

  test('should handle empty form submission', async ({ page }) => {
    // Navigate to login page
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    // Try to submit empty form
    await page.click(SELECTORS.loginButton);
    
    // Wait for any validation messages
    await page.waitForLoadState('networkidle');
    
    // Check for validation errors or error messages
    const errorMessage = page.locator(SELECTORS.errorMessage);
    const hasErrors = await errorMessage.count() > 0;
    
    // Either there should be an error message or we should still be on login page
    if (hasErrors) {
      await expect(errorMessage.first()).toBeVisible();
    } else {
      // Verify we're still on the login page
      const loginButton = page.locator(SELECTORS.loginButton);
      await expect(loginButton).toBeVisible();
    }
  });

  test('should maintain login state after page refresh', async ({ page }) => {
    // First, login successfully
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    await page.fill(SELECTORS.usernameField, TEST_CREDENTIALS.username);
    await page.fill(SELECTORS.passwordField, TEST_CREDENTIALS.password);
    await page.click(SELECTORS.loginButton);
    
    // Wait for login to complete
    await page.waitForLoadState('networkidle');
    
    // Verify we're logged in
    const logoutButton = page.locator(SELECTORS.logoutButton);
    const userMenu = page.locator(SELECTORS.userMenu);
    await expect(logoutButton.or(userMenu)).toBeVisible({ timeout: 10000 });
    
    // Refresh the page
    await page.reload();
    await page.waitForLoadState('networkidle');
    
    // Verify we're still logged in after refresh
    await expect(logoutButton.or(userMenu)).toBeVisible({ timeout: 10000 });
  });

  test('should logout successfully', async ({ page }) => {
    // First, login successfully
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    await page.fill(SELECTORS.usernameField, TEST_CREDENTIALS.username);
    await page.fill(SELECTORS.passwordField, TEST_CREDENTIALS.password);
    await page.click(SELECTORS.loginButton);
    
    // Wait for login to complete
    await page.waitForLoadState('networkidle');
    
    // Verify we're logged in
    const logoutButton = page.locator(SELECTORS.logoutButton);
    const userMenu = page.locator(SELECTORS.userMenu);
    await expect(logoutButton.or(userMenu)).toBeVisible({ timeout: 10000 });
    
    // Click logout
    await logoutButton.click();
    await page.waitForLoadState('networkidle');
    
    // Verify we're logged out by checking for login link
    const loginLink = page.locator(SELECTORS.loginLink);
    await expect(loginLink).toBeVisible();
    
    // Verify logout button is no longer visible
    await expect(logoutButton).not.toBeVisible();
  });

  test('should handle network errors gracefully', async ({ page }) => {
    // Navigate to login page
    await page.click(SELECTORS.loginLink);
    await page.waitForLoadState('networkidle');
    
    // Fill in credentials
    await page.fill(SELECTORS.usernameField, TEST_CREDENTIALS.username);
    await page.fill(SELECTORS.passwordField, TEST_CREDENTIALS.password);
    
    // Simulate network error by going offline
    await page.context().setOffline(true);
    
    // Try to submit form
    await page.click(SELECTORS.loginButton);
    
    // Wait a moment for any error handling
    await page.waitForTimeout(2000);
    
    // Go back online
    await page.context().setOffline(false);
    
    // Verify we're still on the login page
    const loginButton = page.locator(SELECTORS.loginButton);
    await expect(loginButton).toBeVisible();
  });
}); 