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

/**
 * Focused Investigation Tests for Bet Creation and Taking Issues
 *
 * This test suite investigates why bet creation and taking are not working
 * on the events page.
 */

const TEST_USERS = {
  alice: { email: 'alice@example.com', password: 'password123' },
  bob: { email: 'bob@example.com', password: 'password123' },
};

interface TestErrors {
  jsErrors: string[];
  networkErrors: { url: string; status: number; method: string; body?: any }[];
  consoleErrors: string[];
}

function setupErrorTracking(page: Page): TestErrors {
  const errors: TestErrors = {
    jsErrors: [],
    networkErrors: [],
    consoleErrors: [],
  };

  page.on('pageerror', (error) => {
    errors.jsErrors.push(`${error.name}: ${error.message}`);
  });

  page.on('response', async (response) => {
    if (response.status() >= 400) {
      let body = null;
      try {
        body = await response.json();
      } catch {}
      errors.networkErrors.push({
        url: response.url(),
        status: response.status(),
        method: response.request().method(),
        body,
      });
    }
  });

  page.on('console', (msg) => {
    if (msg.type() === 'error') {
      errors.consoleErrors.push(msg.text());
    }
  });

  return errors;
}

async function login(page: Page, user: { email: string; password: string }) {
  await page.goto('/login');
  await page.waitForLoadState('networkidle');
  await page.fill('input[type="email"]', user.email);
  await page.fill('input[type="password"]', user.password);
  await page.click('button[type="submit"]');
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(1500);
}

test.describe('Bet Flow Investigation', () => {
  test('INVESTIGATION-001: Check event click and TradingPanel on home page', async ({ page }) => {
    const errors = setupErrorTracking(page);

    console.log('\n=== INVESTIGATION-001: Home Page Event Click ===');

    await login(page, TEST_USERS.alice);
    console.log('Logged in as Alice');

    await page.screenshot({ path: 'tests/screenshots/inv001-after-login.png', fullPage: true });

    // The home page shows events in a table/list format
    // Look for event rows that contain "vs"
    const eventRows = page.locator('tr, [class*="divide-y"] > div, button').filter({ hasText: /vs/i });
    const eventCount = await eventRows.count();
    console.log(`Found ${eventCount} event elements`);

    if (eventCount > 0) {
      // Click first event
      const firstEvent = eventRows.first();
      const eventText = await firstEvent.textContent();
      console.log(`Clicking event: ${eventText?.substring(0, 100)}...`);

      await firstEvent.click();
      await page.waitForTimeout(2000);

      await page.screenshot({ path: 'tests/screenshots/inv001-after-event-click.png', fullPage: true });

      // Check what's visible now
      const pageContent = await page.content();

      // Check for TradingPanel elements
      const tradingPanelElements = {
        'Order Book': await page.locator('text=Order Book').isVisible(),
        'Place Bet': await page.locator('text=Place Bet').isVisible(),
        'Create Bet button': await page.locator('button').filter({ hasText: /create.*bet/i }).isVisible(),
        'Stake input': await page.locator('input[type="number"]').first().isVisible(),
        'Team selection': await page.locator('button').filter({ hasText: /home|away/i }).first().isVisible(),
      };

      console.log('\nTradingPanel Elements:');
      for (const [name, visible] of Object.entries(tradingPanelElements)) {
        console.log(`  ${visible ? '[FOUND]' : '[MISSING]'} ${name}`);
      }

      // Check for SpreadGrid elements
      const spreadGridElements = {
        'Spread cells': await page.locator('button').filter({ hasText: /^[+-]?\d+\.?\d*$/ }).count(),
        'Back button': await page.locator('text=Back').isVisible(),
      };

      console.log('\nSpreadGrid Elements:');
      console.log(`  Spread cells found: ${spreadGridElements['Spread cells']}`);
      console.log(`  Back button visible: ${spreadGridElements['Back button']}`);
    }

    console.log('\n--- Errors ---');
    console.log('JS Errors:', errors.jsErrors);
    console.log('Network Errors:', errors.networkErrors);
    console.log('Console Errors:', errors.consoleErrors);
  });

  test('INVESTIGATION-002: Test bet creation flow step by step', async ({ page }) => {
    const errors = setupErrorTracking(page);

    console.log('\n=== INVESTIGATION-002: Bet Creation Step by Step ===');

    await login(page, TEST_USERS.alice);

    // Navigate directly to sport events page
    await page.goto('/sport-events');
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    console.log('On Sport Events page');
    await page.screenshot({ path: 'tests/screenshots/inv002-sport-events.png', fullPage: true });

    // Find and click on an event
    const eventButtons = page.locator('button').filter({ hasText: /vs/i });
    const count = await eventButtons.count();
    console.log(`Found ${count} event buttons`);

    if (count > 0) {
      await eventButtons.first().click();
      await page.waitForTimeout(1500);

      console.log('Clicked on first event');
      await page.screenshot({ path: 'tests/screenshots/inv002-event-selected.png', fullPage: true });

      // Look for spread cells and click one
      const spreadCells = page.locator('button').filter({ hasText: /^[+-]?\d+\.?\d*$/ });
      const spreadCount = await spreadCells.count();
      console.log(`Found ${spreadCount} spread cells`);

      if (spreadCount > 0) {
        // Click on a spread cell near the middle
        const middleIndex = Math.floor(spreadCount / 2);
        const spreadCell = spreadCells.nth(middleIndex);
        const spreadValue = await spreadCell.textContent();
        console.log(`Clicking spread cell: ${spreadValue}`);

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

        await page.screenshot({ path: 'tests/screenshots/inv002-spread-modal.png', fullPage: true });

        // Check if modal opened
        const modalOverlay = page.locator('.fixed.inset-0.bg-black, [role="dialog"]');
        const modalVisible = await modalOverlay.isVisible();
        console.log(`Modal overlay visible: ${modalVisible}`);

        if (modalVisible) {
          // Look for Create New Bet button
          const createButton = page.locator('button').filter({ hasText: /create new bet/i });
          const createVisible = await createButton.isVisible();
          console.log(`"Create New Bet" button visible: ${createVisible}`);

          if (createVisible) {
            await createButton.click();
            await page.waitForTimeout(1000);

            await page.screenshot({ path: 'tests/screenshots/inv002-create-modal.png', fullPage: true });

            // Fill stake amount
            const stakeInput = page.locator('input[type="number"]');
            if (await stakeInput.isVisible()) {
              await stakeInput.fill('50');
              console.log('Entered stake amount: 50');

              // Monitor API call
              const apiPromise = page.waitForResponse(
                resp => resp.url().includes('/api/v1/spread-bets') && resp.request().method() === 'POST',
                { timeout: 15000 }
              ).catch(e => {
                console.log('API wait error:', e.message);
                return null;
              });

              // Click submit
              const submitButton = page.locator('button[type="submit"]');
              if (await submitButton.isVisible()) {
                console.log('Clicking submit button...');
                await submitButton.click();

                await page.waitForTimeout(3000);
                await page.screenshot({ path: 'tests/screenshots/inv002-after-submit.png', fullPage: true });

                const response = await apiPromise;
                if (response) {
                  console.log(`API Response: ${response.status()} ${response.statusText()}`);
                  const body = await response.json().catch(() => null);
                  if (body) {
                    console.log('Response body:', JSON.stringify(body, null, 2));
                  }
                } else {
                  console.log('WARNING: No API call was made!');
                }

                // Check for success/error toast
                await page.waitForTimeout(500);
                const toastText = await page.locator('[class*="toast"], [role="alert"]').textContent().catch(() => '');
                console.log(`Toast message: ${toastText}`);
              }
            }
          }
        }
      }
    }

    console.log('\n--- Final Error Summary ---');
    console.log('JS Errors:', errors.jsErrors);
    console.log('Network Errors:', errors.networkErrors.map(e => `${e.method} ${e.url}: ${e.status}`));
    console.log('Console Errors:', errors.consoleErrors);
  });

  test('INVESTIGATION-003: Test TradingPanel bet creation', async ({ page }) => {
    const errors = setupErrorTracking(page);

    console.log('\n=== INVESTIGATION-003: TradingPanel Bet Creation ===');

    await login(page, TEST_USERS.alice);
    await page.goto('/');
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    // Click on an event row/cell
    const eventElements = page.locator('tr:has-text("vs"), div:has-text("vs")').filter({ hasText: /football|basketball|hockey|soccer/i });
    const eventCount = await eventElements.count();
    console.log(`Found ${eventCount} event rows/divs`);

    // Try clicking on the event name text directly
    const eventLinks = page.locator('text=/\\w+ vs \\w+/i');
    const linkCount = await eventLinks.count();
    console.log(`Found ${linkCount} event name links`);

    if (linkCount > 0) {
      await eventLinks.first().click();
      await page.waitForTimeout(2000);

      await page.screenshot({ path: 'tests/screenshots/inv003-after-click.png', fullPage: true });

      // Check current URL
      const url = page.url();
      console.log(`Current URL: ${url}`);

      // Check for TradingPanel
      const placeBetVisible = await page.locator('text=Place Bet').isVisible();
      console.log(`"Place Bet" section visible: ${placeBetVisible}`);

      if (placeBetVisible) {
        // Enter stake
        const stakeInput = page.locator('input[type="number"]').first();
        if (await stakeInput.isVisible()) {
          await stakeInput.fill('100');
          console.log('Entered stake: 100');

          // Find create button
          const createBtn = page.locator('button').filter({ hasText: /create.*bet/i });
          const btnText = await createBtn.textContent();
          console.log(`Create button text: ${btnText}`);

          if (await createBtn.isEnabled()) {
            console.log('Create button is enabled, clicking...');

            // Listen for network request
            let apiCalled = false;
            page.on('request', req => {
              if (req.url().includes('/spread-bets') && req.method() === 'POST') {
                apiCalled = true;
                console.log('API Request detected:', req.url());
                console.log('Request body:', req.postData());
              }
            });

            await createBtn.click();
            await page.waitForTimeout(3000);

            console.log(`API was called: ${apiCalled}`);
            await page.screenshot({ path: 'tests/screenshots/inv003-after-create.png', fullPage: true });
          } else {
            console.log('Create button is disabled');
          }
        }
      }
    }

    console.log('\n--- Errors ---');
    console.log('JS Errors:', errors.jsErrors);
    console.log('Network Errors:', errors.networkErrors);
  });

  test('INVESTIGATION-004: Direct API test for bet creation', async ({ page, request }) => {
    console.log('\n=== INVESTIGATION-004: Direct API Test ===');

    // Login via UI to get token
    await login(page, TEST_USERS.alice);

    // Get token from localStorage
    const token = await page.evaluate(() => localStorage.getItem('token'));
    console.log(`Token retrieved: ${token ? 'Yes' : 'No'}`);

    if (!token) {
      console.log('ERROR: No token found after login');
      return;
    }

    // Get events
    const eventsResponse = await request.get('http://localhost:8000/api/v1/sport-events', {
      headers: { Authorization: `Bearer ${token}` }
    });
    console.log(`GET /sport-events: ${eventsResponse.status()}`);

    const events = await eventsResponse.json();
    console.log(`Found ${events.length} events`);

    if (events.length > 0) {
      const event = events[0];
      console.log(`Testing with event: ${event.home_team} vs ${event.away_team}`);
      console.log(`Event ID: ${event.id}, Official spread: ${event.official_spread}`);
      console.log(`Min bet: ${event.min_bet_amount}, Max bet: ${event.max_bet_amount}`);

      // Create bet directly via API
      const createResponse = await request.post('http://localhost:8000/api/v1/spread-bets', {
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        data: {
          event_id: event.id,
          spread: event.official_spread,
          team: 'home',
          stake_amount: 50
        }
      });

      console.log(`POST /spread-bets: ${createResponse.status()}`);
      const responseBody = await createResponse.json();
      console.log('Response:', JSON.stringify(responseBody, null, 2));

      if (createResponse.status() >= 400) {
        console.log('BET CREATION FAILED via direct API');
      } else {
        console.log('BET CREATED SUCCESSFULLY via direct API');
        console.log(`Bet ID: ${responseBody.id}`);
      }
    }
  });

  test('INVESTIGATION-005: Check for TakeBetModal bug', async ({ page }) => {
    const errors = setupErrorTracking(page);

    console.log('\n=== INVESTIGATION-005: TakeBetModal Data Bug ===');
    console.log('Investigating: betInfo is array but used as object');

    // First, create a bet as Alice via API
    await login(page, TEST_USERS.alice);
    const aliceToken = await page.evaluate(() => localStorage.getItem('token'));

    // Get event
    const eventsResp = await page.request.get('http://localhost:8000/api/v1/sport-events', {
      headers: { Authorization: `Bearer ${aliceToken}` }
    });
    const events = await eventsResp.json();

    if (events.length > 0) {
      const event = events[0];

      // Create bet as Alice
      const createResp = await page.request.post('http://localhost:8000/api/v1/spread-bets', {
        headers: {
          Authorization: `Bearer ${aliceToken}`,
          'Content-Type': 'application/json'
        },
        data: {
          event_id: event.id,
          spread: event.official_spread,
          team: 'home',
          stake_amount: 75
        }
      });

      if (createResp.ok()) {
        const createdBet = await createResp.json();
        console.log(`Created bet ${createdBet.id} as Alice`);

        // Now logout and login as Bob
        await page.goto('/');
        await page.locator('button:has-text("Logout")').click().catch(() => {});
        await page.waitForTimeout(500);

        await login(page, TEST_USERS.bob);
        console.log('Logged in as Bob');

        // Navigate to sport events
        await page.goto('/sport-events');
        await page.waitForTimeout(1500);

        // Select the event
        const eventBtn = page.locator('button').filter({ hasText: new RegExp(event.home_team, 'i') });
        if (await eventBtn.count() > 0) {
          await eventBtn.first().click();
          await page.waitForTimeout(1500);

          await page.screenshot({ path: 'tests/screenshots/inv005-bob-event.png', fullPage: true });

          // Find spread cell with the bet
          const spreadCell = page.locator('button').filter({ hasText: new RegExp(`^[+-]?${event.official_spread}$`) });
          if (await spreadCell.count() > 0) {
            await spreadCell.first().click();
            await page.waitForTimeout(1000);

            await page.screenshot({ path: 'tests/screenshots/inv005-spread-modal.png', fullPage: true });

            // Look for Take Bet button
            const takeBetBtn = page.locator('button').filter({ hasText: /take bet/i });
            if (await takeBetBtn.count() > 0) {
              console.log('Take Bet button found');
              await takeBetBtn.first().click();
              await page.waitForTimeout(1000);

              await page.screenshot({ path: 'tests/screenshots/inv005-take-modal.png', fullPage: true });

              // Check modal content for undefined/NaN
              const modalText = await page.locator('.fixed.inset-0').textContent().catch(() => '');
              console.log('Modal text sample:', modalText?.substring(0, 500));

              const hasUndefined = modalText?.includes('undefined');
              const hasNaN = modalText?.includes('NaN');
              const hasNull = modalText?.includes('null');

              console.log(`Contains "undefined": ${hasUndefined}`);
              console.log(`Contains "NaN": ${hasNaN}`);
              console.log(`Contains "null": ${hasNull}`);

              if (hasUndefined || hasNaN) {
                console.log('\nDEFECT CONFIRMED: TakeBetModal displays corrupted data');
                console.log('Root cause: betInfo is assigned from spread_grid[spread] which returns SpreadGridBet[]');
                console.log('but is used as a single SpreadGridBet object (accessing .creator_username, .stake directly)');
              }
            } else {
              console.log('No Take Bet button found - bet may not be visible to Bob');
            }
          }
        }
      }
    }

    console.log('\n--- Errors ---');
    console.log('JS Errors:', errors.jsErrors);
    console.log('Network Errors:', errors.networkErrors);
  });

  test('INVESTIGATION-006: Full bet creation and taking workflow', async ({ page }) => {
    const errors = setupErrorTracking(page);

    console.log('\n=== INVESTIGATION-006: Full Workflow Test ===');

    // Step 1: Login as Alice and create bet
    await login(page, TEST_USERS.alice);
    const aliceToken = await page.evaluate(() => localStorage.getItem('token'));

    // Get events
    const eventsResp = await page.request.get('http://localhost:8000/api/v1/sport-events', {
      headers: { Authorization: `Bearer ${aliceToken}` }
    });
    const events = await eventsResp.json();
    console.log(`Found ${events.length} events`);

    if (events.length === 0) {
      console.log('ERROR: No events available');
      return;
    }

    const event = events[0];
    console.log(`Using event: ${event.home_team} vs ${event.away_team}`);

    // Create bet via API (to ensure it works)
    const createResp = await page.request.post('http://localhost:8000/api/v1/spread-bets', {
      headers: {
        Authorization: `Bearer ${aliceToken}`,
        'Content-Type': 'application/json'
      },
      data: {
        event_id: event.id,
        spread: event.official_spread,
        team: 'home',
        stake_amount: 50
      }
    });

    const createStatus = createResp.status();
    const createBody = await createResp.json();
    console.log(`Create bet API: ${createStatus}`);
    console.log('Create response:', createBody);

    if (createStatus >= 400) {
      console.log('DEFECT: Cannot create bet via API');
      return;
    }

    const betId = createBody.id;
    console.log(`Created bet ID: ${betId}`);

    // Step 2: Logout Alice
    await page.goto('/');
    await page.getByRole('button', { name: /logout/i }).click().catch(() => {});
    await page.waitForTimeout(1000);

    // Step 3: Login as Bob and try to take bet
    await login(page, TEST_USERS.bob);
    const bobToken = await page.evaluate(() => localStorage.getItem('token'));
    console.log('Logged in as Bob');

    // Try to take bet via API
    const takeResp = await page.request.post(`http://localhost:8000/api/v1/spread-bets/${betId}/take`, {
      headers: {
        Authorization: `Bearer ${bobToken}`,
        'Content-Type': 'application/json'
      }
    });

    const takeStatus = takeResp.status();
    const takeBody = await takeResp.json();
    console.log(`Take bet API: ${takeStatus}`);
    console.log('Take response:', takeBody);

    if (takeStatus >= 400) {
      console.log('DEFECT: Cannot take bet via API');
    } else {
      console.log('SUCCESS: Bet taken successfully via API');
      console.log(`Bet status: ${takeBody.status}`);
    }

    // Now test via UI
    console.log('\n--- UI Test ---');
    await page.goto('/sport-events');
    await page.waitForTimeout(1500);

    // Click on the event
    const eventBtn = page.locator('button').filter({ hasText: new RegExp(event.home_team, 'i') });
    if (await eventBtn.count() > 0) {
      await eventBtn.first().click();
      await page.waitForTimeout(1500);

      await page.screenshot({ path: 'tests/screenshots/inv006-event-view.png', fullPage: true });

      // Check what's displayed
      const pageText = await page.textContent('body');
      console.log(`Page shows "matched": ${pageText?.includes('matched')}`);
      console.log(`Page shows "open": ${pageText?.includes('open')}`);
    }

    console.log('\n--- Final Error Summary ---');
    console.log('JS Errors:', errors.jsErrors);
    console.log('Network Errors:', errors.networkErrors.map(e => `${e.method} ${e.url}: ${e.status} ${JSON.stringify(e.body)}`));
  });
});
