/**
 * Journey: Error Scenarios
 *
 * Tests that the application handles error conditions gracefully and does not
 * expose internal errors or crash the UI:
 *
 * - Missing GSC connection: analyze page prompts for GSC setup rather than crashing
 * - 404 page: unknown routes render a user-friendly not-found page
 * - Unauthorized access: site-scoped routes reject users who don't own the site
 * - Invalid route parameters: the app handles non-existent IDs without a 500 error
 *
 * What this catches:
 * - Unguarded controllers that throw 500 when GSC/WP connections are absent
 * - Missing 404 handler in bootstrap/app.php
 * - SitePolicy not returning 403 for non-owner requests
 * - React crashes when Inertia props contain null/empty connection state
 */

import { expect, test } from '../fixtures/auth';

test.describe('Journey: Error Scenarios', () => {
  test.describe('Missing GSC connection', () => {
    test('analyze page renders without crashing when GSC is not connected', async ({
      page,
      seedData,
    }) => {
      const errors: string[] = [];
      page.on('pageerror', (err) => errors.push(err.message));
      page.on('console', (msg) => {
        if (msg.type() === 'error') errors.push(msg.text());
      });

      await page.goto(`/sites/${seedData.siteId}/analyze`, { waitUntil: 'domcontentloaded' });

      // Page must not crash — either shows the analyze UI or a GSC connect prompt
      await expect(page.locator('body')).not.toBeEmpty();

      const appErrors = errors.filter(
        (e) => !e.includes('extension') && !e.includes('chrome-extension'),
      );
      expect(appErrors, `Console errors: ${appErrors.join(', ')}`).toHaveLength(0);
    });

    test('analyze page shows connect prompt or empty state when GSC is absent', async ({
      page,
      seedData,
    }) => {
      await page.goto(`/sites/${seedData.siteId}/analyze`, { waitUntil: 'domcontentloaded' });

      const pageText = await page.innerText('body');
      // Either the analyze form or a connection prompt should be present
      expect(
        /connect|google search console|gsc|analyze|run analysis/i.test(pageText),
      ).toBe(true);
    });
  });

  test.describe('404 Not Found', () => {
    test('visiting an unknown URL returns a not-found page', async ({ page }) => {
      const response = await page.goto('/this-route-definitely-does-not-exist-xyz', {
        waitUntil: 'domcontentloaded',
      });

      // Should return a 404 status
      expect(response?.status()).toBe(404);
    });

    test('404 page renders without JS errors', async ({ page }) => {
      const errors: string[] = [];
      page.on('pageerror', (err) => errors.push(err.message));
      page.on('console', (msg) => {
        if (msg.type() === 'error') errors.push(msg.text());
      });

      await page.goto('/this-route-definitely-does-not-exist-xyz', {
        waitUntil: 'domcontentloaded',
      });

      const appErrors = errors.filter(
        (e) => !e.includes('extension') && !e.includes('chrome-extension'),
      );
      expect(appErrors, `Console errors: ${appErrors.join(', ')}`).toHaveLength(0);
    });

    test('404 page contains a user-friendly message', async ({ page }) => {
      await page.goto('/this-route-definitely-does-not-exist-xyz', {
        waitUntil: 'domcontentloaded',
      });

      const pageText = await page.innerText('body');
      expect(/not found|404|page.*not.*exist|missing/i.test(pageText)).toBe(true);
    });
  });

  test.describe('Unauthorized access attempts', () => {
    test('accessing a non-existent site ID returns an error page not a crash', async ({
      page,
    }) => {
      // Use a very large ID that is unlikely to exist
      const response = await page.goto('/sites/999999/analyze', {
        waitUntil: 'domcontentloaded',
      });

      const status = response?.status() ?? 0;
      // Should be 403, 404, or a redirect to login — never a 500
      expect(
        status === 403 || status === 404 || status === 302 || /login/i.test(page.url()),
        `Expected 403/404/redirect for non-existent site, got ${status}`,
      ).toBe(true);
    });

    test('accessing a non-existent site ID does not render a 500 error', async ({ page }) => {
      const errors: string[] = [];
      page.on('pageerror', (err) => errors.push(err.message));

      const response = await page.goto('/sites/999999/recommendations', {
        waitUntil: 'domcontentloaded',
      });

      const status = response?.status() ?? 0;
      expect(status, 'Expected non-500 response for non-existent site').not.toBe(500);
    });

    test('unauthenticated request to site-scoped route redirects to login', async ({
      browser,
    }) => {
      const context = await browser.newContext();
      const page = await context.newPage();

      await page.goto('/sites/1/analyze');
      await expect(page).toHaveURL(/\/login/);

      await context.close();
    });

    test('unauthenticated request to recommendations redirects to login', async ({
      browser,
    }) => {
      const context = await browser.newContext();
      const page = await context.newPage();

      await page.goto('/sites/1/recommendations');
      await expect(page).toHaveURL(/\/login/);

      await context.close();
    });
  });

  test.describe('Invalid route parameters', () => {
    test('non-numeric site ID in URL does not cause a 500 error', async ({ page }) => {
      const response = await page.goto('/sites/not-a-number/analyze', {
        waitUntil: 'domcontentloaded',
      });

      const status = response?.status() ?? 0;
      expect(status, 'Expected non-500 response for non-numeric site ID').not.toBe(500);
    });
  });
});
