import { test, expect, type Page, type Response } from '@playwright/test';
import { exec } from 'child_process';
import { promisify } from 'util';
import {
  assertNoAuthRedirect,
  attachImportDiagnostics,
  ensureImportUiPreconditions,
  ensureImportFormReady,
  logImportFailureContext,
  resetImportSession,
  waitForSuccessfulImportResponse,
} from './import-page-helpers';

const execAsync = promisify(exec);

async function fillImportTextarea(page: Page, content: string): Promise<void> {
  const importPageMarker = page.getByTestId('import-banner').first();
  if ((await importPageMarker.count()) > 0) {
    await expect(importPageMarker).toBeVisible();
  }

  for (let attempt = 1; attempt <= 2; attempt += 1) {
    const textarea = page.locator('textarea').first();

    try {
      await expect(textarea).toBeVisible();
      await expect(textarea).toBeEditable();
      await textarea.click();
      await textarea.press('ControlOrMeta+A');
      await textarea.fill(content);
      return;
    } catch (error) {
      if (attempt === 2) {
        throw error;
      }

      // Retry after ensuring the form remains in an interactive state.
      await ensureImportFormReady(page);
    }
  }
}

async function waitForImportResponseOrFallback(
  page: Page,
  triggerAction: () => Promise<void>,
  scope: string,
  expectedPath: RegExp
): Promise<Response | null> {
  await assertNoAuthRedirect(page, `${scope} pre-trigger`);

  try {
    const [response] = await Promise.all([
      page.waitForResponse((r) => expectedPath.test(r.url()), { timeout: 8000 }),
      triggerAction(),
    ]);
    return response;
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : String(error);
    if (!errorMessage.includes('waitForResponse')) {
      throw error;
    }

    await logImportFailureContext(page, scope);
    console.warn(`[${scope}] No matching import response observed; switching to UI-state assertions`);
    return null;
  }
}

async function openImportPageDeterministic(page: Page): Promise<void> {
  const maxAttempts = 2;

  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
    try {
      await ensureImportUiPreconditions(page);
      return;
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      const isRetriableWebKitNavigationError = message.includes('WebKit encountered an internal error');

      if (attempt < maxAttempts && isRetriableWebKitNavigationError) {
        console.warn(`[Navigation] Retrying import page preconditions after WebKit navigation error (attempt ${attempt}/${maxAttempts})`);
        await page.goto('/', { waitUntil: 'domcontentloaded' }).catch(() => undefined);
        continue;
      }

      throw error;
    }
  }
}

/**
 * Caddy Import Debug Tests - POC Implementation
 *
 * Purpose: Diagnostic tests to expose failure modes in Caddy import functionality
 * Specification: docs/plans/caddy_import_debug_spec.md
 *
 * CRITICAL FIXES APPLIED:
 * 1. ✅ No loginUser() - uses stored auth state from auth.setup.ts
 * 2. ✅ waitForResponse() registered BEFORE click() to prevent race conditions
 * 3. ✅ Programmatic Docker log capture in afterEach() hook
 * 4. ✅ Health check in beforeAll() validates container state
 *
 * Current Status: POC - Test 1 only (Baseline validation)
 */
test.describe('Caddy Import Debug Tests @caddy-import-debug', () => {
  const diagnosticsByPage = new WeakMap<Page, () => void>();

  test.beforeEach(async ({ page }) => {
    diagnosticsByPage.set(page, attachImportDiagnostics(page, 'caddy-import-debug'));
    await resetImportSession(page);
  });

  // CRITICAL FIX #4: Pre-test health check
  test.beforeAll(async ({ baseURL }) => {
    console.log('[Health Check] Validating Charon container state...');

    try {
      const healthResponse = await fetch(`${baseURL}/health`);
      console.log('[Health Check] Response status:', healthResponse.status);

      if (!healthResponse.ok) {
        throw new Error(`Charon container unhealthy - Status: ${healthResponse.status}`);
      }

      console.log('[Health Check] ✅ Container is healthy and ready');
    } catch (error) {
      console.error('[Health Check] ❌ Failed:', error);
      throw new Error('Charon container not running or unhealthy. Please start the container with: docker-compose up -d');
    }
  });

  // CRITICAL FIX #3: Programmatic backend log capture on test failure
  test.afterEach(async ({ page }, testInfo) => {
    diagnosticsByPage.get(page)?.();

    await resetImportSession(page);

    if (testInfo.status !== 'passed') {
      await logImportFailureContext(page, 'caddy-import-debug');
      console.log('[Log Capture] Test failed - capturing backend logs...');

      try {
        const { stdout } = await execAsync(
          'docker logs charon-app 2>&1 | grep -i import | tail -50'
        );

        if (stdout) {
          console.log('[Log Capture] Backend logs retrieved:', stdout);
          testInfo.attach('backend-logs', {
            body: stdout,
            contentType: 'text/plain'
          });
          console.log('[Log Capture] ✅ Backend logs attached to test report');
        } else {
          console.warn('[Log Capture] ⚠️ No import-related logs found in backend');
        }
      } catch (error) {
        console.warn('[Log Capture] ⚠️ Failed to capture backend logs:', error);
        console.warn('[Log Capture] Ensure Docker container name is "charon-app"');
      }
    }
  });

  test.describe('Baseline Verification', () => {
    /**
     * Test 1: Simple Valid Caddyfile (POC)
     *
     * Objective: Verify the happy path works correctly and establish baseline behavior
     * Expected: ✅ Should PASS if basic import functionality is working
     *
     * This test determines whether the entire import pipeline is functional:
     * - Frontend uploads Caddyfile content
     * - Backend receives and parses it
     * - Caddy CLI successfully adapts the config
     * - Hosts are extracted and returned
     * - UI displays the preview correctly
     */
    test('should successfully import a simple valid Caddyfile', async ({ page }) => {
      console.log('\n=== Test 1: Simple Valid Caddyfile (POC) ===');

      // CRITICAL FIX #1: No loginUser() call
      // Auth state automatically loaded from storage state (auth.setup.ts)
      console.log('[Auth] Using stored authentication state from global setup');

      // Navigate to import page
      console.log('[Navigation] Going to /tasks/import/caddyfile');
      await openImportPageDeterministic(page);

      // Simple valid Caddyfile with single reverse proxy
      const caddyfile = `
test-simple.example.com {
    reverse_proxy localhost:3000
}
      `.trim();

      console.log('[Input] Caddyfile content:');
      console.log(caddyfile);

      // Step 1: Paste Caddyfile content into textarea
      console.log('[Action] Filling textarea with Caddyfile content...');
      await fillImportTextarea(page, caddyfile);
      console.log('[Action] ✅ Content pasted');

      // Step 2: Set up API response waiter BEFORE clicking parse button
      // CRITICAL FIX #2: Race condition prevention
      const parseButton = page.getByRole('button', { name: /parse|review/i });
      const apiResponse = await waitForSuccessfulImportResponse(
        page,
        async () => {
          console.log('[Action] Clicking parse button...');
          await parseButton.click();
          console.log('[Action] ✅ Parse button clicked, waiting for API response...');
        },
        'debug-simple-parse'
      );
      console.log('[API] Response received:', apiResponse.status(), apiResponse.statusText());

      // Step 3: Log full API response for diagnostics
      const responseBody = await apiResponse.json();
      console.log('[API] Response body:');
      console.log(JSON.stringify(responseBody, null, 2));

      // Analyze response structure
      if (responseBody.preview) {
        console.log('[API] ✅ Preview object present');
        console.log('[API] Hosts count:', responseBody.preview.hosts?.length || 0);

        if (responseBody.preview.hosts && responseBody.preview.hosts.length > 0) {
          console.log('[API] First host:', JSON.stringify(responseBody.preview.hosts[0], null, 2));
        }
      } else {
        console.warn('[API] ⚠️ No preview object in response');
      }

      if (responseBody.error) {
        console.error('[API] ❌ Error in response:', responseBody.error);
      }

      // Step 4: Verify preview shows the host domain (use test-id to avoid matching textarea)
      console.log('[Verification] Checking if domain appears in preview...');
      const reviewTable = page.getByTestId('import-review-table');
      await expect(reviewTable.getByText('test-simple.example.com')).toBeVisible({ timeout: 10000 });
      console.log('[Verification] ✅ Domain visible in preview');

      // Step 5: Verify we got hosts in the API response (forward details in raw_json)
      console.log('[Verification] Checking API returned valid host details...');
      const firstHost = responseBody.preview?.hosts?.[0];
      expect(firstHost).toBeDefined();
      expect(firstHost.forward_port).toBe(3000);
      console.log('[Verification] ✅ Forward port 3000 confirmed in API response');

      console.log('\n=== Test 1: ✅ PASSED ===\n');
    });
  });

  test.describe('Import Directives', () => {
    /**
     * Test 2: Caddyfile with Import Directives
     *
     * Objective: Expose the import directive handling - should show appropriate error/guidance
     * Expected: ⚠️ May FAIL if error message is unclear or missing
     */
    test('should detect import directives and provide actionable error', async ({ page }) => {
      console.log('\n=== Test 2: Import Directives Detection ===');

      // Auth state loaded from storage - no login needed
      console.log('[Auth] Using stored authentication state');
      await openImportPageDeterministic(page);
      console.log('[Navigation] Navigated to import page');

      const caddyfileWithImports = `
import sites.d/*.caddy

admin.example.com {
    reverse_proxy localhost:9090
}
      `.trim();

      console.log('[Input] Caddyfile with import directive:');
      console.log(caddyfileWithImports);

      // Paste content with import directive
      console.log('[Action] Filling textarea...');
      await fillImportTextarea(page, caddyfileWithImports);
      console.log('[Action] ✅ Content pasted');

      // Click parse and capture response (FIX: waitForResponse BEFORE click)
      const parseButton = page.getByRole('button', { name: /parse|review/i });

      const [apiResponse] = await Promise.all([
        page.waitForResponse((response) => response.url().includes('/api/v1/import/upload'), { timeout: 15000 }),
        parseButton.click(),
      ]);
      console.log('[API] Response received');

      // Log status and response body
      const status = apiResponse.status();
      const responseBody = await apiResponse.json();
      console.log('[API] Status:', status);
      console.log('[API] Response:', JSON.stringify(responseBody, null, 2));

      // Check if backend detected import directives
      if (responseBody.imports && responseBody.imports.length > 0) {
        console.log('✅ Backend detected imports:', responseBody.imports);
      } else {
        console.warn('❌ Backend did NOT detect import directives');
      }

      // Verify user-facing error message
      console.log('[Verification] Checking for error message display...');
      const errorMessage = page.locator('.bg-red-900, .bg-red-900\\/20');
      await expect(errorMessage).toBeVisible({ timeout: 5000 });
      console.log('[Verification] ✅ Error message visible');

      // Check error text surfaces the import failure
      const errorText = await errorMessage.textContent();
      console.log('[Verification] Error message displayed to user:', errorText);

      // Should mention "import" - caddy adapt returns errors like:
      // "import failed: parsing caddy json: invalid character '{' after top-level value"
      // NOTE: Future enhancement could add actionable guidance about multi-file upload
      expect(errorText?.toLowerCase()).toContain('import');
      console.log('[Verification] ✅ Error message surfaces import failure');

      console.log('\n=== Test 2: Complete ===\n');
    });
  });

  test.describe('Unsupported Features', () => {
    /**
     * Test 3: Caddyfile with No Reverse Proxy (File Server Only)
     *
     * Objective: Expose silent host skipping - should inform user which hosts were ignored
     * Expected: ⚠️ May FAIL if no feedback about skipped hosts
     */
    test('should provide feedback when all hosts are file servers (not reverse proxies)', async ({ page }) => {
      console.log('\n=== Test 3: File Server Only ===');

      // Auth state loaded from storage
      console.log('[Auth] Using stored authentication state');
      await openImportPageDeterministic(page);
      console.log('[Navigation] Navigated to import page');

      const fileServerCaddyfile = `
static.example.com {
    file_server
    root * /var/www/html
}

docs.example.com {
    file_server browse
    root * /var/www/docs
}
      `.trim();

      console.log('[Input] File server only Caddyfile:');
      console.log(fileServerCaddyfile);

      // Paste file server config
      console.log('[Action] Filling textarea...');
      await fillImportTextarea(page, fileServerCaddyfile);
      console.log('[Action] ✅ Content pasted');

      // Parse and capture API response (FIX: register waiter first)
      const parseButton = page.getByRole('button', { name: /parse|review/i });
      const apiResponse = await waitForImportResponseOrFallback(
        page,
        async () => {
          await parseButton.click();
        },
        'debug-file-server-only',
        /\/api\/v1\/import\/upload/i
      );

      if (apiResponse) {
        console.log('[API] Response received');

        const status = apiResponse.status();
        const responseBody = await apiResponse.json();
        console.log('[API] Status:', status);
        console.log('[API] Response:', JSON.stringify(responseBody, null, 2));

        // Check if preview.hosts is empty
        const hosts = responseBody.preview?.hosts || [];
        if (hosts.length === 0) {
          console.log('✅ Backend correctly parsed 0 hosts');
        } else {
          console.warn('❌ Backend unexpectedly returned hosts:', hosts);
        }

        // Check if warnings exist for unsupported features
        if (hosts.some((h: any) => h.warnings?.length > 0)) {
          console.log('✅ Backend included warnings:', hosts[0].warnings);
        } else {
          console.warn('❌ Backend did NOT include warnings about file_server');
        }
      } else {
        console.log('[API] No upload request observed (likely client-side validation path)');
      }

      // Verify user-facing error/warning (use .first() since we may have multiple warning banners)
      console.log('[Verification] Checking for warning/error message...');
      const warningMessage = page.locator('.bg-yellow-900, .bg-yellow-900\\/20, .bg-red-900').first();
      await expect(warningMessage).toBeVisible({ timeout: 5000 });
      console.log('[Verification] ✅ Warning/Error message visible');

      const warningText = await warningMessage.textContent();
      console.log('[Verification] Warning/Error displayed:', warningText);

      // Should mention "file server" or "not supported" or "no sites found"
      expect(warningText?.toLowerCase()).toMatch(/file.?server|not supported|no (sites|hosts|domains) found/);
      console.log('[Verification] ✅ Message mentions unsupported features');

      console.log('\n=== Test 3: Complete ===\n');
    });

    /**
     * Test 5: Caddyfile with Mixed Content (Valid + Unsupported)
     *
     * Objective: Test partial import scenario - some hosts valid, some skipped/warned
     * Expected: ⚠️ May FAIL if skipped hosts not communicated
     */
    test('should handle mixed valid/invalid hosts and provide detailed feedback', async ({ page }) => {
      console.log('\n=== Test 5: Mixed Content ===');

      // Auth state loaded from storage
      console.log('[Auth] Using stored authentication state');
      await openImportPageDeterministic(page);
      console.log('[Navigation] Navigated to import page');

      const mixedCaddyfile = `
# Valid reverse proxy
api.example.com {
    reverse_proxy localhost:8080
}

# File server (should be skipped)
static.example.com {
    file_server
    root * /var/www
}

# Valid reverse proxy with WebSocket
ws.example.com {
    reverse_proxy localhost:9000 {
        header_up Upgrade websocket
    }
}

# Redirect (should be warned)
redirect.example.com {
    redir https://other.example.com{uri}
}
      `.trim();

      console.log('[Input] Mixed content Caddyfile:');
      console.log(mixedCaddyfile);

      // Paste mixed content
      console.log('[Action] Filling textarea...');
      await fillImportTextarea(page, mixedCaddyfile);
      console.log('[Action] ✅ Content pasted');

      // Parse and capture response (FIX: waiter registered first)
      const [apiResponse] = await Promise.all([
        page.waitForResponse((response) => response.url().includes('/api/v1/import/upload') && response.ok(), { timeout: 15000 }),
        page.getByRole('button', { name: /parse|review/i }).click(),
      ]);
      console.log('[API] Response received');

      const responseBody = await apiResponse.json();
      console.log('[API] Response:', JSON.stringify(responseBody, null, 2));

      // Analyze what was parsed
      const hosts = responseBody.preview?.hosts || [];
      console.log(`[Analysis] Parsed ${hosts.length} hosts:`, hosts.map((h: any) => h.domain_names));

      // Should find 2 valid reverse proxies (api + ws)
      expect(hosts.length).toBeGreaterThanOrEqual(2);
      console.log('✅ Found at least 2 hosts');

      // Check if static.example.com is in list (should NOT be, or should have warning)
      const staticHost = hosts.find((h: any) => h.domain_names === 'static.example.com');
      if (staticHost) {
        console.warn('⚠️ static.example.com was included:', staticHost);
        expect(staticHost.warnings).toBeDefined();
        expect(staticHost.warnings.length).toBeGreaterThan(0);
        console.log('✅ But has warnings:', staticHost.warnings);
      } else {
        console.log('✅ static.example.com correctly excluded');
      }

      // Check if redirect host has warnings
      const redirectHost = hosts.find((h: any) => h.domain_names === 'redirect.example.com');
      if (redirectHost) {
        console.log('ℹ️ redirect.example.com included:', redirectHost);
      }

      // Verify UI shows all importable hosts (use test-id to avoid matching textarea)
      console.log('[Verification] Checking if valid hosts visible in preview...');
      const reviewTable = page.getByTestId('import-review-table');
      await expect(reviewTable.getByText('api.example.com')).toBeVisible();
      console.log('[Verification] \u2705 api.example.com visible');
      await expect(reviewTable.getByText('ws.example.com')).toBeVisible();
      console.log('[Verification] ✅ ws.example.com visible');

      // Check if warnings are displayed
      const warningElements = page.locator('.text-yellow-400, .bg-yellow-900');
      const warningCount = await warningElements.count();
      console.log(`[Verification] UI displays ${warningCount} warning indicators`);

      console.log('\n=== Test 5: Complete ===\n');
    });
  });

  test.describe('Parse Errors', () => {
    /**
     * Test 4: Caddyfile with Invalid Syntax
     *
     * Objective: Expose how parse errors from `caddy adapt` are surfaced to the user
     * Expected: ⚠️ May FAIL if error message is cryptic
     */
    test('should provide clear error message for invalid Caddyfile syntax', async ({ page }) => {
      console.log('\n=== Test 4: Invalid Syntax ===');

      // Auth state loaded from storage
      console.log('[Auth] Using stored authentication state');
      await openImportPageDeterministic(page);
      console.log('[Navigation] Navigated to import page');

      const invalidCaddyfile = `
broken.example.com {
    reverse_proxy localhost:3000
    this is invalid syntax
    another broken line
}
      `.trim();

      console.log('[Input] Invalid Caddyfile:');
      console.log(invalidCaddyfile);

      // Paste invalid content
      console.log('[Action] Filling textarea...');
      await fillImportTextarea(page, invalidCaddyfile);
      console.log('[Action] ✅ Content pasted');

      // Parse and capture response (FIX: waiter before click)
      const [apiResponse] = await Promise.all([
        page.waitForResponse((response) => response.url().includes('/api/v1/import/upload'), { timeout: 15000 }),
        page.getByRole('button', { name: /parse|review/i }).click(),
      ]);
      console.log('[API] Response received');

      const status = apiResponse.status();
      const responseBody = await apiResponse.json();
      console.log('[API] Status:', status);
      console.log('[API] Error Response:', JSON.stringify(responseBody, null, 2));

      // Should be 400 Bad Request
      expect(status).toBe(400);
      console.log('✅ Status is 400 Bad Request');

      // Check error message structure
      if (responseBody.error) {
        console.log('✅ Backend returned error:', responseBody.error);

        // Check if error mentions "caddy adapt" output
        if (responseBody.error.includes('caddy adapt failed')) {
          console.log('✅ Error includes caddy adapt context');
        } else {
          console.warn('⚠️ Error does NOT mention caddy adapt failure');
        }

        // Check if error includes line number hint
        if (/line \d+/i.test(responseBody.error)) {
          console.log('✅ Error includes line number reference');
        } else {
          console.warn('⚠️ Error does NOT include line number');
        }
      } else {
        console.error('❌ No error field in response body');
      }

      // Verify UI displays error
      console.log('[Verification] Checking for error message display...');
      const errorMessage = page.locator('.bg-red-900, .bg-red-900\\/20');
      await expect(errorMessage).toBeVisible({ timeout: 5000 });
      console.log('[Verification] ✅ Error message visible');

      const errorText = await errorMessage.textContent();
      console.log('[Verification] User-facing error:', errorText);

      // Error should be actionable
      expect(errorText?.length).toBeGreaterThan(10); // Not just "error"
      console.log('[Verification] ✅ Error message is substantive (>10 chars)');

      console.log('\n=== Test 4: Complete ===\n');
    });
  });

  test.describe('Multi-File Flow', () => {
    /**
     * Test 6: Import Directive with Multi-File Upload
     *
     * Objective: Test the multi-file upload flow that SHOULD work for imports
     * Expected: ✅ Should PASS if multi-file implementation is correct
     */
    test('should reject unsafe multi-file payloads with actionable validation feedback', async ({ page }) => {
      console.log('\n=== Test 6: Multi-File Upload ===');

      // Auth state loaded from storage
      console.log('[Auth] Using stored authentication state');
      await openImportPageDeterministic(page);
      console.log('[Navigation] Navigated to import page');

      // Main Caddyfile
      const mainCaddyfile = `
import sites.d/app.caddy

admin.example.com {
    reverse_proxy localhost:9090
}
      `.trim();

      // Site file
      const siteCaddyfile = `
app.example.com {
    reverse_proxy localhost:3000
}

api.example.com {
    reverse_proxy localhost:8080
}
      `.trim();

      console.log('[Input] Main Caddyfile:');
      console.log(mainCaddyfile);
      console.log('[Input] Site file (sites.d/app.caddy):');
      console.log(siteCaddyfile);

      // Click multi-file import button
      console.log('[Action] Looking for multi-file upload button...');
      await page.getByRole('button', { name: /multi.*file|multi.*site/i }).click();
      console.log('[Action] ✅ Multi-file button clicked');

      // Wait for modal to open
      console.log('[Verification] Waiting for modal to appear...');
      const modal = page.locator('[role="dialog"], .modal, [data-testid="multi-site-modal"]');
      await expect(modal).toBeVisible({ timeout: 5000 });
      console.log('[Verification] ✅ Modal visible');

      // Find the file input within modal
      // NOTE: File input is intentionally hidden (standard UX pattern - label triggers it)
      // We locate it but don't check visibility since hidden inputs can still receive files
      console.log('[Action] Locating file input...');
      const fileInput = modal.locator('input[type="file"]');
      console.log('[Action] ✅ File input located');

      // Upload ALL files at once
      console.log('[Action] Uploading both files...');
      await fileInput.setInputFiles([
        { name: 'Caddyfile', mimeType: 'text/plain', buffer: Buffer.from(mainCaddyfile) },
        { name: 'app.caddy', mimeType: 'text/plain', buffer: Buffer.from(siteCaddyfile) },
      ]);
      console.log('[Action] ✅ Files uploaded');

      // Click upload/parse button in modal (FIX: waiter first)
      // Use more specific selector to avoid matching multiple buttons
      const uploadButton = modal.getByRole('button', { name: /Parse and Review/i });

      const apiResponse = await waitForImportResponseOrFallback(
        page,
        async () => {
          await uploadButton.click();
        },
        'debug-multi-file-upload',
        /\/api\/v1\/import\/(upload-multi|upload)/i
      );

      if (!apiResponse) {
        console.log('[API] No multi-file upload request observed; validating client-side state');
        await expect(modal).toBeVisible();
        await expect(uploadButton).toBeVisible();

        const clientFeedback = modal.locator('.bg-red-900, .bg-red-900\\/20, .bg-yellow-900, .bg-yellow-900\\/20, [role="alert"]');
        if ((await clientFeedback.count()) > 0) {
          await expect(clientFeedback.first()).toBeVisible();
          const feedbackText = (await clientFeedback.first().textContent()) ?? '';
          expect(feedbackText.trim().length).toBeGreaterThan(0);
          console.log('[Verification] Client-side feedback:', feedbackText);
        }

        return;
      }

      console.log('[API] Response received');

      const status = apiResponse.status();
      const responseBody = await apiResponse.json();
      console.log('[API] Multi-file Status:', status);
      console.log('[API] Multi-file Response:', JSON.stringify(responseBody, null, 2));

      // Hardened import validation rejects this payload and should provide a clear reason.
      expect(status).toBe(400);
      expect(responseBody.error).toBeDefined();
      expect((responseBody.error as string).toLowerCase()).toMatch(/import failed|parsing caddy json|invalid character/);

      const hosts = responseBody.preview?.hosts || [];
      console.log(`[Analysis] Parsed ${hosts.length} hosts from multi-file import`);
      console.log('[Analysis] Host domains:', hosts.map((h: any) => h.domain_names));
      expect(hosts.length).toBe(0);

      // Verify users see explicit rejection feedback in the modal or page alert area.
      const errorBanner = page.locator('.bg-red-900, .bg-red-900\\/20, [role="alert"]').first();
      await expect(errorBanner).toBeVisible({ timeout: 10000 });
      await expect(errorBanner).toContainText(/import failed|parsing caddy json|invalid character/i);
      console.log('[Verification] ✅ Rejection feedback visible with actionable message');

      console.log('\n=== Test 6: ✅ PASSED ===\n');
    });
  });
});
