/**
 * Comprehensive E2E Test Suite for H2H Betting Platform
 *
 * Tests all critical user flows and captures console errors
 */

const { chromium } = require('playwright');

// Configuration
const BASE_URL = 'http://localhost:5173';
const API_URL = 'http://localhost:8000';

// Test users
const USERS = {
  alice: { email: 'alice@example.com', password: 'password123' },
  bob: { email: 'bob@example.com', password: 'password123' },
  charlie: { email: 'charlie@example.com', password: 'password123' }
};

// Collect all console errors
let consoleErrors = [];
let consoleWarnings = [];

async function setupBrowser() {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext({
    viewport: { width: 1280, height: 720 }
  });
  const page = await context.newPage();

  // Capture console errors and warnings
  page.on('console', msg => {
    const type = msg.type();
    const text = msg.text();

    if (type === 'error') {
      consoleErrors.push({ text, url: page.url() });
      console.log(`❌ Console Error: ${text}`);
    } else if (type === 'warning') {
      consoleWarnings.push({ text, url: page.url() });
      console.log(`⚠️  Console Warning: ${text}`);
    }
  });

  // Capture page errors
  page.on('pageerror', error => {
    consoleErrors.push({ text: error.message, url: page.url(), stack: error.stack });
    console.log(`❌ Page Error: ${error.message}`);
  });

  // Capture failed requests
  page.on('requestfailed', request => {
    console.log(`❌ Request Failed: ${request.url()} - ${request.failure().errorText}`);
  });

  return { browser, context, page };
}

async function login(page, user) {
  console.log(`\n🔐 Logging in as ${user.email}...`);

  await page.goto(BASE_URL);
  await page.waitForLoadState('networkidle');

  // Check if already logged in
  const isLoggedIn = await page.locator('text=/logout/i').count() > 0;
  if (isLoggedIn) {
    console.log('✅ Already logged in');
    return;
  }

  // Click login/sign in button
  const loginButton = page.locator('button', { hasText: /sign in|login/i }).first();
  if (await loginButton.count() > 0) {
    await loginButton.click();
    await page.waitForTimeout(500);
  }

  // Fill in credentials
  await page.fill('input[type="email"], input[name="email"]', user.email);
  await page.fill('input[type="password"], input[name="password"]', user.password);

  // Submit
  await page.click('button[type="submit"]');
  await page.waitForTimeout(2000);

  console.log('✅ Logged in successfully');
}

async function logout(page) {
  console.log('\n🚪 Logging out...');

  const logoutButton = page.locator('button, a', { hasText: /logout|sign out/i }).first();
  if (await logoutButton.count() > 0) {
    await logoutButton.click();
    await page.waitForTimeout(1000);
    console.log('✅ Logged out');
  }
}

async function testMarketplace(page) {
  console.log('\n📊 Testing Marketplace...');

  await page.goto(`${BASE_URL}/marketplace`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(2000);

  // Check for bet cards
  const betCards = await page.locator('[class*="bet"], [data-testid*="bet"]').count();
  console.log(`   Found ${betCards} bet cards`);

  // Check filters
  const categoryFilters = await page.locator('button, select', { hasText: /sports|entertainment|politics|custom/i }).count();
  console.log(`   Found ${categoryFilters} category filters`);

  console.log('✅ Marketplace loaded');
}

async function testWallet(page) {
  console.log('\n💰 Testing Wallet...');

  await page.goto(`${BASE_URL}/wallet`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(2000);

  // Check wallet balance display
  const balanceElements = await page.locator('text=/balance|\\$/i').count();
  console.log(`   Found ${balanceElements} balance elements`);

  // Check for deposit button
  const depositButton = await page.locator('button', { hasText: /deposit|add funds/i }).count();
  console.log(`   Deposit button present: ${depositButton > 0}`);

  console.log('✅ Wallet loaded');
}

async function testCreateBet(page) {
  console.log('\n➕ Testing Create Bet...');

  await page.goto(`${BASE_URL}/marketplace`);
  await page.waitForLoadState('networkidle');

  // Find and click create bet button
  const createButton = page.locator('button', { hasText: /create|new bet/i }).first();
  if (await createButton.count() === 0) {
    console.log('⚠️  Create bet button not found');
    return;
  }

  await createButton.click();
  await page.waitForTimeout(1000);

  // Check if modal opened
  const modalOpen = await page.locator('[role="dialog"], .modal').count() > 0;
  console.log(`   Modal opened: ${modalOpen}`);

  if (modalOpen) {
    // Fill in bet details
    console.log('   Filling bet form...');

    await page.fill('input[type="text"]').first().fill('Test Bet Title');
    await page.locator('textarea').first().fill('This is a test bet description');

    // Find stake amount input
    const stakeInput = page.locator('input[type="number"]').first();
    await stakeInput.fill('10');

    // Look for submit button
    const submitButton = page.locator('button[type="submit"], button', { hasText: /create|submit/i }).last();
    console.log(`   Submit button found: ${await submitButton.count() > 0}`);

    // Don't actually submit - just testing the form opens
    const cancelButton = page.locator('button', { hasText: /cancel/i }).first();
    if (await cancelButton.count() > 0) {
      await cancelButton.click();
      await page.waitForTimeout(500);
    }
  }

  console.log('✅ Create bet flow tested');
}

async function testMyBets(page) {
  console.log('\n📋 Testing My Bets...');

  await page.goto(`${BASE_URL}/my-bets`);
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(2000);

  // Check for tabs
  const tabs = await page.locator('[role="tab"], button[class*="tab"]').count();
  console.log(`   Found ${tabs} tabs`);

  console.log('✅ My Bets loaded');
}

async function testNavigation(page) {
  console.log('\n🧭 Testing Navigation...');

  const routes = [
    { path: '/marketplace', name: 'Marketplace' },
    { path: '/my-bets', name: 'My Bets' },
    { path: '/wallet', name: 'Wallet' }
  ];

  for (const route of routes) {
    console.log(`   Navigating to ${route.name}...`);
    await page.goto(`${BASE_URL}${route.path}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);
  }

  console.log('✅ Navigation tested');
}

async function runTests() {
  console.log('🧪 Starting Comprehensive E2E Tests\n');
  console.log('=' .repeat(60));

  const { browser, page } = await setupBrowser();

  try {
    // Test 1: Login Flow
    console.log('\n📝 TEST 1: Login Flow');
    await login(page, USERS.alice);

    // Test 2: Marketplace
    console.log('\n📝 TEST 2: Marketplace');
    await testMarketplace(page);

    // Test 3: Wallet
    console.log('\n📝 TEST 3: Wallet');
    await testWallet(page);

    // Test 4: Create Bet
    console.log('\n📝 TEST 4: Create Bet');
    await testCreateBet(page);

    // Test 5: My Bets
    console.log('\n📝 TEST 5: My Bets');
    await testMyBets(page);

    // Test 6: Navigation
    console.log('\n📝 TEST 6: Navigation');
    await testNavigation(page);

    // Test 7: Logout
    console.log('\n📝 TEST 7: Logout');
    await logout(page);

    // Summary
    console.log('\n' + '='.repeat(60));
    console.log('📊 TEST SUMMARY\n');

    console.log(`Console Errors: ${consoleErrors.length}`);
    if (consoleErrors.length > 0) {
      console.log('\n❌ CONSOLE ERRORS:');
      consoleErrors.forEach((err, i) => {
        console.log(`\n${i + 1}. ${err.text}`);
        console.log(`   Page: ${err.url}`);
        if (err.stack) {
          console.log(`   Stack: ${err.stack.split('\n')[0]}`);
        }
      });
    }

    console.log(`\nConsole Warnings: ${consoleWarnings.length}`);
    if (consoleWarnings.length > 0 && consoleWarnings.length < 20) {
      console.log('\n⚠️  CONSOLE WARNINGS:');
      consoleWarnings.forEach((warn, i) => {
        console.log(`${i + 1}. ${warn.text}`);
      });
    }

    console.log('\n' + '='.repeat(60));

    if (consoleErrors.length === 0) {
      console.log('✅ All tests passed with no console errors!');
    } else {
      console.log(`⚠️  Tests completed with ${consoleErrors.length} console errors`);
    }

  } catch (error) {
    console.error('\n❌ Test failed:', error);
  } finally {
    console.log('\n🔍 Keeping browser open for 10 seconds for inspection...');
    await page.waitForTimeout(10000);
    await browser.close();
  }
}

// Run tests
runTests().catch(console.error);
