/**
 * Settings Page Mobile Tests
 *
 * Tests for the settings page on mobile devices.
 * The settings page uses a tab-based navigation within a single page.
 *
 * Tabs tested:
 * 1. All Settings - Default tab
 * 2. Language Models - LLM configuration
 * 3. Search Engines - Search configuration
 * 4. Reports - Report settings
 * 5. Application - App settings
 * 6. Notifications - Notification settings
 * 7. Domain Classification - Domain settings
 */

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

// Settings tabs configuration (based on actual tab structure)
const SETTINGS_TABS = [
  { selector: '[data-tab="all"]', name: 'All Settings', dataTab: 'all' },
  { selector: '[data-tab="llm"]', name: 'Language Models', dataTab: 'llm' },
  { selector: '[data-tab="search"]', name: 'Search Engines', dataTab: 'search' },
  { selector: '[data-tab="report"]', name: 'Reports', dataTab: 'report' },
  { selector: '[data-tab="app"]', name: 'Application', dataTab: 'app' },
  { selector: '[data-tab="notifications"]', name: 'Notifications', dataTab: 'notifications' },
  { selector: '[data-tab="domains"]', name: 'Domain Classification', dataTab: 'domains' },
];

// ============================================
// SETTINGS PAGE LOAD TESTS
// ============================================

test.describe('Settings Page - Mobile', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/settings/');
    await page.waitForLoadState('domcontentloaded');
    // Wait for settings to load
    await page.waitForSelector('.ldr-loading-spinner', { state: 'hidden', timeout: 15000 }).catch(() => {});
  });

  test('page loads without errors', async ({ page }) => {
    // The page is already loaded by beforeEach - just verify no JS errors
    const errors = [];
    page.on('console', (msg) => {
      if (msg.type() === 'error') {
        errors.push(msg.text());
      }
    });

    // Trigger a small interaction to capture any runtime errors
    await page.evaluate(() => window.scrollTo(0, 100));
    await page.waitForTimeout(300);

    const criticalErrors = errors.filter(
      (err) =>
        !err.includes('favicon') &&
        !err.includes('404') &&
        !err.includes('Failed to load resource')
    );

    expect(criticalErrors.length).toBe(0);
  });

  test('has no horizontal overflow', async ({ page }) => {
    const hasOverflow = await page.evaluate(() =>
      document.documentElement.scrollWidth > window.innerWidth
    );

    expect(hasOverflow, 'Settings page should have no horizontal overflow').toBe(false);
  });

  test('shows mobile nav on phone', async ({ page, isMobile }, testInfo) => {
    if (!isMobile) {
      test.skip();
      return;
    }

    const isTablet = testInfo.project.name.includes('iPad');
    if (isTablet) {
      test.skip();
      return;
    }

    const mobileNav = page.locator(MOBILE_NAV_SELECTOR);
    await expect(mobileNav, 'Mobile nav should be visible').toBeVisible();
  });

  test('displays settings form', async ({ page }) => {
    const form = page.locator('form#settings-form, .ldr-settings-form').first();
    await expect(form).toBeVisible();
  });

  test('displays settings tabs', async ({ page }) => {
    const tabsContainer = page.locator('.ldr-settings-tabs');
    await expect(tabsContainer).toBeVisible();
  });

  test('has search input', async ({ page }) => {
    const searchInput = page.locator('#settings-search, .ldr-search-input').first();
    await expect(searchInput).toBeVisible();
  });

});

// ============================================
// SETTINGS TAB NAVIGATION TESTS
// ============================================

test.describe('Settings Tab Navigation', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/settings/');
    await page.waitForLoadState('domcontentloaded');
    await page.waitForSelector('.ldr-loading-spinner', { state: 'hidden', timeout: 15000 }).catch(() => {});
  });

  test('all tabs are visible', async ({ page }) => {
    for (const tab of SETTINGS_TABS) {
      const tabElement = page.locator(tab.selector);
      const isVisible = await tabElement.isVisible().catch(() => false);

      // Tabs might be scrollable on mobile, so just check they exist in DOM
      if (!isVisible) {
        const exists = (await tabElement.count()) > 0;
        expect(exists, `Tab ${tab.name} should exist`).toBe(true);
      }
    }
  });

  test('default tab is active', async ({ page }) => {
    const allSettingsTab = page.locator('[data-tab="all"]');
    await expect(allSettingsTab).toHaveClass(/active/);
  });

  test('can click through tabs', async ({ page }) => {
    // Skip first tab (already active) and test clicking others
    for (const tab of SETTINGS_TABS.slice(1, 3)) {
      const tabElement = page.locator(tab.selector);

      // Scroll tab into view if needed
      await tabElement.scrollIntoViewIfNeeded().catch(() => {});

      if (await tabElement.isVisible()) {
        await tabElement.click();
        await expect(tabElement).toHaveClass(/active/);
      }
    }
  });

  test('tabs are horizontally scrollable on mobile', async ({ page, isMobile }) => {
    if (!isMobile) {
      test.skip();
      return;
    }

    const tabsContainer = page.locator('.ldr-settings-tabs');
    const box = await tabsContainer.boundingBox();

    // Check tabs container exists
    expect(box).not.toBeNull();

    // The tabs container should be scrollable or all tabs visible
    const scrollWidth = await tabsContainer.evaluate((el) => el.scrollWidth);
    const clientWidth = await tabsContainer.evaluate((el) => el.clientWidth);

    // Either all tabs fit, or container is scrollable
    expect(scrollWidth >= clientWidth).toBe(true);
  });
});

// ============================================
// SETTINGS FORM MOBILE TESTS
// ============================================

test.describe('Settings Form - Mobile', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/settings/');
    await page.waitForLoadState('domcontentloaded');
    await page.waitForSelector('.ldr-loading-spinner', { state: 'hidden', timeout: 15000 }).catch(() => {});
  });

  test('form inputs have adequate size', async ({ page, isMobile }, testInfo) => {
    if (!isMobile) {
      test.skip();
      return;
    }

    const isTablet = testInfo.project.name.includes('iPad');
    if (isTablet) {
      test.skip();
      return;
    }

    const inputs = page.locator(
      '#settings-form input:visible, #settings-form select:visible, #settings-form textarea:visible'
    );
    const inputCount = await inputs.count();

    let tooSmallInputs = 0;
    for (let i = 0; i < Math.min(inputCount, 10); i++) {
      const input = inputs.nth(i);
      const box = await input.boundingBox().catch(() => null);

      if (box && (box.height < 32 || box.width < 44)) {
        tooSmallInputs++;
      }
    }

    // Allow up to 2 small inputs (some toggle switches may be small)
    expect(tooSmallInputs, 'Settings should have properly sized form inputs').toBeLessThan(3);
  });

  test('has adequate touch targets', async ({ page, isMobile }, testInfo) => {
    if (!isMobile) {
      test.skip();
      return;
    }

    const isTablet = testInfo.project.name.includes('iPad');
    if (isTablet) {
      test.skip();
      return;
    }

    const smallTargets = await page.evaluate((MIN_SIZE) => {
      const elements = document.querySelectorAll(
        '#settings-form button, #settings-form a, #settings-form input, #settings-form select, .ldr-settings-tabs .ldr-settings-tab'
      );
      const issues = [];

      elements.forEach((el) => {
        const rect = el.getBoundingClientRect();
        const style = window.getComputedStyle(el);

        if (style.display === 'none' || style.visibility === 'hidden') return;
        if (rect.width === 0 || rect.height === 0) return;
        if (rect.top > window.innerHeight || rect.bottom < 0) return;

        if (rect.width < MIN_SIZE || rect.height < MIN_SIZE) {
          issues.push({
            tag: el.tagName.toLowerCase(),
            class: el.className?.toString().slice(0, 50),
            size: `${Math.round(rect.width)}x${Math.round(rect.height)}`,
          });
        }
      });

      return issues;
    }, MIN_TOUCH_TARGET);

    // Allow up to 3 small elements
    expect(smallTargets.length, 'Settings should have adequate touch targets').toBeLessThan(4);
  });

  test('content not hidden behind mobile nav', async ({ page, isMobile }, testInfo) => {
    if (!isMobile) {
      test.skip();
      return;
    }

    const isTablet = testInfo.project.name.includes('iPad');
    if (isTablet) {
      test.skip();
      return;
    }

    // Scroll to bottom
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(200);

    const result = await page.evaluate((navSelector) => {
      const mobileNav = document.querySelector(navSelector);
      if (!mobileNav) return { hasNav: false };

      const navStyle = window.getComputedStyle(mobileNav);
      if (navStyle.display === 'none') return { hasNav: false };

      const navRect = mobileNav.getBoundingClientRect();
      const interactiveElements = document.querySelectorAll(
        '#settings-form button, #settings-form a, #settings-form input, #settings-form select'
      );
      const hiddenElements = [];

      interactiveElements.forEach((el) => {
        const rect = el.getBoundingClientRect();
        const style = window.getComputedStyle(el);

        if (style.display === 'none' || style.visibility === 'hidden') return;
        if (rect.width === 0 || rect.height === 0) return;

        const OVERLAP_TOLERANCE = 5;
        if (rect.bottom > navRect.top + OVERLAP_TOLERANCE && rect.top < navRect.bottom) {
          if (!mobileNav.contains(el)) {
            hiddenElements.push({
              tag: el.tagName.toLowerCase(),
              text: (el.textContent || '').trim().slice(0, 30),
            });
          }
        }
      });

      return { hasNav: true, hiddenElements };
    }, MOBILE_NAV_SELECTOR);

    expect(
      result.hiddenElements?.length || 0,
      'Settings should have no elements behind mobile nav'
    ).toBe(0);
  });
});

// ============================================
// INDIVIDUAL TAB CONTENT TESTS
// ============================================

test.describe('Settings Tab Content', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/settings/');
    await page.waitForLoadState('domcontentloaded');
    await page.waitForSelector('.ldr-loading-spinner', { state: 'hidden', timeout: 15000 }).catch(() => {});
  });

  test('All Settings tab shows content', async ({ page }) => {
    const allTab = page.locator('[data-tab="all"]');
    await allTab.click();
    await expect(allTab).toHaveClass(/active/);

    // Settings content should be visible
    const content = page.locator('#settings-content');
    await expect(content).toBeVisible();
  });

  test('Language Models tab shows content', async ({ page }) => {
    const llmTab = page.locator('[data-tab="llm"]');
    await llmTab.scrollIntoViewIfNeeded().catch(() => {});

    if (await llmTab.isVisible()) {
      await llmTab.click();
      await expect(llmTab).toHaveClass(/active/);

      // Should filter to show LLM settings
      const content = page.locator('#settings-content');
      await expect(content).toBeVisible();
    }
  });

  test('Search Engines tab shows content', async ({ page }) => {
    const searchTab = page.locator('[data-tab="search"]');
    await searchTab.scrollIntoViewIfNeeded().catch(() => {});

    if (await searchTab.isVisible()) {
      await searchTab.click();
      await expect(searchTab).toHaveClass(/active/);

      const content = page.locator('#settings-content');
      await expect(content).toBeVisible();
    }
  });
});

// ============================================
// SETTINGS SEARCH FUNCTIONALITY
// ============================================

test.describe('Settings Search', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/settings/');
    await page.waitForLoadState('domcontentloaded');
    await page.waitForSelector('.ldr-loading-spinner', { state: 'hidden', timeout: 15000 }).catch(() => {});
  });

  test('search input accepts text', async ({ page }) => {
    const searchInput = page.locator('#settings-search');
    await expect(searchInput).toBeVisible();

    await searchInput.fill('model');
    const value = await searchInput.inputValue();
    expect(value).toBe('model');
  });

  test('search input clears with empty string', async ({ page }) => {
    const searchInput = page.locator('#settings-search');

    await searchInput.fill('test');
    await searchInput.fill('');

    const value = await searchInput.inputValue();
    expect(value).toBe('');
  });
});
