#!/usr/bin/env node
/**
 * Test: Button and Icon Fluid Sizing
 *
 * Verifies that on mobile view (max-width: 900px):
 * - Buttons scale fluidly from 36px (at 380px viewport) to 50px (at 900px viewport)
 * - Icons scale proportionally from 18px to 24px
 * - Icons properly override HTML width/height attributes
 */

import { chromium } from 'playwright';

const TEST_URL = 'http://localhost:1999';
// Use height > width to ensure portrait orientation (avoid landscape breakpoint)
const VIEWPORT_HEIGHT = 1000;

// Expected sizes at different viewport widths based on CSS formulas:
// Buttons: clamp(36px, calc(2.7vw + 25.7px), 50px)
// Icons: clamp(18px, calc(1.15vw + 13.6px), 24px)
function expectedSizes(viewportWidth) {
  const btnCalc = 0.027 * viewportWidth + 25.7;
  const iconCalc = 0.0115 * viewportWidth + 13.6;
  return {
    button: Math.min(50, Math.max(36, btnCalc)),
    icon: Math.min(24, Math.max(18, iconCalc))
  };
}

async function testButtonIconFluidSizing() {
  console.log('🧪 Testing Button and Icon Fluid Sizing');
  console.log('='.repeat(70));

  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 900, height: VIEWPORT_HEIGHT },
    deviceScaleFactor: 1,
  });
  const page = await context.newPage();

  // Disable cache
  await page.route('**/*', (route) => {
    route.continue({
      headers: {
        ...route.request().headers(),
        'Cache-Control': 'no-cache, no-store, must-revalidate',
      },
    });
  });

  try {
    await page.goto(TEST_URL, { waitUntil: 'networkidle' });
    console.log(`✅ Navigated to ${TEST_URL}`);
    await page.waitForTimeout(500);

    const viewportWidths = [900, 700, 500, 380];
    const buttons = [
      { selector: '.cmd-k-btn', name: 'CmdK' },
      { selector: '.download-btn', name: 'Download' },
      { selector: '.print-friendly-btn', name: 'Print' },
      { selector: '.fixed-btn.contact-btn', name: 'Contact' },
      { selector: '.shortcuts-btn', name: 'Shortcuts' },
      { selector: '.color-theme-switcher', name: 'Theme' },
      { selector: '.info-button', name: 'Info' },
      { selector: '.back-to-top', name: 'BackToTop' },
    ];

    let allTestsPassed = true;
    const tolerance = 4; // Allow 4px tolerance for rounding

    for (const width of viewportWidths) {
      await page.setViewportSize({ width, height: VIEWPORT_HEIGHT });
      await page.waitForTimeout(300);

      const expected = expectedSizes(width);
      console.log(`\n📏 Viewport: ${width}px (expected button: ~${Math.round(expected.button)}px, icon: ~${Math.round(expected.icon)}px)`);
      console.log('-'.repeat(70));

      for (const btn of buttons) {
        try {
          const buttonElement = await page.$(btn.selector);
          if (!buttonElement) {
            // Some buttons may be hidden on certain viewports
            continue;
          }

          const isVisible = await buttonElement.isVisible();
          if (!isVisible) {
            continue;
          }

          // Get button bounding box
          const btnBox = await buttonElement.boundingBox();
          if (!btnBox) continue;

          const btnWidth = Math.round(btnBox.width);
          const btnHeight = Math.round(btnBox.height);

          // Get icon inside button
          const iconElement = await buttonElement.$('iconify-icon');
          let iconWidth = 0;
          let iconHeight = 0;

          if (iconElement) {
            const iconBox = await iconElement.boundingBox();
            if (iconBox) {
              iconWidth = Math.round(iconBox.width);
              iconHeight = Math.round(iconBox.height);
            }
          }

          // Check if sizes are within tolerance of expected
          const btnOk = Math.abs(btnWidth - expected.button) <= tolerance;
          const iconOk = iconWidth === 0 || Math.abs(iconWidth - expected.icon) <= tolerance;

          const status = btnOk && iconOk ? '✅' : '❌';

          if (btnOk && iconOk) {
            console.log(`${status} ${btn.name}: button=${btnWidth}x${btnHeight}, icon=${iconWidth}x${iconHeight}`);
          } else {
            console.log(`${status} ${btn.name}: button=${btnWidth}x${btnHeight} (expected ~${Math.round(expected.button)}), icon=${iconWidth}x${iconHeight} (expected ~${Math.round(expected.icon)})`);
            allTestsPassed = false;
          }

        } catch (error) {
          // Button may not exist
        }
      }
    }

    // Test landscape orientation (width > height)
    console.log('\n\n📐 LANDSCAPE ORIENTATION TESTS');
    console.log('='.repeat(70));

    // Landscape viewports: width > height triggers landscape media query
    // Note: At 400x400, width == height so CSS treats it as portrait, not landscape
    const landscapeViewports = [
      { width: 800, height: 400 },  // Clear landscape
      { width: 600, height: 350 },  // Clear landscape
      { width: 500, height: 300 },  // Clear landscape
    ];

    // Landscape formula: clamp(32px, calc(2.2vw + 19.6px), 40px) for buttons
    // clamp(16px, calc(1.1vw + 9.8px), 20px) for icons
    function expectedLandscapeSizes(viewportWidth) {
      const btnCalc = 0.022 * viewportWidth + 19.6;
      const iconCalc = 0.011 * viewportWidth + 9.8;
      return {
        button: Math.min(40, Math.max(32, btnCalc)),
        icon: Math.min(20, Math.max(16, iconCalc))
      };
    }

    for (const viewport of landscapeViewports) {
      await page.setViewportSize({ width: viewport.width, height: viewport.height });
      await page.waitForTimeout(300);

      const expected = expectedLandscapeSizes(viewport.width);
      console.log(`\n📏 Landscape ${viewport.width}x${viewport.height} (expected button: ~${Math.round(expected.button)}px, icon: ~${Math.round(expected.icon)}px)`);
      console.log('-'.repeat(70));

      for (const btn of buttons) {
        try {
          const buttonElement = await page.$(btn.selector);
          if (!buttonElement) continue;
          const isVisible = await buttonElement.isVisible();
          if (!isVisible) continue;

          const btnBox = await buttonElement.boundingBox();
          if (!btnBox) continue;

          const btnWidth = Math.round(btnBox.width);
          const btnHeight = Math.round(btnBox.height);

          const iconElement = await buttonElement.$('iconify-icon');
          let iconWidth = 0;
          if (iconElement) {
            const iconBox = await iconElement.boundingBox();
            if (iconBox) iconWidth = Math.round(iconBox.width);
          }

          const btnOk = Math.abs(btnWidth - expected.button) <= tolerance;
          const iconOk = iconWidth === 0 || Math.abs(iconWidth - expected.icon) <= tolerance;
          const status = btnOk && iconOk ? '✅' : '❌';

          if (btnOk && iconOk) {
            console.log(`${status} ${btn.name}: button=${btnWidth}x${btnHeight}, icon=${iconWidth}`);
          } else {
            console.log(`${status} ${btn.name}: button=${btnWidth}x${btnHeight} (expected ~${Math.round(expected.button)}), icon=${iconWidth} (expected ~${Math.round(expected.icon)})`);
            allTestsPassed = false;
          }
        } catch (error) {}
      }
    }

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

    if (allTestsPassed) {
      console.log('\n✅ ALL TESTS PASSED - Button and icon fluid sizing working correctly!');
      console.log('   • Portrait: Buttons 36-50px, Icons 18-24px');
      console.log('   • Landscape: Buttons 32-40px, Icons 16-20px');
    } else {
      console.log('\n❌ SOME TESTS FAILED - Check output above');
    }

    await browser.close();
    process.exit(allTestsPassed ? 0 : 1);

  } catch (error) {
    console.error('\n❌ Test error:', error);
    await browser.close();
    process.exit(1);
  }
}

testButtonIconFluidSizing();
