/**
 * Breakpoint Edge Case Tests
 *
 * Tests layout behavior at CSS breakpoint boundaries to catch
 * edge cases where layout transitions between mobile, tablet, and desktop.
 *
 * IMPORTANT: These tests create new browser contexts with specific viewports,
 * so they should only run on Desktop Chrome/Firefox (not mobile projects).
 *
 * Breakpoints tested:
 * - 767px: Mobile max (mobile nav visible, sidebar hidden)
 * - 768px: Tablet min (mobile nav hidden, sidebar 60px)
 * - 991px: Tablet max (sidebar 60px)
 * - 992px: Desktop min (sidebar 240px)
 * - 380px: Extra small (single column, icons hidden)
 */

import { test, expect } from '@playwright/test';
const { BREAKPOINTS, PAGES } = require('./helpers/mobile-utils');

// These tests create new browser contexts with specific viewports
// Skip on mobile projects as they have fixed viewports
test.beforeEach(async ({ isMobile }, testInfo) => {
  if (isMobile || testInfo.project.name.includes('iPhone') || testInfo.project.name.includes('iPad')) {
    test.skip();
  }
});

test.describe('Breakpoint Edge Cases - Mobile Nav Boundary', () => {
  // Split into individual tests for better isolation and parallelization
  test('Mobile nav visible at 766px', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 766, height: 800 },
      isMobile: true,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    const mobileNav = page.locator('.ldr-mobile-bottom-nav');
    await expect(mobileNav, 'Mobile nav visible at 766px').toBeVisible();
    await context.close();
  });

  test('Mobile nav visible at 767px (mobile max)', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 767, height: 800 },
      isMobile: true,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    const mobileNav = page.locator('.ldr-mobile-bottom-nav');
    await expect(mobileNav, 'Mobile nav visible at 767px').toBeVisible();
    await context.close();
  });

  test('Mobile nav hidden at 768px (tablet min)', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 768, height: 800 },
      isMobile: false,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    const mobileNav = page.locator('.ldr-mobile-bottom-nav');
    await expect(mobileNav, 'Mobile nav hidden at 768px').not.toBeVisible();
    await context.close();
  });

  test('Mobile nav hidden at 769px', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 769, height: 800 },
      isMobile: false,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    const mobileNav = page.locator('.ldr-mobile-bottom-nav');
    await expect(mobileNav, 'Mobile nav hidden at 769px').not.toBeVisible();
    await context.close();
  });
});

test.describe('Breakpoint Edge Cases - Sidebar Width', () => {
  test('Sidebar width at breakpoints', async ({ browser }) => {
    const tests = [
      { width: 767, expectedSidebar: 0, desc: 'Hidden on mobile' },
      { width: 850, expectedSidebar: 60, desc: 'Collapsed on tablet' },
      { width: 992, expectedSidebar: 240, desc: 'Full on desktop' },
    ];

    for (const { width, expectedSidebar, desc } of tests) {
      const context = await browser.newContext({
        viewport: { width, height: 800 },
        isMobile: width <= BREAKPOINTS.MOBILE_MAX,
      });
      const page = await context.newPage();
      await page.goto('/');
      await page.waitForLoadState('domcontentloaded');

      const sidebar = page.locator('.ldr-sidebar');

      if (expectedSidebar === 0) {
        // Sidebar should be hidden or have 0 width
        const isVisible = await sidebar.isVisible();
        if (isVisible) {
          const box = await sidebar.boundingBox();
          expect(box?.width ?? 0, `${desc}: Sidebar width at ${width}px`).toBe(0);
        }
      } else {
        const isVisible = await sidebar.isVisible();
        if (isVisible) {
          const box = await sidebar.boundingBox();
          // Allow some tolerance (±5px) for different CSS implementations
          expect(box?.width, `${desc}: Sidebar width at ${width}px`).toBeGreaterThanOrEqual(expectedSidebar - 5);
          expect(box?.width, `${desc}: Sidebar width at ${width}px`).toBeLessThanOrEqual(expectedSidebar + 5);
        }
      }

      await context.close();
    }
  });
});

test.describe('Breakpoint Edge Cases - No Overflow', () => {
  const pagesToTest = ['/', '/history/', '/settings/', '/metrics/'];
  const widthsToTest = [380, 767, 768, 991];

  for (const path of pagesToTest) {
    for (const width of widthsToTest) {
      test(`${path} no overflow at ${width}px`, async ({ browser }) => {
        const context = await browser.newContext({
          viewport: { width, height: 800 },
          isMobile: width <= BREAKPOINTS.MOBILE_MAX,
          hasTouch: true,
        });
        const page = await context.newPage();
        await page.goto(path);
        await page.waitForLoadState('domcontentloaded');

        // Wait for settings spinner to disappear if on settings page
        if (path === '/settings/') {
          await page.waitForSelector('.ldr-loading-spinner', { state: 'hidden', timeout: 10000 }).catch(() => {});
        }

        const hasOverflow = await page.evaluate(() =>
          document.documentElement.scrollWidth > window.innerWidth
        );

        expect(hasOverflow, `No horizontal overflow at ${width}px`).toBe(false);
        await context.close();
      });
    }
  }
});

test.describe('Breakpoint Edge Cases - Content Layout', () => {
  test('Extra small (380px) shows single column layout', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 380, height: 800 },
      isMobile: true,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    // Mobile nav should be visible
    const mobileNav = page.locator('.ldr-mobile-bottom-nav');
    await expect(mobileNav, 'Mobile nav visible at 380px').toBeVisible();

    // No horizontal overflow
    const hasOverflow = await page.evaluate(() =>
      document.documentElement.scrollWidth > window.innerWidth
    );
    expect(hasOverflow, 'No overflow at 380px').toBe(false);

    await context.close();
  });

  test('Tablet boundary (768px) shows collapsed sidebar', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 768, height: 800 },
      isMobile: false,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    // Mobile nav should NOT be visible
    const mobileNav = page.locator('.ldr-mobile-bottom-nav');
    await expect(mobileNav, 'Mobile nav hidden at 768px').not.toBeVisible();

    // Sidebar should be visible (collapsed)
    const sidebar = page.locator('.ldr-sidebar');
    const sidebarVisible = await sidebar.isVisible();
    if (sidebarVisible) {
      const box = await sidebar.boundingBox();
      // Collapsed sidebar is typically around 60px
      expect(box?.width, 'Sidebar collapsed at 768px').toBeLessThanOrEqual(100);
    }

    await context.close();
  });

  test('Desktop boundary (992px) shows full sidebar', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 992, height: 800 },
      isMobile: false,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    // Sidebar should be visible and expanded
    const sidebar = page.locator('.ldr-sidebar');
    const sidebarVisible = await sidebar.isVisible();
    if (sidebarVisible) {
      const box = await sidebar.boundingBox();
      // Full sidebar is typically around 240px
      expect(box?.width, 'Sidebar expanded at 992px').toBeGreaterThanOrEqual(200);
    }

    await context.close();
  });
});

test.describe('Breakpoint Edge Cases - Touch Targets at Boundaries', () => {
  test('Touch targets adequate at 767px (mobile max)', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 767, height: 800 },
      isMobile: true,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    // Check mobile nav touch targets
    const navItems = page.locator('.ldr-mobile-bottom-nav a, .ldr-mobile-bottom-nav button');
    const count = await navItems.count();

    for (let i = 0; i < count; i++) {
      const item = navItems.nth(i);
      if (await item.isVisible()) {
        const box = await item.boundingBox();
        expect(box?.height, `Nav item ${i} height >= 44px at 767px`).toBeGreaterThanOrEqual(44);
        expect(box?.width, `Nav item ${i} width >= 44px at 767px`).toBeGreaterThanOrEqual(44);
      }
    }

    await context.close();
  });

  test('Touch targets adequate at 768px (tablet min)', async ({ browser }) => {
    const context = await browser.newContext({
      viewport: { width: 768, height: 800 },
      isMobile: false,
      hasTouch: true,
    });
    const page = await context.newPage();
    await page.goto('/');
    await page.waitForLoadState('domcontentloaded');

    // Check sidebar nav touch targets (if visible)
    const sidebarItems = page.locator('.ldr-sidebar a, .ldr-sidebar button');
    const count = await sidebarItems.count();

    for (let i = 0; i < Math.min(count, 10); i++) {
      const item = sidebarItems.nth(i);
      if (await item.isVisible()) {
        const box = await item.boundingBox();
        // Sidebar items should still be touchable
        if (box && box.height > 0 && box.width > 0) {
          expect(box.height, `Sidebar item ${i} height >= 40px at 768px`).toBeGreaterThanOrEqual(40);
        }
      }
    }

    await context.close();
  });
});
