/**
 * QA-FILTER-021: Filters Tests
 * 
 * E2E Test Suite for Advanced Filters on Scenarios Page
 * - Region filter
 * - Cost filter
 * - Status filter
 * - Combined filters
 * - URL sync with query params
 * - Clear filters
 * - Search by name
 */

import { test, expect } from '@playwright/test';
import { 
  navigateTo, 
  waitForLoading, 
  createScenarioViaAPI,
  deleteScenarioViaAPI,
  startScenarioViaAPI,
  generateTestScenarioName,
} from './utils/test-helpers';
import {
  generateTestUser,
  loginUserViaUI,
  registerUserViaAPI,
} from './utils/auth-helpers';
import { newScenarioData } from './fixtures/test-scenarios';

// Test data storage
let testUser: { email: string; password: string; fullName: string } | null = null;
let accessToken: string | null = null;
const createdScenarioIds: string[] = [];

// Test scenario names for cleanup
const scenarioNames = {
  usEast: generateTestScenarioName('Filter-US-East'),
  euWest: generateTestScenarioName('Filter-EU-West'),
  apSouth: generateTestScenarioName('Filter-AP-South'),
  lowCost: generateTestScenarioName('Filter-Low-Cost'),
  highCost: generateTestScenarioName('Filter-High-Cost'),
  running: generateTestScenarioName('Filter-Running'),
  draft: generateTestScenarioName('Filter-Draft'),
  searchMatch: generateTestScenarioName('Filter-Search-Match'),
};

test.describe('QA-FILTER-021: Filters Setup', () => {
  test.beforeAll(async ({ request }) => {
    // Register and login test user
    testUser = generateTestUser('Filters');
    const auth = await registerUserViaAPI(
      request,
      testUser.email,
      testUser.password,
      testUser.fullName
    );
    accessToken = auth.access_token;

    // Create test scenarios with different properties
    const scenarios = [
      { name: scenarioNames.usEast, region: 'us-east-1', status: 'draft' },
      { name: scenarioNames.euWest, region: 'eu-west-1', status: 'draft' },
      { name: scenarioNames.apSouth, region: 'ap-southeast-1', status: 'draft' },
      { name: scenarioNames.searchMatch, region: 'us-west-2', status: 'draft' },
    ];

    for (const scenario of scenarios) {
      const created = await createScenarioViaAPI(request, {
        ...newScenarioData,
        name: scenario.name,
        region: scenario.region,
      });
      createdScenarioIds.push(created.id);
    }
  });

  test.afterAll(async ({ request }) => {
    // Cleanup all created scenarios
    for (const id of createdScenarioIds) {
      try {
        await deleteScenarioViaAPI(request, id);
      } catch {
        // Ignore cleanup errors
      }
    }
  });
});

// ============================================
// TEST SUITE: Region Filter
// ============================================
test.describe('QA-FILTER-021: Region Filter', () => {
  test.beforeEach(async ({ page }) => {
    // Login and navigate
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should apply region filter and update list', async ({ page }) => {
    // Find and open region filter
    const regionFilter = page.getByLabel(/region|select region/i).or(
      page.locator('[data-testid="region-filter"]').or(
        page.getByRole('combobox', { name: /region/i })
      )
    );

    if (!await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Region filter not found');
    }

    // Select US East region
    await regionFilter.click();
    await regionFilter.selectOption?.('us-east-1') || 
      page.getByText('us-east-1').click();

    // Apply filter
    await page.getByRole('button', { name: /apply|filter|search/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify list updates - should show only us-east-1 scenarios
    await expect(page.getByText(scenarioNames.usEast)).toBeVisible();
    await expect(page.getByText(scenarioNames.euWest)).not.toBeVisible();
    await expect(page.getByText(scenarioNames.apSouth)).not.toBeVisible();
  });

  test('should filter by eu-west-1 region', async ({ page }) => {
    const regionFilter = page.getByLabel(/region/i).or(
      page.locator('[data-testid="region-filter"]')
    );

    if (!await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Region filter not found');
    }

    await regionFilter.click();
    await regionFilter.selectOption?.('eu-west-1') || 
      page.getByText('eu-west-1').click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    await expect(page.getByText(scenarioNames.euWest)).toBeVisible();
    await expect(page.getByText(scenarioNames.usEast)).not.toBeVisible();
  });

  test('should show all regions when no filter selected', async ({ page }) => {
    // Ensure no region filter is applied
    const clearButton = page.getByRole('button', { name: /clear|reset/i });
    if (await clearButton.isVisible().catch(() => false)) {
      await clearButton.click();
      await page.waitForLoadState('networkidle');
    }

    // All scenarios should be visible
    await expect(page.getByText(scenarioNames.usEast)).toBeVisible();
    await expect(page.getByText(scenarioNames.euWest)).toBeVisible();
    await expect(page.getByText(scenarioNames.apSouth)).toBeVisible();
  });
});

// ============================================
// TEST SUITE: Cost Filter
// ============================================
test.describe('QA-FILTER-021: Cost Filter', () => {
  test.beforeEach(async ({ page }) => {
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should apply min cost filter', async ({ page }) => {
    const minCostInput = page.getByLabel(/min cost|minimum cost|from cost/i).or(
      page.locator('input[placeholder*="min"], input[name*="min_cost"], [data-testid*="min-cost"]')
    );

    if (!await minCostInput.isVisible().catch(() => false)) {
      test.skip(true, 'Min cost filter not found');
    }

    await minCostInput.fill('10');
    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify filtered results
    await expect(page.locator('table tbody tr')).toHaveCount(await page.locator('table tbody tr').count());
  });

  test('should apply max cost filter', async ({ page }) => {
    const maxCostInput = page.getByLabel(/max cost|maximum cost|to cost/i).or(
      page.locator('input[placeholder*="max"], input[name*="max_cost"], [data-testid*="max-cost"]')
    );

    if (!await maxCostInput.isVisible().catch(() => false)) {
      test.skip(true, 'Max cost filter not found');
    }

    await maxCostInput.fill('100');
    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify results
    await expect(page.locator('table tbody')).toBeVisible();
  });

  test('should apply cost range filter', async ({ page }) => {
    const minCostInput = page.getByLabel(/min cost/i).or(
      page.locator('[data-testid*="min-cost"]')
    );
    const maxCostInput = page.getByLabel(/max cost/i).or(
      page.locator('[data-testid*="max-cost"]')
    );

    if (!await minCostInput.isVisible().catch(() => false) || 
        !await maxCostInput.isVisible().catch(() => false)) {
      test.skip(true, 'Cost range filters not found');
    }

    await minCostInput.fill('5');
    await maxCostInput.fill('50');
    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify results are filtered
    await expect(page.locator('table')).toBeVisible();
  });
});

// ============================================
// TEST SUITE: Status Filter
// ============================================
test.describe('QA-FILTER-021: Status Filter', () => {
  test.beforeEach(async ({ page }) => {
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should filter by draft status', async ({ page }) => {
    const statusFilter = page.getByLabel(/status/i).or(
      page.locator('[data-testid="status-filter"]')
    );

    if (!await statusFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Status filter not found');
    }

    await statusFilter.click();
    await statusFilter.selectOption?.('draft') || 
      page.getByText('draft', { exact: true }).click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify only draft scenarios are shown
    const rows = page.locator('table tbody tr');
    const count = await rows.count();
    
    for (let i = 0; i < count; i++) {
      await expect(rows.nth(i)).toContainText('draft');
    }
  });

  test('should filter by running status', async ({ page }) => {
    const statusFilter = page.getByLabel(/status/i).or(
      page.locator('[data-testid="status-filter"]')
    );

    if (!await statusFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Status filter not found');
    }

    await statusFilter.click();
    await statusFilter.selectOption?.('running') || 
      page.getByText('running', { exact: true }).click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify filtered results
    await expect(page.locator('table')).toBeVisible();
  });
});

// ============================================
// TEST SUITE: Combined Filters
// ============================================
test.describe('QA-FILTER-021: Combined Filters', () => {
  test.beforeEach(async ({ page }) => {
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should combine region and status filters', async ({ page }) => {
    const regionFilter = page.getByLabel(/region/i);
    const statusFilter = page.getByLabel(/status/i);

    if (!await regionFilter.isVisible().catch(() => false) || 
        !await statusFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Required filters not found');
    }

    // Apply region filter
    await regionFilter.click();
    await regionFilter.selectOption?.('us-east-1') || 
      page.getByText('us-east-1').click();

    // Apply status filter
    await statusFilter.click();
    await statusFilter.selectOption?.('draft') || 
      page.getByText('draft').click();

    // Apply filters
    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify combined results
    await expect(page.locator('table tbody')).toBeVisible();
  });

  test('should sync filters with URL query params', async ({ page }) => {
    const regionFilter = page.getByLabel(/region/i);

    if (!await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Region filter not found');
    }

    // Apply filter
    await regionFilter.click();
    await regionFilter.selectOption?.('eu-west-1') || 
      page.getByText('eu-west-1').click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify URL contains query params
    await expect(page).toHaveURL(/region=eu-west-1/);
  });

  test('should parse filters from URL on page load', async ({ page }) => {
    // Navigate with query params
    await navigateTo(page, '/scenarios?region=us-east-1&status=draft');
    await waitForLoading(page);

    // Verify filters are applied
    const url = page.url();
    expect(url).toContain('region=us-east-1');
    expect(url).toContain('status=draft');

    // Verify filtered results
    await expect(page.locator('table')).toBeVisible();
  });

  test('should handle multiple region filters in URL', async ({ page }) => {
    // Navigate with multiple regions
    await navigateTo(page, '/scenarios?region=us-east-1&region=eu-west-1');
    await waitForLoading(page);

    // Verify URL is preserved
    await expect(page).toHaveURL(/region=/);
  });
});

// ============================================
// TEST SUITE: Clear Filters
// ============================================
test.describe('QA-FILTER-021: Clear Filters', () => {
  test.beforeEach(async ({ page }) => {
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should clear all filters and restore full list', async ({ page }) => {
    // Apply a filter first
    const regionFilter = page.getByLabel(/region/i);

    if (!await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Region filter not found');
    }

    await regionFilter.click();
    await regionFilter.selectOption?.('us-east-1') || 
      page.getByText('us-east-1').click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Get filtered count
    const filteredCount = await page.locator('table tbody tr').count();

    // Clear filters
    const clearButton = page.getByRole('button', { name: /clear|reset|clear filters/i });
    if (!await clearButton.isVisible().catch(() => false)) {
      test.skip(true, 'Clear filters button not found');
    }

    await clearButton.click();
    await page.waitForLoadState('networkidle');

    // Verify all scenarios are visible
    await expect(page.getByText(scenarioNames.usEast)).toBeVisible();
    await expect(page.getByText(scenarioNames.euWest)).toBeVisible();
    await expect(page.getByText(scenarioNames.apSouth)).toBeVisible();

    // Verify URL is cleared
    await expect(page).toHaveURL(/\/scenarios$/);
  });

  test('should clear individual filter', async ({ page }) => {
    // Apply filters
    const regionFilter = page.getByLabel(/region/i);

    if (!await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Region filter not found');
    }

    await regionFilter.click();
    await regionFilter.selectOption?.('us-east-1');
    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Clear region filter specifically
    const regionClear = page.locator('[data-testid="clear-region"]').or(
      page.locator('[aria-label*="clear region"]')
    );

    if (await regionClear.isVisible().catch(() => false)) {
      await regionClear.click();
      await page.waitForLoadState('networkidle');

      // Verify filter cleared
      await expect(page.locator('table tbody')).toBeVisible();
    }
  });

  test('should clear filters on page refresh if not persisted', async ({ page }) => {
    // Apply filter
    const regionFilter = page.getByLabel(/region/i);

    if (!await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Region filter not found');
    }

    await regionFilter.click();
    await regionFilter.selectOption?.('us-east-1') || 
      page.getByText('us-east-1').click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Refresh without query params
    await page.goto('/scenarios');
    await waitForLoading(page);

    // All scenarios should be visible
    await expect(page.locator('table tbody tr')).toHaveCount(
      await page.locator('table tbody tr').count()
    );
  });
});

// ============================================
// TEST SUITE: Search by Name
// ============================================
test.describe('QA-FILTER-021: Search by Name', () => {
  test.beforeEach(async ({ page }) => {
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should search scenarios by name', async ({ page }) => {
    const searchInput = page.getByPlaceholder(/search|search by name/i).or(
      page.getByLabel(/search/i).or(
        page.locator('input[type="search"], [data-testid="search-input"]')
      )
    );

    if (!await searchInput.isVisible().catch(() => false)) {
      test.skip(true, 'Search input not found');
    }

    // Search for specific scenario
    await searchInput.fill('US-East');
    await page.waitForTimeout(500); // Debounce wait

    // Verify search results
    await expect(page.getByText(scenarioNames.usEast)).toBeVisible();
  });

  test('should filter results with partial name match', async ({ page }) => {
    const searchInput = page.getByPlaceholder(/search/i).or(
      page.locator('[data-testid="search-input"]')
    );

    if (!await searchInput.isVisible().catch(() => false)) {
      test.skip(true, 'Search input not found');
    }

    // Partial search
    await searchInput.fill('Filter-US');
    await page.waitForTimeout(500);

    // Should match US scenarios
    await expect(page.getByText(scenarioNames.usEast)).toBeVisible();
  });

  test('should show no results for non-matching search', async ({ page }) => {
    const searchInput = page.getByPlaceholder(/search/i).or(
      page.locator('[data-testid="search-input"]')
    );

    if (!await searchInput.isVisible().catch(() => false)) {
      test.skip(true, 'Search input not found');
    }

    // Search for non-existent scenario
    await searchInput.fill('xyz-non-existent-scenario-12345');
    await page.waitForTimeout(500);

    // Verify no results or empty state
    const rows = page.locator('table tbody tr');
    const count = await rows.count();
    
    if (count > 0) {
      await expect(page.getByText(/no results|no.*found|empty/i).first()).toBeVisible();
    }
  });

  test('should combine search with other filters', async ({ page }) => {
    const searchInput = page.getByPlaceholder(/search/i).or(
      page.locator('[data-testid="search-input"]')
    );
    const regionFilter = page.getByLabel(/region/i);

    if (!await searchInput.isVisible().catch(() => false) || 
        !await regionFilter.isVisible().catch(() => false)) {
      test.skip(true, 'Required filters not found');
    }

    // Apply search
    await searchInput.fill('Filter');
    await page.waitForTimeout(500);

    // Apply region filter
    await regionFilter.click();
    await regionFilter.selectOption?.('us-east-1') || 
      page.getByText('us-east-1').click();

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify combined results
    await expect(page.locator('table tbody')).toBeVisible();
  });

  test('should clear search and show all results', async ({ page }) => {
    const searchInput = page.getByPlaceholder(/search/i).or(
      page.locator('[data-testid="search-input"]')
    );

    if (!await searchInput.isVisible().catch(() => false)) {
      test.skip(true, 'Search input not found');
    }

    // Apply search
    await searchInput.fill('US-East');
    await page.waitForTimeout(500);

    // Clear search
    const clearButton = page.locator('[data-testid="clear-search"]').or(
      page.getByRole('button', { name: /clear/i })
    );

    if (await clearButton.isVisible().catch(() => false)) {
      await clearButton.click();
    } else {
      await searchInput.fill('');
    }

    await page.waitForTimeout(500);

    // Verify all scenarios visible
    await expect(page.locator('table tbody')).toBeVisible();
  });
});

// ============================================
// TEST SUITE: Date Range Filter
// ============================================
test.describe('QA-FILTER-021: Date Range Filter', () => {
  test.beforeEach(async ({ page }) => {
    await loginUserViaUI(page, testUser!.email, testUser!.password);
    await navigateTo(page, '/scenarios');
    await waitForLoading(page);
  });

  test('should filter by created date range', async ({ page }) => {
    const dateFrom = page.getByLabel(/from|start date|date from/i).or(
      page.locator('input[type="date"]').first()
    );

    if (!await dateFrom.isVisible().catch(() => false)) {
      test.skip(true, 'Date filter not found');
    }

    const today = new Date().toISOString().split('T')[0];
    await dateFrom.fill(today);

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    // Verify results
    await expect(page.locator('table tbody')).toBeVisible();
  });

  test('should filter by date range with from and to', async ({ page }) => {
    const dateFrom = page.getByLabel(/from|start date/i);
    const dateTo = page.getByLabel(/to|end date/i);

    if (!await dateFrom.isVisible().catch(() => false) || 
        !await dateTo.isVisible().catch(() => false)) {
      test.skip(true, 'Date range filters not found');
    }

    const today = new Date();
    const yesterday = new Date(today);
    yesterday.setDate(yesterday.getDate() - 1);

    await dateFrom.fill(yesterday.toISOString().split('T')[0]);
    await dateTo.fill(today.toISOString().split('T')[0]);

    await page.getByRole('button', { name: /apply|filter/i }).click();
    await page.waitForLoadState('networkidle');

    await expect(page.locator('table tbody')).toBeVisible();
  });
});
