#!/usr/bin/env node
const puppeteer = require('puppeteer');

async function getPlayerCount(roomCode) {
  const browser = await puppeteer.launch({ 
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-web-security']
  });
  
  const page = await browser.newPage();
  let playerCount = null;

  // Listen for console API calls (this catches console.log with formatting)
  page.on('console', async msg => {
    try {
      // Get all args
      for (const arg of msg.args()) {
        const val = await arg.jsonValue();
        const str = JSON.stringify(val);
        
        if (process.env.DEBUG) console.error('[CONSOLE]', str.substring(0, 200));
        
        // Check if this is the welcome message
        if (str && str.includes('"opcode":"client/welcome"') && str.includes('"here"')) {
          const data = JSON.parse(str);
          if (data.result && data.result.here) {
            playerCount = Object.keys(data.result.here).length;
            if (process.env.DEBUG) console.error('[FOUND] Player count:', playerCount);
            break;
          }
        }
      }
    } catch (e) {
      // Ignore
    }
  });

  try {
    if (process.env.DEBUG) console.error('[1] Loading page...');
    await page.goto('https://jackbox.tv/', { waitUntil: 'networkidle2', timeout: 30000 });
    
    // Clear storage and reload to avoid reconnect
    if (process.env.DEBUG) console.error('[2] Clearing storage...');
    await page.evaluate(() => {
      localStorage.clear();
      sessionStorage.clear();
    });
    await page.reload({ waitUntil: 'networkidle2' });
    
    await page.waitForSelector('input[placeholder*="ENTER 4-LETTER CODE"]', { timeout: 10000 });
    
    if (process.env.DEBUG) {
      console.error('[2.5] Checking all inputs on page...');
      const allInputs = await page.evaluate(() => {
        const inputs = Array.from(document.querySelectorAll('input'));
        return inputs.map(inp => ({
          type: inp.type,
          placeholder: inp.placeholder,
          value: inp.value,
          name: inp.name,
          id: inp.id,
          visible: inp.offsetParent !== null
        }));
      });
      console.error('[2.5] All inputs:', JSON.stringify(allInputs, null, 2));
    }
    
    if (process.env.DEBUG) console.error('[3] Typing room code...');
    
    // Type room code character by character (with delay to trigger validation)
    await page.click('input[placeholder*="ENTER 4-LETTER CODE"]');
    await page.type('input[placeholder*="ENTER 4-LETTER CODE"]', roomCode, { delay: 100 });
    
    // Wait for room validation to complete (look for loader success message)
    if (process.env.DEBUG) console.error('[3.5] Waiting for room validation...');
    await new Promise(resolve => setTimeout(resolve, 1500));
    
    // Type name character by character - this will enable the Play button
    if (process.env.DEBUG) console.error('[3.6] Typing name...');
    await page.click('input[placeholder*="ENTER YOUR NAME"]');
    await page.type('input[placeholder*="ENTER YOUR NAME"]', 'Observer', { delay: 100 });
    
    // Wait a moment for button to fully enable
    await new Promise(resolve => setTimeout(resolve, 500));
    
    if (process.env.DEBUG) {
      const fieldValues = await page.evaluate(() => {
        const roomInput = document.querySelector('input[placeholder*="ENTER 4-LETTER CODE"]');
        const nameInput = document.querySelector('input[placeholder*="ENTER YOUR NAME"]');
        return {
          roomCode: roomInput ? roomInput.value : 'NOT FOUND',
          name: nameInput ? nameInput.value : 'NOT FOUND'
        };
      });
      console.error('[3.5] Field values:', fieldValues);
    }
    
    // Find the Play or RECONNECT button (case-insensitive, not disabled)
    if (process.env.DEBUG) {
      const buttonInfo = await page.evaluate(() => {
        const buttons = Array.from(document.querySelectorAll('button'));
        const allButtons = buttons.map(b => ({
          text: b.textContent.trim(),
          disabled: b.disabled,
          visible: b.offsetParent !== null
        }));
        const actionBtn = buttons.find(b => {
          const text = b.textContent.toUpperCase();
          return (text.includes('PLAY') || text.includes('RECONNECT')) && !b.disabled;
        });
        return {
          allButtons,
          found: actionBtn ? actionBtn.textContent.trim() : 'NOT FOUND'
        };
      });
      console.error('[4] All buttons:', JSON.stringify(buttonInfo.allButtons, null, 2));
      console.error('[4] Target button:', buttonInfo.found);
    }
    
    if (process.env.DEBUG) console.error('[5] Clicking Play/Reconnect (even if disabled)...');
    await page.evaluate(() => {
      const buttons = Array.from(document.querySelectorAll('button'));
      const actionBtn = buttons.find(b => {
        const text = b.textContent.toUpperCase();
        return text.includes('PLAY') || text.includes('RECONNECT');
      });
      if (actionBtn) {
        // Remove disabled attribute and click
        actionBtn.disabled = false;
        actionBtn.click();
      } else {
        throw new Error('Could not find PLAY or RECONNECT button');
      }
    });
    
    // Wait for navigation/lobby to load
    if (process.env.DEBUG) console.error('[6] Waiting for lobby (5 seconds)...');
    await new Promise(resolve => setTimeout(resolve, 5000));
    
    // Check if we're in the lobby
    const pageText = await page.evaluate(() => document.body.innerText);
    const inLobby = pageText.includes('Sit back') || pageText.includes('relax');
    
    if (process.env.DEBUG) {
      console.error('[7] In lobby:', inLobby);
      console.error('[7] Page text sample:', pageText.substring(0, 100));
      console.error('[7] Page URL:', page.url());
    }
    
    // Wait for WebSocket message
    if (process.env.DEBUG) console.error('[8] Waiting for player count...');
    for (let i = 0; i < 20 && playerCount === null; i++) {
      await new Promise(resolve => setTimeout(resolve, 500));
      if (process.env.DEBUG && i % 4 === 0) {
        console.error(`[8.${i}] Still waiting...`);
      }
    }
  } finally {
    await browser.close();
  }

  if (playerCount === null) {
    throw new Error('Could not get player count');
  }

  return playerCount;
}

const roomCode = process.argv[2];
if (!roomCode) {
  console.error('Usage: node jackbox-count-v2.js <ROOM_CODE>');
  process.exit(1);
}

getPlayerCount(roomCode.toUpperCase())
  .then(count => {
    console.log(count);
    process.exit(0);
  })
  .catch(err => {
    console.error('Error:', err.message);
    process.exit(1);
  });

