#!/usr/bin/env bun
/**
 * HTMX FUNCTIONALITY TEST
 * ========================
 * Tests HTMX swap behavior and indicators
 * - Verifies HTMX is loaded
 * - Tests hx-get requests
 * - Validates swap behavior
 * - Checks loading indicators
 */

import { chromium } from 'playwright';

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

async function testHTMX() {
  console.log('⚡ HTMX FUNCTIONALITY TEST\n');
  console.log('='.repeat(70));

  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } });

  const errors = [];
  const testResults = [];

  page.on('console', msg => {
    const text = msg.text();
    if (msg.type() === 'error') {
      errors.push(text);
      console.log(`❌ ERROR: ${text}`);
    }
  });

  console.log("\n1️⃣  Loading page...");
  await page.goto(URL);
  await page.waitForTimeout(2000);

  // ========================================================================
  // TEST 1: HTMX is loaded
  // ========================================================================
  console.log("\n2️⃣  Testing HTMX Loaded...");
  const htmxLoaded = await page.evaluate(() => {
    return {
      htmxExists: typeof htmx !== 'undefined',
      version: typeof htmx !== 'undefined' ? htmx.version : 'N/A'
    };
  });

  console.log(`   HTMX loaded: ${htmxLoaded.htmxExists ? '✅' : '❌'}`);
  console.log(`   Version: ${htmxLoaded.version}`);
  console.log(`   ${htmxLoaded.htmxExists ? '✅ PASS' : '❌ FAIL'} - HTMX loaded`);
  testResults.push({ test: 'HTMX Loaded', passed: htmxLoaded.htmxExists });

  // ========================================================================
  // TEST 2: Check for HTMX elements
  // ========================================================================
  console.log("\n3️⃣  Testing HTMX Elements...");
  const htmxElements = await page.evaluate(() => {
    const hxGetElements = document.querySelectorAll('[hx-get]').length;
    const hxPostElements = document.querySelectorAll('[hx-post]').length;
    const hxSwapElements = document.querySelectorAll('[hx-swap]').length;
    const hxTargetElements = document.querySelectorAll('[hx-target]').length;

    return {
      hxGet: hxGetElements,
      hxPost: hxPostElements,
      hxSwap: hxSwapElements,
      hxTarget: hxTargetElements,
      total: hxGetElements + hxPostElements + hxSwapElements + hxTargetElements
    };
  });

  console.log(`   hx-get elements: ${htmxElements.hxGet}`);
  console.log(`   hx-post elements: ${htmxElements.hxPost}`);
  console.log(`   hx-swap elements: ${htmxElements.hxSwap}`);
  console.log(`   hx-target elements: ${htmxElements.hxTarget}`);
  console.log(`   Total HTMX attributes: ${htmxElements.total}`);
  console.log(`   ${htmxElements.total > 0 ? '✅ PASS' : '❌ FAIL'} - HTMX elements found`);
  testResults.push({ test: 'HTMX Elements Present', passed: htmxElements.total > 0 });

  // ========================================================================
  // TEST 3: HTMX request/response (if any interactive elements exist)
  // ========================================================================
  console.log("\n4️⃣  Testing HTMX Request Handling...");

  // Look for any clickable HTMX elements
  const htmxButton = await page.$('[hx-get], [hx-post]');

  if (htmxButton) {
    // Track HTMX events
    const htmxEvents = await page.evaluate(() => {
      return new Promise((resolve) => {
        const events = [];
        let timeout;

        const handlers = {
          'htmx:beforeRequest': (e) => events.push({ type: 'beforeRequest', target: e.detail.target.id }),
          'htmx:afterRequest': (e) => events.push({ type: 'afterRequest', status: e.detail.xhr.status }),
          'htmx:beforeSwap': (e) => events.push({ type: 'beforeSwap' }),
          'htmx:afterSwap': (e) => events.push({ type: 'afterSwap' })
        };

        // Add event listeners
        Object.entries(handlers).forEach(([event, handler]) => {
          document.body.addEventListener(event, handler);
        });

        // Find first HTMX element and click it
        const element = document.querySelector('[hx-get], [hx-post]');
        if (element) {
          element.click();

          // Wait for events or timeout
          timeout = setTimeout(() => {
            Object.entries(handlers).forEach(([event, handler]) => {
              document.body.removeEventListener(event, handler);
            });
            resolve(events);
          }, 3000);
        } else {
          resolve([]);
        }
      });
    });

    const hasBeforeRequest = htmxEvents.some(e => e.type === 'beforeRequest');
    const hasAfterRequest = htmxEvents.some(e => e.type === 'afterRequest');
    const requestWorked = hasBeforeRequest && hasAfterRequest;

    console.log(`   HTMX events captured: ${htmxEvents.length}`);
    htmxEvents.forEach(e => {
      console.log(`   - ${e.type}${e.status ? ` (${e.status})` : ''}`);
    });
    console.log(`   ${requestWorked ? '✅ PASS' : '⚠️  SKIP'} - HTMX request cycle`);
    testResults.push({ test: 'HTMX Request Cycle', passed: requestWorked });
  } else {
    console.log(`   ⚠️  SKIP - No interactive HTMX elements found`);
    testResults.push({ test: 'HTMX Request Cycle', passed: true }); // Skip = pass
  }

  // ========================================================================
  // TEST 4: HTMX indicators
  // ========================================================================
  console.log("\n5️⃣  Testing HTMX Indicators...");
  const indicatorsTest = await page.evaluate(() => {
    const hasIndicator = document.querySelector('.htmx-indicator') !== null;
    const hasSwapping = document.querySelector('.htmx-swapping') !== null;
    const hasSettling = document.querySelector('.htmx-settling') !== null;

    return {
      indicator: hasIndicator,
      swapping: hasSwapping,
      settling: hasSettling,
      hasAny: hasIndicator || hasSwapping || hasSettling
    };
  });

  console.log(`   htmx-indicator: ${indicatorsTest.indicator ? '✅' : '⚠️  Not found'}`);
  console.log(`   htmx-swapping: ${indicatorsTest.swapping ? '✅' : '⚠️  Not in use'}`);
  console.log(`   htmx-settling: ${indicatorsTest.settling ? '✅' : '⚠️  Not in use'}`);
  console.log(`   ${indicatorsTest.hasAny ? '✅ PASS' : '⚠️  INFO'} - Indicators configured`);
  testResults.push({ test: 'HTMX Indicators', passed: true }); // Info only

  // ========================================================================
  // 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`);

  if (errors.length === 0) {
    console.log("\n✅ NO CONSOLE ERRORS");
  } else {
    console.log(`\n⚠️  ${errors.length} CONSOLE ERRORS`);
  }

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

  if (failedTests === 0) {
    console.log("🎉 HTMX FUNCTIONALITY VALIDATED!");
  } else {
    console.log("⚠️  SOME TESTS FAILED - See details above");
  }

  console.log("\nBrowser will stay open for manual inspection.");
  console.log("Press Ctrl+C when done.\n");

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

await testHTMX();
