#!/usr/bin/env bun
/**
 * CMD+K API SCROLL POSITION TEST
 * ==============================
 * Tests the /api/cmd-k endpoint integration with ninja-keys command palette.
 *
 * Tests:
 * 1. API returns valid JSON with experiences, projects, courses
 * 2. ninja-keys receives data from API (not hardcoded)
 * 3. Scroll navigation works for dynamic entries:
 *    - Experience items (e.g., Olympic Broadcasting)
 *    - Project items (e.g., Somos Una Ola)
 *    - Course items (e.g., Codecademy Certifications)
 * 4. Static navigation actions still work (e.g., Skills section)
 *
 * Related: doc/16-CMD-K-API.md
 */

import { chromium } from 'playwright';

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

async function testCmdKScroll() {
  console.log('🎯 CMD+K SCROLL POSITION TEST\n');
  console.log('='.repeat(70));

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

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

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

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

  // Helper function to check if element is in viewport
  async function isElementInViewport(selector) {
    return await page.evaluate((sel) => {
      const el = document.querySelector(sel);
      if (!el) return { found: false };
      const rect = el.getBoundingClientRect();
      return {
        found: true,
        top: rect.top,
        inViewport: rect.top >= 0 && rect.top < window.innerHeight
      };
    }, selector);
  }

  // Helper function to scroll to top
  async function scrollToTop() {
    await page.evaluate(() => window.scrollTo(0, 0));
    await page.waitForTimeout(300);
  }

  // Helper function to invoke ninja-keys action directly by ID
  async function invokeNinjaKeyAction(actionId) {
    const result = await page.evaluate((id) => {
      const nk = document.getElementById('cmd-k-bar');
      if (!nk || !nk.data) return { success: false, reason: 'ninja-keys not found' };

      const action = nk.data.find(a => a.id === id);
      if (!action) return { success: false, reason: `action ${id} not found` };

      if (action.handler) {
        action.handler();
        return { success: true, actionTitle: action.title };
      }
      return { success: false, reason: 'no handler' };
    }, actionId);

    console.log(`      [DEBUG] Action "${actionId}": ${result.success ? 'invoked ' + result.actionTitle : result.reason}`);
    await page.waitForTimeout(1000);
    return result.success;
  }

  // ========================================================================
  // TEST 1: Scroll to Experience item (Olympic Broadcasting)
  // ========================================================================
  console.log("\n2️⃣  Testing scroll to Experience (Olympic Broadcasting)...");
  await scrollToTop();

  const expBefore = await isElementInViewport('#exp-olympic-broadcasting');
  console.log(`   Element found: ${expBefore.found}`);
  console.log(`   Before: Element top position = ${expBefore.top?.toFixed(0) || 'N/A'}`);

  // API now returns exp-olympic-broadcasting as the action ID
  await invokeNinjaKeyAction('exp-olympic-broadcasting');

  const expAfter = await isElementInViewport('#exp-olympic-broadcasting');
  console.log(`   After:  Element top position = ${expAfter.top?.toFixed(0) || 'N/A'}`);

  const expPassed = expBefore.found && expAfter.found && expAfter.inViewport;
  console.log(`   ${expPassed ? '✅ PASS' : '❌ FAIL'} - Scrolled to Olympic Broadcasting`);
  testResults.push({ test: 'Experience - Olympic Broadcasting', passed: expPassed });

  // ========================================================================
  // TEST 2: Scroll to Project item (Somos Una Ola)
  // ========================================================================
  console.log("\n3️⃣  Testing scroll to Project (Somos Una Ola)...");
  await scrollToTop();

  const projBefore = await isElementInViewport('#proj-somos-una-ola');
  console.log(`   Element found: ${projBefore.found}`);
  console.log(`   Before: Element top position = ${projBefore.top?.toFixed(0) || 'N/A'}`);

  // API now returns proj-somos-una-ola as the action ID
  await invokeNinjaKeyAction('proj-somos-una-ola');

  const projAfter = await isElementInViewport('#proj-somos-una-ola');
  console.log(`   After:  Element top position = ${projAfter.top?.toFixed(0) || 'N/A'}`);

  const projPassed = projBefore.found && projAfter.found && projAfter.inViewport;
  console.log(`   ${projPassed ? '✅ PASS' : '❌ FAIL'} - Scrolled to Somos Una Ola`);
  testResults.push({ test: 'Project - Somos Una Ola', passed: projPassed });

  // ========================================================================
  // TEST 3: Scroll to Course item (Codecademy)
  // ========================================================================
  console.log("\n4️⃣  Testing scroll to Course (Codecademy)...");
  await scrollToTop();

  const courseBefore = await isElementInViewport('#course-codecademy-certifications');
  console.log(`   Element found: ${courseBefore.found}`);
  console.log(`   Before: Element top position = ${courseBefore.top?.toFixed(0) || 'N/A'}`);

  // API now returns course-codecademy-certifications as the action ID
  await invokeNinjaKeyAction('course-codecademy-certifications');

  const courseAfter = await isElementInViewport('#course-codecademy-certifications');
  console.log(`   After:  Element top position = ${courseAfter.top?.toFixed(0) || 'N/A'}`);

  const coursePassed = courseBefore.found && courseAfter.found && courseAfter.inViewport;
  console.log(`   ${coursePassed ? '✅ PASS' : '❌ FAIL'} - Scrolled to Codecademy Certifications`);
  testResults.push({ test: 'Course - Codecademy', passed: coursePassed });

  // ========================================================================
  // TEST 4: Scroll to section (Skills)
  // ========================================================================
  console.log("\n5️⃣  Testing scroll to Section (Skills)...");
  await scrollToTop();

  const skillsBefore = await isElementInViewport('#skills');
  console.log(`   Element found: ${skillsBefore.found}`);
  console.log(`   Before: Element top position = ${skillsBefore.top?.toFixed(0) || 'N/A'}`);

  await invokeNinjaKeyAction('nav-skills');

  const skillsAfter = await isElementInViewport('#skills');
  console.log(`   After:  Element top position = ${skillsAfter.top?.toFixed(0) || 'N/A'}`);

  const skillsPassed = skillsBefore.found && skillsAfter.found && skillsAfter.inViewport;
  console.log(`   ${skillsPassed ? '✅ PASS' : '❌ FAIL'} - Scrolled to Skills section`);
  testResults.push({ test: 'Section - Skills', passed: skillsPassed });

  // ========================================================================
  // 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 FOUND:\n`);
    errors.forEach((err, i) => {
      console.log(`${i + 1}. ${err}`);
    });
  }

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

  if (failedTests === 0 && errors.length === 0) {
    console.log("🎉 ALL CMD+K SCROLL TESTS PASSED!");
  } else {
    console.log("⚠️  SOME TESTS FAILED - See details above");
  }

  // Auto-close after tests if HEADLESS env is set, otherwise keep open
  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 testCmdKScroll();
