#!/usr/bin/env bun
/**
 * CMD+K LAZY LOADING TEST
 * =======================
 * Tests that ninja-keys is lazy-loaded only when needed:
 * - No ninja-keys element on initial page load
 * - No esm.sh/ninja-keys loaded initially
 * - CMD+K triggers dynamic import
 * - ninja-keys element created and opened
 * - Subsequent uses don't reload
 *
 * This optimization reduces initial page load by ~15 module requests
 */

import { chromium } from 'playwright';

const URL = "http://localhost:1999";

async function testCmdKLazyLoading() {
  console.log('🚀 CMD+K LAZY LOADING TEST\n');
  console.log('='.repeat(70));

  const browser = await chromium.launch({ headless: process.env.HEADLESS === 'true' });
  const context = await browser.newContext({ viewport: { width: 1920, height: 1080 } });
  const page = await context.newPage();

  const testResults = [];
  const networkRequests = [];

  // Monitor network requests
  page.on('request', request => {
    const url = request.url();
    if (url.includes('ninja-keys') || url.includes('esm.sh')) {
      networkRequests.push({
        url,
        timestamp: Date.now(),
        type: request.resourceType()
      });
    }
  });

  await page.goto(URL);
  await page.waitForTimeout(2000);

  const initialRequestCount = networkRequests.length;
  console.log(`   Initial ninja-keys/esm.sh requests: ${initialRequestCount}`);

  // ========================================================================
  // TEST 1: No ninja-keys element on initial load
  // ========================================================================
  console.log('\n1️⃣  Testing no ninja-keys on initial load...');

  const ninjaKeysOnLoad = await page.evaluate(() => {
    const nk = document.getElementById('cmd-k-bar');
    return {
      exists: !!nk,
      tagName: nk?.tagName || 'N/A'
    };
  });

  console.log(`   ninja-keys element exists: ${ninjaKeysOnLoad.exists}`);
  const noInitialElement = !ninjaKeysOnLoad.exists;
  console.log(`   ${noInitialElement ? '✅ PASS' : '❌ FAIL'} - No ninja-keys element on initial load`);
  testResults.push({ test: 'No ninja-keys element on initial load', passed: noInitialElement });

  // ========================================================================
  // TEST 2: No esm.sh requests on initial load
  // ========================================================================
  console.log('\n2️⃣  Testing no esm.sh requests on initial load...');

  const noInitialRequests = initialRequestCount === 0;
  console.log(`   esm.sh requests before interaction: ${initialRequestCount}`);
  console.log(`   ${noInitialRequests ? '✅ PASS' : '❌ FAIL'} - No ninja-keys loaded initially`);
  testResults.push({ test: 'No esm.sh requests on initial load', passed: noInitialRequests });

  // ========================================================================
  // TEST 3: Container element exists for lazy loading
  // ========================================================================
  console.log('\n3️⃣  Testing container element exists...');

  const containerExists = await page.evaluate(() => {
    const container = document.getElementById('cmd-k-container');
    return !!container;
  });

  console.log(`   cmd-k-container exists: ${containerExists}`);
  console.log(`   ${containerExists ? '✅ PASS' : '❌ FAIL'} - Container ready for lazy loading`);
  testResults.push({ test: 'Container element exists', passed: containerExists });

  // ========================================================================
  // TEST 4: CMD+K triggers lazy load
  // ========================================================================
  console.log('\n4️⃣  Testing CMD+K triggers lazy load...');

  const requestsBeforeCmdK = networkRequests.length;

  // Press CMD+K (Mac) or Ctrl+K (Windows/Linux)
  await page.keyboard.press('Meta+k');
  await page.waitForTimeout(3000); // Wait for module to load and custom element to register

  const requestsAfterCmdK = networkRequests.length;
  const newRequests = requestsAfterCmdK - requestsBeforeCmdK;

  console.log(`   Requests before CMD+K: ${requestsBeforeCmdK}`);
  console.log(`   Requests after CMD+K: ${requestsAfterCmdK}`);
  console.log(`   New esm.sh requests: ${newRequests}`);

  const lazyLoadTriggered = newRequests > 0;
  console.log(`   ${lazyLoadTriggered ? '✅ PASS' : '❌ FAIL'} - CMD+K triggers module load`);
  testResults.push({ test: 'CMD+K triggers lazy load', passed: lazyLoadTriggered });

  // ========================================================================
  // TEST 5: ninja-keys element created after CMD+K
  // ========================================================================
  console.log('\n5️⃣  Testing ninja-keys element created...');

  const ninjaKeysAfterCmdK = await page.evaluate(() => {
    const nk = document.getElementById('cmd-k-bar');
    if (!nk) return { exists: false, tagName: 'N/A', isOpen: false };
    // ninja-keys uses shadow DOM with .modal.visible class
    const shadow = nk.shadowRoot;
    const modal = shadow?.querySelector('.modal');
    return {
      exists: true,
      tagName: nk.tagName,
      isOpen: modal?.classList?.contains('visible') || false
    };
  });

  console.log(`   ninja-keys exists: ${ninjaKeysAfterCmdK.exists}`);
  console.log(`   ninja-keys tag: ${ninjaKeysAfterCmdK.tagName}`);
  console.log(`   ninja-keys open: ${ninjaKeysAfterCmdK.isOpen}`);

  const elementCreated = ninjaKeysAfterCmdK.exists && ninjaKeysAfterCmdK.tagName === 'NINJA-KEYS';
  console.log(`   ${elementCreated ? '✅ PASS' : '❌ FAIL'} - ninja-keys element created`);
  testResults.push({ test: 'ninja-keys element created', passed: elementCreated });

  // Close ninja-keys
  await page.keyboard.press('Escape');
  await page.waitForTimeout(300);

  // ========================================================================
  // TEST 6: Subsequent CMD+K doesn't reload module
  // ========================================================================
  console.log('\n6️⃣  Testing subsequent CMD+K doesn\'t reload...');

  const requestsBeforeSecond = networkRequests.length;

  // Press CMD+K again
  await page.keyboard.press('Meta+k');
  await page.waitForTimeout(500);

  const requestsAfterSecond = networkRequests.length;
  const additionalRequests = requestsAfterSecond - requestsBeforeSecond;

  console.log(`   Requests before 2nd CMD+K: ${requestsBeforeSecond}`);
  console.log(`   Requests after 2nd CMD+K: ${requestsAfterSecond}`);
  console.log(`   Additional requests: ${additionalRequests}`);

  const noReload = additionalRequests === 0;
  console.log(`   ${noReload ? '✅ PASS' : '❌ FAIL'} - No module reload on subsequent use`);
  testResults.push({ test: 'No module reload on subsequent use', passed: noReload });

  // Close ninja-keys
  await page.keyboard.press('Escape');
  await page.waitForTimeout(300);

  // ========================================================================
  // TEST 7: Button click also triggers lazy load
  // ========================================================================
  console.log('\n7️⃣  Testing button click works with lazy-loaded ninja-keys...');

  const cmdKButton = await page.$('#cmd-k-button');
  if (cmdKButton) {
    await cmdKButton.click();
    await page.waitForTimeout(1000);

    const openAfterClick = await page.evaluate(() => {
      const nk = document.getElementById('cmd-k-bar');
      if (!nk) return false;
      // ninja-keys uses shadow DOM with .modal.visible class
      const shadow = nk.shadowRoot;
      const modal = shadow?.querySelector('.modal');
      return modal?.classList?.contains('visible') || false;
    });

    console.log(`   ninja-keys opened via button: ${openAfterClick}`);
    console.log(`   ${openAfterClick ? '✅ PASS' : '❌ FAIL'} - Button click opens ninja-keys`);
    testResults.push({ test: 'Button click opens ninja-keys', passed: openAfterClick });

    await page.keyboard.press('Escape');
  } else {
    console.log('   ⚠️  CMD+K button not found');
    testResults.push({ test: 'Button click opens ninja-keys', passed: false });
  }

  // ========================================================================
  // TEST 8: esm.sh used instead of unpkg (no redirect chains)
  // ========================================================================
  console.log('\n8️⃣  Testing esm.sh CDN used (no 302 redirects)...');

  const esmShRequests = networkRequests.filter(r => r.url.includes('esm.sh'));
  const unpkgRequests = networkRequests.filter(r => r.url.includes('unpkg.com/ninja-keys'));

  console.log(`   esm.sh requests: ${esmShRequests.length}`);
  console.log(`   unpkg ninja-keys requests: ${unpkgRequests.length}`);

  const usesEsmSh = esmShRequests.length > 0 && unpkgRequests.length === 0;
  console.log(`   ${usesEsmSh ? '✅ PASS' : '❌ FAIL'} - Uses esm.sh CDN (pre-bundled)`);
  testResults.push({ test: 'Uses esm.sh CDN (no redirects)', passed: usesEsmSh });

  // ========================================================================
  // FINAL SUMMARY
  // ========================================================================
  console.log("\n" + "=".repeat(70));
  console.log("📊 TEST SUMMARY\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`);

  // Show all network requests for debugging
  if (networkRequests.length > 0) {
    console.log('\n   Network requests (ninja-keys/esm.sh):');
    networkRequests.forEach((r, i) => {
      console.log(`     ${i + 1}. ${r.url.substring(0, 80)}...`);
    });
  }

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

  if (failedTests === 0) {
    console.log("🎉 ALL CMD+K LAZY LOADING TESTS PASSED!");
    console.log("   Initial page load has NO ninja-keys overhead!");
  } else {
    console.log("⚠️  SOME TESTS FAILED - See details above");
  }

  // Auto-close after tests if HEADLESS env is set
  if (process.env.HEADLESS === 'true') {
    await browser.close();
    process.exit(failedTests === 0 ? 0 : 1);
  } else {
    console.log("\nBrowser will stay open for manual inspection.");
    console.log("Press Ctrl+C when done.\n");
    await new Promise(() => {}); // Keep browser open
  }
}

await testCmdKLazyLoading();
