import {
  Drupal,
  type DrupalSite,
  isolatedPerTest as isolatedPerTestBase,
  parallelWorker as parallelWorkerBase,
} from '@drupal/playwright';
import type { Browser, Page } from '@playwright/test';

import { Canvas } from '../objects/Canvas.js';
import { Conductor } from '../objects/Conductor.js';
import { setupSite } from '../setup.js';

export const isolatedPerTest = isolatedPerTestBase.extend<{
  canvas: Canvas;
  conductor: Conductor;
  beforeEach: void;
}>({
  beforeEach: [
    async ({ drupal }, use) => {
      await setupSite({ drupal });
      await use();
    },
    { auto: true },
  ],
  canvas: [
    async ({ drupal }, use) => {
      const canvas = new Canvas({ drupal });
      await use(canvas);
    },
    { auto: true },
  ],
  conductor: [
    async ({ drupal, canvas }: { page: Page; drupal: Drupal; canvas: Canvas }, use) => {
      const conductor = new Conductor({ drupal, canvas });
      await use(conductor);
    },
    { auto: true },
  ],
});

export const parallelWorker = parallelWorkerBase.extend<
  { canvas: Canvas; conductor: Conductor },
  { browser: Browser; drupalSite: DrupalSite; beforeAll: void }
>({
  beforeAll: [
    async ({ browser, drupalSite }, use, testInfo) => {
      const baseURL = testInfo.project?.use?.baseURL || '';
      const context = await browser.newContext({
        baseURL,
      });
      const page = await context.newPage();
      const drupal = new Drupal({ page, drupalSite });
      await setupSite({ drupal });
      await page.close();
      await context.close();
      await use();
    },
    { scope: 'worker', auto: true },
  ],
  canvas: [
    async ({ drupal }, use) => {
      const canvas = new Canvas({ drupal });
      await use(canvas);
    },
    { auto: true },
  ],
  conductor: [
    async ({ drupal, canvas }: { drupal: Drupal; canvas: Canvas }, use) => {
      const conductor = new Conductor({ drupal, canvas });
      await use(conductor);
    },
    { auto: true },
  ],
});
