import { test, expect } from '@playwright/test';

/**
 * E2E Tests for Backward Compatibility - Single-Server Login (US-011)
 *
 * These tests verify that the classic username/password login flow works
 * when ORACLE_SERVERS is NOT configured (single-server mode).
 *
 * Prerequisites:
 *   1. Backend running WITHOUT ORACLE_SERVERS env variable
 *   2. Start test environment: ./start.sh test
 *   3. Frontend running on port 3000
 *
 * Run:
 *   npm run test:e2e -- single-server-login.spec.js
 *   npm run test:e2e:headed -- single-server-login.spec.js
 */

// Test configuration for single-server mode
const TEST_USER = {
  username: 'MARIUS M',
  password: '123',
  company: 'MARIUSM AUTO'
};

test.describe('Single-Server Login Backward Compatibility (US-011)', () => {

  test('should show username/password form in single-server mode', async ({ page }) => {
    // Navigate to login page
    await page.goto('/');

    // Wait for auth mode detection to complete
    // The login form should show username field (not email) in single-server mode
    await page.waitForSelector('input#identity', { timeout: 10000 });

    // Verify username field is visible (single-server mode)
    const usernameField = page.locator('input#identity');
    const emailField = page.locator('input#identity');

    // In single-server mode, username field should be visible
    // In multi-server mode, email field would be visible instead
    const isUsernameVisible = await usernameField.isVisible().catch(() => false);
    const isEmailVisible = await emailField.isVisible().catch(() => false);

    // At least one should be visible
    expect(isUsernameVisible || isEmailVisible).toBe(true);

    if (isUsernameVisible) {
      // Single-server mode - verify password field is also present
      const passwordField = page.locator('#password input');
      await expect(passwordField).toBeVisible();

      // Verify "Autentificare" button exists (not "Continuă")
      await expect(page.locator('button:has-text("Autentificare")')).toBeVisible();
    }
  });

  test('should successfully login with username/password', async ({ page }) => {
    await page.goto('/');

    // Wait for form to load
    await page.waitForSelector('input#identity', { timeout: 10000 });

    // Check which mode we're in
    const usernameField = page.locator('input#identity');
    const isUsernameVisible = await usernameField.isVisible().catch(() => false);

    if (isUsernameVisible) {
      // Single-server mode: fill username and password
      await page.fill('input#identity', TEST_USER.username);
      await page.fill('#password input', TEST_USER.password);

      // Click login button
      await page.click('button:has-text("Autentificare")');

      // Wait for redirect after successful login
      await page.waitForURL(/\/(reports|data-entry|dashboard)/, { timeout: 15000 });

      // Verify we're logged in (check for logout button or user menu)
      const logoutButton = page.locator('button:has-text("Deconectare"), [class*="logout"]');
      const userMenu = page.locator('[class*="user"], [class*="profile"]');

      // Should be redirected away from login page
      expect(page.url()).not.toContain('/login');
    } else {
      // Multi-server mode: use email flow (existing tests cover this)
      console.log('Multi-server mode detected - skipping single-server login test');
    }
  });

  test('should show error for invalid credentials', async ({ page }) => {
    await page.goto('/');

    // Wait for form to load
    await page.waitForSelector('input#identity', { timeout: 10000 });

    const usernameField = page.locator('input#identity');
    const isUsernameVisible = await usernameField.isVisible().catch(() => false);

    if (isUsernameVisible) {
      // Single-server mode: test invalid credentials
      await page.fill('input#identity', 'INVALID_USER');
      await page.fill('#password input', 'wrong_password');

      // Click login button
      await page.click('button:has-text("Autentificare")');

      // Wait for error message
      await page.waitForTimeout(2000); // Wait for API response

      // Check for error toast or message
      const errorToast = page.locator('.p-toast-message-error, .p-toast-error, [class*="error"]');
      const errorMessage = page.locator('[class*="error-message"], .p-message-error');

      // Should show some form of error
      const hasError = await errorToast.isVisible().catch(() => false) ||
                       await errorMessage.isVisible().catch(() => false);

      // Should still be on login page (not redirected)
      expect(page.url()).toMatch(/\/$|\/login/);
    }
  });

  test('should preserve JWT in localStorage after login', async ({ page }) => {
    await page.goto('/');

    await page.waitForSelector('input#identity', { timeout: 10000 });

    const usernameField = page.locator('input#identity');
    const isUsernameVisible = await usernameField.isVisible().catch(() => false);

    if (isUsernameVisible) {
      await page.fill('input#identity', TEST_USER.username);
      await page.fill('#password input', TEST_USER.password);
      await page.click('button:has-text("Autentificare")');

      await page.waitForURL(/\/(reports|data-entry|dashboard)/, { timeout: 15000 });

      // Check localStorage for JWT
      const accessToken = await page.evaluate(() => localStorage.getItem('access_token'));
      const user = await page.evaluate(() => localStorage.getItem('user'));

      // JWT should be stored
      expect(accessToken).toBeTruthy();
      expect(accessToken.split('.').length).toBe(3); // Valid JWT format

      // User should be stored
      expect(user).toBeTruthy();
      const userData = JSON.parse(user);
      expect(userData).toHaveProperty('username');
    }
  });

  test('should access reports after login', async ({ page }) => {
    await page.goto('/');

    await page.waitForSelector('input#identity', { timeout: 10000 });

    const usernameField = page.locator('input#identity');
    const isUsernameVisible = await usernameField.isVisible().catch(() => false);

    if (isUsernameVisible) {
      // Login first
      await page.fill('input#identity', TEST_USER.username);
      await page.fill('#password input', TEST_USER.password);
      await page.click('button:has-text("Autentificare")');

      await page.waitForURL(/\/(reports|data-entry|dashboard)/, { timeout: 15000 });

      // Navigate to reports if not already there
      await page.goto('/reports');

      // Wait for page to load
      await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => {});

      // Should not be redirected back to login
      await page.waitForTimeout(2000);
      expect(page.url()).not.toMatch(/\/$|\/login/);
    }
  });

});

test.describe('Auth Mode Detection', () => {

  test('should return valid auth-mode response', async ({ request }) => {
    // Test the auth-mode endpoint directly
    const response = await request.get('/api/system/auth-mode');

    expect(response.ok()).toBe(true);

    const data = await response.json();

    // Should have required fields
    expect(data).toHaveProperty('mode');
    expect(data).toHaveProperty('supports_email_login');

    // Mode should be either single-server or multi-server
    expect(['single-server', 'multi-server']).toContain(data.mode);

    // supports_email_login should match mode
    if (data.mode === 'single-server') {
      expect(data.supports_email_login).toBe(false);
    } else {
      expect(data.supports_email_login).toBe(true);
    }
  });

});
