import { test, expect } from '@playwright/test';

test.describe('Input Validation and XSS Prevention (US-89)', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/');
    // Accept any cookie consent if present
    const cookieButton = page.locator('button:has-text("Accept")').first();
    if (await cookieButton.isVisible({ timeout: 1000 }).catch(() => false)) {
      await cookieButton.click();
    }
  });

  test.describe('Flight Search - Valid Input Handling', () => {
    test('should accept valid Cyrillic city names', async ({ page }) => {
      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();

      // Enter valid city name
      await departureInput.fill('Москва');

      const inputValue = await departureInput.inputValue();
      expect(inputValue).toBe('Москва');
    });

    test('should accept valid Latin city names', async ({ page }) => {
      const arrivalContainer = page.locator('[data-testid="filter-route-arrival-input"]');
      const arrivalInput = arrivalContainer.locator('input').first();

      // Enter valid city name
      await arrivalInput.fill('Paris');

      const inputValue = await arrivalInput.inputValue();
      expect(inputValue).toBe('Paris');
    });

    test('should trim whitespace from city input', async ({ page }) => {
      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();

      // Enter city with extra whitespace
      await departureInput.fill('  Москва  ');
      await departureInput.blur();

      const inputValue = await departureInput.inputValue();
      // After sanitization, whitespace should be trimmed
      expect(inputValue.trim()).toBe('Москва');
    });
  });

  test.describe('No Console Errors on Valid Input', () => {
    test('should not produce XSS-related console errors when handling valid input', async ({
      page,
    }) => {
      // Listen for console errors that indicate XSS attempts
      const xssErrors: string[] = [];
      page.on('console', (msg) => {
        const text = msg.text();
        if (
          msg.type() === 'error' &&
          (text.includes('script') || text.includes('xss') || text.includes('alert'))
        ) {
          xssErrors.push(text);
        }
      });

      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();

      // Enter valid city names
      const testInputs = ['Москва', 'Paris', 'London'];

      for (const input of testInputs) {
        await departureInput.clear();
        await departureInput.fill(input);
        await departureInput.blur();
        await page.waitForTimeout(50);
      }

      // Should not have any XSS-related console errors
      expect(xssErrors).toHaveLength(0);
    });
  });

  test.describe('XSS Attack Prevention', () => {
    test('should not execute injected script tags', async ({ page }) => {
      let scriptExecuted = false;
      page.on('dialog', () => {
        scriptExecuted = true;
      });

      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();

      // Try to inject script
      await departureInput.fill('<script>alert("xss")</script>');
      await departureInput.blur();
      await page.waitForTimeout(200);

      // Alert dialog should not appear
      expect(scriptExecuted).toBe(false);
    });

    test('should not execute event handler injections', async ({ page }) => {
      let eventTriggered = false;
      page.on('dialog', () => {
        eventTriggered = true;
      });

      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();

      // Try event handler injection via attribute
      await departureInput.fill('City" onload="alert(1)');
      await departureInput.blur();
      await page.waitForTimeout(200);

      // Event should not fire
      expect(eventTriggered).toBe(false);
    });

    test('should not execute onerror handlers in IMG tags', async ({ page }) => {
      let errorTriggered = false;
      page.on('dialog', () => {
        errorTriggered = true;
      });

      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();

      // Try to inject img with onerror
      await departureInput.fill('<img src=invalid onerror="alert(1)">');
      await departureInput.blur();
      await page.waitForTimeout(200);

      // Alert should not fire
      expect(errorTriggered).toBe(false);
    });
  });

  test.describe('Search Functionality Preserved', () => {
    test('should preserve functionality with valid city input', async ({ page }) => {
      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();
      const arrivalContainer = page.locator('[data-testid="filter-route-arrival-input"]');
      const arrivalInput = arrivalContainer.locator('input').first();

      // Enter valid cities
      await departureInput.fill('Москва');
      await arrivalInput.fill('Paris');

      expect(await departureInput.inputValue()).toBe('Москва');
      expect(await arrivalInput.inputValue()).toBe('Paris');
    });

    test('should allow search button to be clicked after valid input', async ({ page }) => {
      const departureContainer = page.locator('[data-testid="filter-route-departure-input"]');
      const departureInput = departureContainer.locator('input').first();
      const arrivalContainer = page.locator('[data-testid="filter-route-arrival-input"]');
      const arrivalInput = arrivalContainer.locator('input').first();
      const searchBtn = page.locator('[data-testid="filter-route-search"]');

      // Enter valid cities
      await departureInput.fill('Москва');
      await arrivalInput.fill('Paris');

      // Verify search button is visible and clickable
      expect(await searchBtn.isVisible()).toBe(true);
      expect(await searchBtn.isEnabled()).toBe(true);
    });
  });
});
