#!/usr/bin/env bun
/**
 * HYPERSCRIPT DEF STATEMENT LIMIT TEST
 * =====================================
 * Tests if hyperscript parser still has the 3 def statement limit
 *
 * CRITICAL: This test determines if we need to keep using JavaScript
 * functions or if we can safely use more def statements in hyperscript.
 *
 * Historical context:
 * - Hyperscript 0.9.12 had a hard limit of 3 def statements
 * - We moved functions to JavaScript to work around this
 * - Now using LATEST hyperscript version - need to verify if limit still exists
 *
 * Test methodology:
 * 1. Create test page with 1, 2, 3, 4, 5 def statements
 * 2. Check for parser errors after each addition
 * 3. Verify functions actually work (not just parse)
 * 4. Document findings for PROJECT-MEMORY.md
 */

import { chromium } from 'playwright';

const PORT = 1999;
const TEST_SERVER_URL = `http://localhost:${PORT}`;

// We'll need to check if the main server is running first
async function checkServerRunning() {
  try {
    const response = await fetch(TEST_SERVER_URL);
    return response.ok;
  } catch (e) {
    return false;
  }
}

async function testHyperscriptDefLimit() {
  console.log('🧪 HYPERSCRIPT DEF STATEMENT LIMIT TEST\n');
  console.log('='.repeat(70));

  // Check if server is running
  const serverRunning = await checkServerRunning();
  if (!serverRunning) {
    console.log(`\n⚠️  WARNING: Server not running on port ${PORT}`);
    console.log('This test will create standalone HTML pages to test hyperscript limits.\n');
  }

  const browser = await chromium.launch({ headless: false });
  const testResults = [];
  const errors = [];

  // ========================================================================
  // TEST 1: Baseline - 1 def statement (should always work)
  // ========================================================================
  console.log("\n1️⃣  Testing 1 def statement...");

  const page1 = await browser.newPage();

  const html1 = `<!DOCTYPE html>
<html>
<head>
  <title>1 Def Statement Test</title>
  <script src="https://unpkg.com/hyperscript.org@latest"></script>
</head>
<body>
  <h1>Test: 1 Def Statement</h1>
  <button id="test-btn-1">Click me</button>
  <div id="result-1"></div>

  <script type="text/hyperscript">
    def testFunction1()
      put "Function 1 works!" into #result-1
    end
  </script>

  <script type="text/hyperscript">
    on click from #test-btn-1
      call testFunction1()
    end
  </script>
</body>
</html>`;

  await page1.setContent(html1);
  await page1.waitForTimeout(1000);

  const test1 = await page1.evaluate(() => {
    const errors = [];
    const warnings = [];

    // Capture console errors
    const originalError = console.error;
    console.error = (...args) => {
      errors.push(args.join(' '));
      originalError.apply(console, args);
    };

    // Check for hyperscript parse errors
    const hasParseError = document.body.innerText.includes('Parse Error') ||
                          document.body.innerText.includes('SyntaxError');

    // Try to trigger the function
    const btn = document.getElementById('test-btn-1');
    const result = document.getElementById('result-1');

    btn.click();

    const functionWorks = result.innerText === "Function 1 works!";

    return {
      hasParseError,
      functionWorks,
      resultText: result.innerText,
      errors: errors.length
    };
  });

  console.log(`   Parse errors: ${test1.hasParseError ? '❌ YES' : '✅ NO'}`);
  console.log(`   Function works: ${test1.functionWorks ? '✅ YES' : '❌ NO'}`);
  console.log(`   Result: "${test1.resultText}"`);

  const test1Pass = !test1.hasParseError && test1.functionWorks;
  console.log(`   ${test1Pass ? '✅ PASS' : '❌ FAIL'} - 1 def statement`);
  testResults.push({ test: '1 Def Statement', passed: test1Pass });

  await page1.close();

  // ========================================================================
  // TEST 2: 2 def statements
  // ========================================================================
  console.log("\n2️⃣  Testing 2 def statements...");

  const page2 = await browser.newPage();

  const html2 = `<!DOCTYPE html>
<html>
<head>
  <title>2 Def Statements Test</title>
  <script src="https://unpkg.com/hyperscript.org@latest"></script>
</head>
<body>
  <h1>Test: 2 Def Statements</h1>
  <button id="test-btn-1">Test 1</button>
  <button id="test-btn-2">Test 2</button>
  <div id="result"></div>

  <script type="text/hyperscript">
    def testFunction1()
      put "Function 1 works!" into #result
    end

    def testFunction2()
      put "Function 2 works!" into #result
    end
  </script>

  <script type="text/hyperscript">
    on click from #test-btn-1
      call testFunction1()
    end

    on click from #test-btn-2
      call testFunction2()
    end
  </script>
</body>
</html>`;

  await page2.setContent(html2);
  await page2.waitForTimeout(1000);

  const test2 = await page2.evaluate(() => {
    const hasParseError = document.body.innerText.includes('Parse Error') ||
                          document.body.innerText.includes('SyntaxError');

    const btn1 = document.getElementById('test-btn-1');
    const btn2 = document.getElementById('test-btn-2');
    const result = document.getElementById('result');

    btn1.click();
    const func1Works = result.innerText === "Function 1 works!";

    btn2.click();
    const func2Works = result.innerText === "Function 2 works!";

    return {
      hasParseError,
      func1Works,
      func2Works,
      bothWork: func1Works && func2Works
    };
  });

  console.log(`   Parse errors: ${test2.hasParseError ? '❌ YES' : '✅ NO'}`);
  console.log(`   Function 1 works: ${test2.func1Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 2 works: ${test2.func2Works ? '✅ YES' : '❌ NO'}`);

  const test2Pass = !test2.hasParseError && test2.bothWork;
  console.log(`   ${test2Pass ? '✅ PASS' : '❌ FAIL'} - 2 def statements`);
  testResults.push({ test: '2 Def Statements', passed: test2Pass });

  await page2.close();

  // ========================================================================
  // TEST 3: 3 def statements (CRITICAL - historical limit)
  // ========================================================================
  console.log("\n3️⃣  Testing 3 def statements (CRITICAL - historical limit)...");

  const page3 = await browser.newPage();

  const html3 = `<!DOCTYPE html>
<html>
<head>
  <title>3 Def Statements Test</title>
  <script src="https://unpkg.com/hyperscript.org@latest"></script>
</head>
<body>
  <h1>Test: 3 Def Statements</h1>
  <button id="test-btn-1">Test 1</button>
  <button id="test-btn-2">Test 2</button>
  <button id="test-btn-3">Test 3</button>
  <div id="result"></div>

  <script type="text/hyperscript">
    def testFunction1()
      put "Function 1 works!" into #result
    end

    def testFunction2()
      put "Function 2 works!" into #result
    end

    def testFunction3()
      put "Function 3 works!" into #result
    end
  </script>

  <script type="text/hyperscript">
    on click from #test-btn-1
      call testFunction1()
    end

    on click from #test-btn-2
      call testFunction2()
    end

    on click from #test-btn-3
      call testFunction3()
    end
  </script>
</body>
</html>`;

  await page3.setContent(html3);
  await page3.waitForTimeout(1000);

  const test3 = await page3.evaluate(() => {
    const hasParseError = document.body.innerText.includes('Parse Error') ||
                          document.body.innerText.includes('SyntaxError');

    const btn1 = document.getElementById('test-btn-1');
    const btn2 = document.getElementById('test-btn-2');
    const btn3 = document.getElementById('test-btn-3');
    const result = document.getElementById('result');

    btn1.click();
    const func1Works = result.innerText === "Function 1 works!";

    btn2.click();
    const func2Works = result.innerText === "Function 2 works!";

    btn3.click();
    const func3Works = result.innerText === "Function 3 works!";

    return {
      hasParseError,
      func1Works,
      func2Works,
      func3Works,
      allWork: func1Works && func2Works && func3Works
    };
  });

  console.log(`   Parse errors: ${test3.hasParseError ? '❌ YES' : '✅ NO'}`);
  console.log(`   Function 1 works: ${test3.func1Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 2 works: ${test3.func2Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 3 works: ${test3.func3Works ? '✅ YES' : '❌ NO'}`);

  const test3Pass = !test3.hasParseError && test3.allWork;
  console.log(`   ${test3Pass ? '✅ PASS' : '❌ FAIL'} - 3 def statements`);
  testResults.push({ test: '3 Def Statements', passed: test3Pass });

  await page3.close();

  // ========================================================================
  // TEST 4: 4 def statements (BEYOND historical limit)
  // ========================================================================
  console.log("\n4️⃣  Testing 4 def statements (BEYOND historical limit)...");

  const page4 = await browser.newPage();

  const html4 = `<!DOCTYPE html>
<html>
<head>
  <title>4 Def Statements Test</title>
  <script src="https://unpkg.com/hyperscript.org@latest"></script>
</head>
<body>
  <h1>Test: 4 Def Statements</h1>
  <button id="test-btn-1">Test 1</button>
  <button id="test-btn-2">Test 2</button>
  <button id="test-btn-3">Test 3</button>
  <button id="test-btn-4">Test 4</button>
  <div id="result"></div>

  <script type="text/hyperscript">
    def testFunction1()
      put "Function 1 works!" into #result
    end

    def testFunction2()
      put "Function 2 works!" into #result
    end

    def testFunction3()
      put "Function 3 works!" into #result
    end

    def testFunction4()
      put "Function 4 works!" into #result
    end
  </script>

  <script type="text/hyperscript">
    on click from #test-btn-1
      call testFunction1()
    end

    on click from #test-btn-2
      call testFunction2()
    end

    on click from #test-btn-3
      call testFunction3()
    end

    on click from #test-btn-4
      call testFunction4()
    end
  </script>
</body>
</html>`;

  await page4.setContent(html4);
  await page4.waitForTimeout(1000);

  const test4 = await page4.evaluate(() => {
    const hasParseError = document.body.innerText.includes('Parse Error') ||
                          document.body.innerText.includes('SyntaxError');

    const btn1 = document.getElementById('test-btn-1');
    const btn2 = document.getElementById('test-btn-2');
    const btn3 = document.getElementById('test-btn-3');
    const btn4 = document.getElementById('test-btn-4');
    const result = document.getElementById('result');

    btn1.click();
    const func1Works = result.innerText === "Function 1 works!";

    btn2.click();
    const func2Works = result.innerText === "Function 2 works!";

    btn3.click();
    const func3Works = result.innerText === "Function 3 works!";

    btn4.click();
    const func4Works = result.innerText === "Function 4 works!";

    return {
      hasParseError,
      func1Works,
      func2Works,
      func3Works,
      func4Works,
      allWork: func1Works && func2Works && func3Works && func4Works
    };
  });

  console.log(`   Parse errors: ${test4.hasParseError ? '❌ YES' : '✅ NO'}`);
  console.log(`   Function 1 works: ${test4.func1Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 2 works: ${test4.func2Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 3 works: ${test4.func3Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 4 works: ${test4.func4Works ? '✅ YES' : '❌ NO'}`);

  const test4Pass = !test4.hasParseError && test4.allWork;
  console.log(`   ${test4Pass ? '✅ PASS' : '❌ FAIL'} - 4 def statements`);
  testResults.push({ test: '4 Def Statements', passed: test4Pass });

  await page4.close();

  // ========================================================================
  // TEST 5: 5 def statements (well beyond limit)
  // ========================================================================
  console.log("\n5️⃣  Testing 5 def statements (well beyond limit)...");

  const page5 = await browser.newPage();

  const html5 = `<!DOCTYPE html>
<html>
<head>
  <title>5 Def Statements Test</title>
  <script src="https://unpkg.com/hyperscript.org@latest"></script>
</head>
<body>
  <h1>Test: 5 Def Statements</h1>
  <button id="test-btn-1">Test 1</button>
  <button id="test-btn-2">Test 2</button>
  <button id="test-btn-3">Test 3</button>
  <button id="test-btn-4">Test 4</button>
  <button id="test-btn-5">Test 5</button>
  <div id="result"></div>

  <script type="text/hyperscript">
    def testFunction1()
      put "Function 1 works!" into #result
    end

    def testFunction2()
      put "Function 2 works!" into #result
    end

    def testFunction3()
      put "Function 3 works!" into #result
    end

    def testFunction4()
      put "Function 4 works!" into #result
    end

    def testFunction5()
      put "Function 5 works!" into #result
    end
  </script>

  <script type="text/hyperscript">
    on click from #test-btn-1
      call testFunction1()
    end

    on click from #test-btn-2
      call testFunction2()
    end

    on click from #test-btn-3
      call testFunction3()
    end

    on click from #test-btn-4
      call testFunction4()
    end

    on click from #test-btn-5
      call testFunction5()
    end
  </script>
</body>
</html>`;

  await page5.setContent(html5);
  await page5.waitForTimeout(1000);

  const test5 = await page5.evaluate(() => {
    const hasParseError = document.body.innerText.includes('Parse Error') ||
                          document.body.innerText.includes('SyntaxError');

    const btn1 = document.getElementById('test-btn-1');
    const btn2 = document.getElementById('test-btn-2');
    const btn3 = document.getElementById('test-btn-3');
    const btn4 = document.getElementById('test-btn-4');
    const btn5 = document.getElementById('test-btn-5');
    const result = document.getElementById('result');

    btn1.click();
    const func1Works = result.innerText === "Function 1 works!";

    btn2.click();
    const func2Works = result.innerText === "Function 2 works!";

    btn3.click();
    const func3Works = result.innerText === "Function 3 works!";

    btn4.click();
    const func4Works = result.innerText === "Function 4 works!";

    btn5.click();
    const func5Works = result.innerText === "Function 5 works!";

    return {
      hasParseError,
      func1Works,
      func2Works,
      func3Works,
      func4Works,
      func5Works,
      allWork: func1Works && func2Works && func3Works && func4Works && func5Works
    };
  });

  console.log(`   Parse errors: ${test5.hasParseError ? '❌ YES' : '✅ NO'}`);
  console.log(`   Function 1 works: ${test5.func1Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 2 works: ${test5.func2Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 3 works: ${test5.func3Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 4 works: ${test5.func4Works ? '✅ YES' : '❌ NO'}`);
  console.log(`   Function 5 works: ${test5.func5Works ? '✅ YES' : '❌ NO'}`);

  const test5Pass = !test5.hasParseError && test5.allWork;
  console.log(`   ${test5Pass ? '✅ PASS' : '❌ FAIL'} - 5 def statements`);
  testResults.push({ test: '5 Def Statements', passed: test5Pass });

  await page5.close();

  // ========================================================================
  // FINAL SUMMARY & ANALYSIS
  // ========================================================================
  console.log("\n" + "=".repeat(70));
  console.log("📊 TEST SUMMARY & ANALYSIS\n");

  const totalTests = testResults.length;
  const passedTests = testResults.filter(r => r.passed).length;
  const failedTests = totalTests - passedTests;

  testResults.forEach(result => {
    console.log(`   ${result.passed ? '✅' : '❌'} ${result.test}`);
  });

  console.log(`\n   Total: ${passedTests}/${totalTests} tests passed`);

  console.log("\n" + "=".repeat(70));
  console.log("🔍 ANALYSIS & CONCLUSION\n");

  // Determine if limit exists
  const limitExists = !test4.allWork || test4.hasParseError;
  const limitAt = passedTests;

  if (passedTests === 5) {
    console.log("✅ GOOD NEWS: NO 3 DEF LIMIT!");
    console.log("\n   The latest hyperscript version does NOT have the 3 def limit.");
    console.log("   All 5 def statements worked perfectly.");
    console.log("\n   RECOMMENDATION:");
    console.log("   - We can safely use def statements in hyperscript");
    console.log("   - No need to keep using JavaScript workarounds");
    console.log("   - Can simplify code by moving functions back to hyperscript");
    console.log("\n   ACTION ITEMS:");
    console.log("   1. Update PROJECT-MEMORY.md: Remove def limit warning");
    console.log("   2. Consider refactoring: Move simple functions from cv-functions.js to hyperscript");
    console.log("   3. Update HYPERSCRIPT-RULES.md: Document new findings");
  } else if (passedTests >= 3 && !test4.allWork) {
    console.log("⚠️  LIMIT CONFIRMED: 3 DEF STATEMENT LIMIT STILL EXISTS");
    console.log("\n   The historical 3 def limit is STILL present.");
    console.log(`   Working: ${passedTests} def statements`);
    console.log("   Failed: 4+ def statements");
    console.log("\n   RECOMMENDATION:");
    console.log("   - Keep current JavaScript workaround approach");
    console.log("   - Continue using cv-functions.js for toggle functions");
    console.log("   - Limit hyperscript def statements to 3 maximum");
    console.log("\n   ACTION ITEMS:");
    console.log("   1. Update PROJECT-MEMORY.md: Confirm limit still exists");
    console.log("   2. Keep HYPERSCRIPT-RULES.md warnings in place");
    console.log("   3. Document this test result for future reference");
  } else {
    console.log("⚠️  UNEXPECTED RESULT");
    console.log("\n   Some basic def statements failed unexpectedly.");
    console.log("   This requires further investigation.");
    console.log("\n   ACTION ITEMS:");
    console.log("   1. Check hyperscript version being loaded");
    console.log("   2. Review console errors in browser");
    console.log("   3. Verify hyperscript.org CDN is working");
  }

  console.log("\n" + "=".repeat(70));

  console.log("\nBrowser will stay open for manual verification.");
  console.log("Please test the buttons in the last page to confirm results.");
  console.log("Press Ctrl+C when done.\n");

  await new Promise(() => {}); // Keep browser open
}

await testHyperscriptDefLimit();
