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

type DiagPage = {
  diagnostics: {
    consoleLogs: { level: string; text: string }[];
    failedRequests: { status: number; url: string }[];
  };
};

/**
 * R9FE-102: ScopeCostModal allowEmptyFilterDispatch prop
 *
 * Tests the fix that allows the "Generate Drafts" button to be enabled when:
 *   1. allMatchingSelected=true (user clicked "Select all N matching")
 *   2. filters are empty (no status, no min_impact selected)
 *   3. allowEmptyFilterDispatch=true (component is explicitly told this is valid)
 *
 * Previously, the R8FE-108 empty-filter guard would permanently disable the button,
 * even though the backend (BatchFromCannibalizationRequest) explicitly supports
 * null filters as a valid "rewrite full matching cohort" signal.
 *
 * The fix adds the allowEmptyFilterDispatch prop to ScopeCostModal and passes it
 * from Cannibalization/Index to unlock full-cohort dispatch for that surface.
 */

test.describe('R9FE-102: ScopeCostModal allowEmptyFilterDispatch', () => {
  test.beforeEach(async ({ page }) => {
    // Enable console error tracking
    const consoleLogs: { level: string; text: string }[] = [];
    page.on('console', (msg) => {
      if (msg.type() === 'error' || msg.type() === 'warning') {
        consoleLogs.push({ level: msg.type(), text: msg.text() });
      }
    });

    // Track failed requests
    const failedRequests: { status: number; url: string }[] = [];
    page.on('response', (response) => {
      if (response.status() >= 400) {
        failedRequests.push({
          status: response.status(),
          url: response.request().url(),
        });
      }
    });

    // Store in page context for use in tests
    (page as unknown as DiagPage).diagnostics = { consoleLogs, failedRequests };
  });

  test('Modal renders with cost estimate on Cannibalization page', async ({ page }) => {
    // Navigate to Cannibalization
    await page.goto('/cannibalization', { waitUntil: 'networkidle' });

    // Verify page loaded
    const heading = page.locator('h1');
    await expect(heading).toContainText(/Cannibalization|Potential/, { timeout: 10000 });

    // Check for zero critical console errors
    await page.waitForTimeout(500);
    const logs = (page as unknown as DiagPage).diagnostics.consoleLogs;
    const criticalErrors = logs.filter((l: { level: string }) => l.level === 'error');
    expect(criticalErrors).toHaveLength(0);
  });

  test('ScopeCostModal estimate calculates correctly', async ({ page }) => {
    // Navigate to Cannibalization
    await page.goto('/cannibalization', { waitUntil: 'networkidle' });

    // Wait for data table to load
    await expect(page.locator('[role="table"]')).toBeVisible({ timeout: 10000 });

    // Look for a bulk action that triggers the modal
    // Common selectors: "Select all", "Generate Drafts", bulk action buttons
    const selectAllBtn = page.locator('button').filter({ hasText: /Select all/i }).first();

    if (await selectAllBtn.isVisible()) {
      await selectAllBtn.click();

      // Wait for selection UI to update
      await page.waitForTimeout(500);

      // Look for modal trigger (could be "Generate Drafts" or similar)
      const generateBtn = page.locator('button').filter({ hasText: /Generate|Rewrite|Bulk/i }).first();

      if (await generateBtn.isVisible()) {
        await generateBtn.click();

        // Wait for modal to appear
        const modal = page.locator('[role="dialog"]').first();
        await expect(modal).toBeVisible({ timeout: 10000 });

        // Verify cost estimate section appears
        const costSection = modal.locator('text=/Cost|Estimate/i');
        await expect(costSection).toBeVisible({ timeout: 10000 });

        // Check for zero failed requests during estimate
        const failedReqs = (page as unknown as DiagPage).diagnostics.failedRequests;
        expect(failedReqs).toHaveLength(0);
      }
    }
  });

  test('No console errors or failed requests during workflow', async ({ page }) => {
    await page.goto('/cannibalization', { waitUntil: 'networkidle' });

    // Let the page settle
    await page.waitForTimeout(1000);

    // Check diagnostics
    const { consoleLogs, failedRequests } = (page as unknown as DiagPage).diagnostics;

    // Assert zero error logs
    const errors = consoleLogs.filter((l: { level: string }) => l.level === 'error');
    expect(errors).toHaveLength(0);

    // Assert zero failed HTTP requests
    const failed4xx5xx = failedRequests.filter((r: { status: number }) => r.status >= 400);
    expect(failed4xx5xx).toHaveLength(0);
  });
});
