/**
 * E2E Test: Dashboard Access After Authentication
 *
 * Tests that authenticated users can access the dashboard
 * and unauthenticated users are redirected to login
 */

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

const APP_URL = 'http://localhost:9000';

test.describe('Dashboard Access Control', () => {

  test('unauthenticated users should be redirected to login', async ({ page }) => {
    // Clear all cookies to ensure no session
    await page.context().clearCookies();

    // Try to access dashboard without authentication
    // Use waitUntil: 'domcontentloaded' to handle redirects better
    await page.goto(`${APP_URL}/en/dashboard`, { waitUntil: 'domcontentloaded' });

    // Wait for redirect to complete
    await page.waitForURL(/\/login/, { timeout: 10000 });

    const currentURL = page.url();
    console.log(`Redirected to: ${currentURL}`);

    expect(currentURL).toContain('/login');
    console.log('✅ Unauthenticated user correctly redirected to login');
  });

  test('dashboard page should check for NextAuth session', async ({ page }) => {
    await page.goto(`${APP_URL}/en/dashboard`);

    // Page should either:
    // 1. Show dashboard (if session exists)
    // 2. Redirect to login (if no session)

    await page.waitForTimeout(2000);

    const currentURL = page.url();

    if (currentURL.includes('/dashboard')) {
      console.log('✅ Dashboard loaded (session exists)');
      // Verify dashboard content is visible
      await expect(page.locator('text=/dashboard|welcome/i')).toBeVisible({ timeout: 5000 });
    } else if (currentURL.includes('/login')) {
      console.log('✅ Redirected to login (no session)');
      expect(currentURL).toContain('/login');
    } else {
      console.log(`⚠️ Unexpected URL: ${currentURL}`);
    }
  });

  test('dashboard should show user information if authenticated', async ({ page, context }) => {
    // Set up a mock session cookie for testing
    // In real scenario, this would be from actual login

    // Navigate to dashboard
    await page.goto(`${APP_URL}/en/dashboard`);
    await page.waitForTimeout(2000);

    const currentURL = page.url();

    if (currentURL.includes('/dashboard')) {
      console.log('✅ Dashboard is accessible');

      // Check for user-specific content
      const pageContent = await page.content();

      // Dashboard should show some user info
      const hasUserContent = pageContent.includes('dashboard') ||
                            pageContent.includes('Welcome') ||
                            pageContent.includes('مرحباً');

      if (hasUserContent) {
        console.log('✅ Dashboard shows user content');
      } else {
        console.log('⚠️ Dashboard loaded but might not show user content');
      }
    } else {
      console.log('⚠️ Not authenticated - redirected to login');
      console.log('This is expected if no valid session exists');
    }
  });

  test('dashboard should be accessible after full OTP login', async ({ page }) => {
    const testEmail = 'gara2222ge@support.com';
    const otpCode = '273390'; // Known valid OTP

    // Step 1: Complete OTP login
    await page.goto(`${APP_URL}/en/login`);
    console.log('Step 1: On login page');

    await page.locator('input[type="text"]').first().fill(testEmail);
    console.log('Step 2: Email entered');

    await page.locator('button[type="submit"]').first().click();
    console.log('Step 3: Send OTP clicked');

    await page.waitForTimeout(3000);

    // Check if OTP input is visible
    const otpInputVisible = await page.locator('input[inputmode="numeric"]').isVisible().catch(() => false);

    if (otpInputVisible) {
      await page.locator('input[inputmode="numeric"]').first().fill(otpCode);
      console.log('Step 4: OTP entered');

      await page.locator('button:has-text("Verify")').first().click();
      console.log('Step 5: Verify clicked');

      await page.waitForTimeout(5000);

      // Step 2: Check final URL
      const finalURL = page.url();
      console.log(`Final URL: ${finalURL}`);

      // Step 3: Verify we're on dashboard
      if (finalURL.includes('/dashboard')) {
        console.log('✅ SUCCESS: Dashboard loaded after OTP login');
        expect(finalURL).toContain('/dashboard');

        // Verify dashboard content is present
        const dashboardContent = await page.content();
        const hasDashboard = dashboardContent.includes('dashboard') ||
                           dashboardContent.includes('Dashboard');

        if (hasDashboard) {
          console.log('✅ Dashboard content visible');
        } else {
          console.log('⚠️ On dashboard URL but content might not be loaded');
        }
      } else if (finalURL.includes('/login')) {
        console.log('❌ FAIL: Redirected back to login');
        console.log('Session was not created properly');

        // Debug: Check for error messages
        const errorVisible = await page.locator('text=/error|invalid|failed/i').isVisible().catch(() => false);
        if (errorVisible) {
          const errorText = await page.locator('text=/error|invalid|failed/i').first().textContent();
          console.log(`Error shown: ${errorText}`);
        }

        throw new Error('Session not created - dashboard redirected to login');
      } else {
        console.log(`⚠️ Unexpected redirect to: ${finalURL}`);
      }
    } else {
      console.log('⚠️ OTP input not visible - might already be at OTP step or error occurred');
    }
  });

  test('session should include user ID and email', async ({ page }) => {
    // Access session endpoint
    await page.goto(`${APP_URL}/en/login`);

    const sessionData = await page.evaluate(async () => {
      const response = await fetch('/api/auth/session');
      return await response.json();
    });

    console.log('Session data:', JSON.stringify(sessionData, null, 2));

    // Session structure validation
    if (sessionData && sessionData.user) {
      console.log('✅ Session has user data');
      expect(sessionData.user).toHaveProperty('id');
      expect(sessionData.user).toHaveProperty('email');
    } else {
      console.log('ℹ️ No active session (expected if not logged in)');
    }
  });

  test('verify server action createSessionFromOTP works', async ({ page }) => {
    // This tests the server action mechanism
    const testEmail = 'gara2222ge@support.com';

    await page.goto(`${APP_URL}/en/login`);

    // Try to call the server action
    // Note: Server actions are called via fetch to a special endpoint

    console.log('Testing server action for session creation');
    console.log('Server action should:');
    console.log('  1. Accept email and OTP verified flag');
    console.log('  2. Call NextAuth signIn() with __OTP_VERIFIED__');
    console.log('  3. Create NextAuth session');
    console.log('  4. Redirect to dashboard');

    // Placeholder test
    expect(true).toBe(true);
  });
});

test.describe('Dashboard Access Validation', () => {

  test('dashboard should require authentication', async ({ page }) => {
    // Clear all cookies to ensure no session
    await page.context().clearCookies();

    await page.goto(`${APP_URL}/en/dashboard`);
    await page.waitForTimeout(2000);

    const url = page.url();

    // Should redirect to login
    expect(url).toContain('/login');
    console.log('✅ Dashboard requires authentication - redirected to login');
  });

  test('dashboard should perform server-side auth check', async ({ page }) => {
    await page.goto(`${APP_URL}/en/dashboard`);

    // The page source should either:
    // 1. Show dashboard content (if authenticated)
    // 2. Trigger redirect (if not authenticated)

    await page.waitForTimeout(2000);

    const pageSource = await page.content();

    // Check if page shows redirect meta tag
    const hasRedirect = pageSource.includes('meta id="__next-page-redirect"');

    if (hasRedirect) {
      console.log('✅ Server-side redirect detected');
      const redirectMatch = pageSource.match(/url=([^"]+)/);
      if (redirectMatch) {
        console.log(`   Redirecting to: ${redirectMatch[1]}`);
      }
    } else {
      console.log('✅ No redirect - dashboard loading');
    }
  });

  test('test NextAuth session endpoint', async ({ page }) => {
    await page.goto(`${APP_URL}/en`);

    // Check session endpoint
    const sessionResponse = await page.evaluate(async () => {
      const res = await fetch('/api/auth/session');
      const data = await res.json();
      return {
        status: res.status,
        data: data,
      };
    });

    console.log('NextAuth session endpoint:', sessionResponse);

    expect(sessionResponse.status).toBe(200);

    if (sessionResponse.data && sessionResponse.data.user) {
      console.log('✅ Active session found');
      console.log(`   User: ${sessionResponse.data.user.email}`);
    } else {
      console.log('ℹ️ No active session');
    }
  });
});
