import { describe, it, expect, afterEach, beforeAll, afterAll } from 'vitest';
import { PlaywrightAutomationAdapter, FixtureServer } from 'core/automation/infrastructure//automation';
import { NoOpLogAdapter } from '@core/automation/infrastructure//logging/NoOpLogAdapter';

describe('Playwright Adapter Smoke Tests', () => {
  let adapter: PlaywrightAutomationAdapter | undefined;
  let server: FixtureServer | undefined;
  let unhandledRejectionHandler: ((reason: unknown) => void) | null = null;
  const logger = new NoOpLogAdapter();

  beforeAll(() => {
    unhandledRejectionHandler = (reason: unknown) => {
      const message =
        reason instanceof Error ? reason.message : String(reason ?? '');
      if (message.includes('cdpSession.send: Target page, context or browser has been closed')) {
        return;
      }
      throw reason;
    };
    (process as any).on('unhandledRejection', unhandledRejectionHandler);
  });

  afterEach(async () => {
    if (adapter) {
      try {
        await adapter.disconnect();
      } catch {
        // Ignore cleanup errors
      }
      adapter = undefined;
    }
    if (server) {
      try {
        await server.stop();
      } catch {
        // Ignore cleanup errors
      }
      server = undefined;
    }
  });

  afterAll(() => {
    if (unhandledRejectionHandler) {
      (process as any).removeListener('unhandledRejection', unhandledRejectionHandler);
      unhandledRejectionHandler = null;
    }
  });

  it('Adapter instantiates without errors', () => {
    expect(() => {
      adapter = new PlaywrightAutomationAdapter({
        headless: true,
        mode: 'mock',
        timeout: 5000,
      }, logger);
    }).not.toThrow();
  });

  it('Browser connects successfully', async () => {
    adapter = new PlaywrightAutomationAdapter({
      headless: true,
      mode: 'mock',
      timeout: 5000,
    }, logger);

    const result = await adapter.connect();
    expect(result.success).toBe(true);
    expect(adapter.isConnected()).toBe(true);
  });

  it('Basic navigation works with mock fixtures', async () => {
    server = new FixtureServer();
    await server.start();

    adapter = new PlaywrightAutomationAdapter({
      headless: true,
      mode: 'mock',
      timeout: 5000,
    }, logger);

    await adapter.connect();
    const navResult = await adapter.navigateToPage(server.getFixtureUrl(2));
    expect(navResult.success).toBe(true);
  });

  it('Adapter can be instantiated multiple times', () => {
    expect(() => {
      const adapter1 = new PlaywrightAutomationAdapter({
        headless: true,
        mode: 'mock',
        timeout: 5000,
      }, logger);
      const adapter2 = new PlaywrightAutomationAdapter({
        headless: true,
        mode: 'mock',
        timeout: 5000,
      }, logger);
      expect(adapter1).not.toBe(adapter2);
    }).not.toThrow();
  });

  it('FixtureServer starts and stops cleanly', async () => {
    server = new FixtureServer();
    
    await expect(server.start()).resolves.not.toThrow();
    expect(server.getFixtureUrl(2)).toContain('http://localhost:');
    await expect(server.stop()).resolves.not.toThrow();
  });
});