import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId';
import {
  PlaywrightAutomationAdapter,
} from 'core/automation/infrastructure//automation';
import {
  IRACING_SELECTORS,
  IRACING_TIMEOUTS,
} from 'core/automation/infrastructure//automation/dom/IRacingSelectors';
import { PinoLogAdapter } from 'core/automation/infrastructure//logging/PinoLogAdapter';

const shouldRun = process.env.HOSTED_REAL_E2E === '1';
const describeMaybe = shouldRun ? describe : describe.skip;

describeMaybe('Real-site hosted session – Cars flow (members.iracing.com)', () => {
  let adapter: PlaywrightAutomationAdapter;

  beforeAll(async () => {
    const logger = new PinoLogAdapter();

    adapter = new PlaywrightAutomationAdapter(
      {
        headless: true,
        timeout: IRACING_TIMEOUTS.navigation,
        mode: 'real',
        baseUrl: '',
        userDataDir: '',
      },
      logger,
    );

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

    const step1Result = await adapter.executeStep(StepId.create(1), {});
    expect(step1Result.success).toBe(true);

    const step2Result = await adapter.executeStep(StepId.create(2), {});
    expect(step2Result.success).toBe(true);

    const page = adapter.getPage();
    expect(page).not.toBeNull();

    const createRaceButton = page!
      .locator(IRACING_SELECTORS.hostedRacing.createRaceButton)
      .first();
    await expect(
      createRaceButton.count(),
      'Create Race button should exist on Hosted Racing page',
    ).resolves.toBeGreaterThan(0);

    await createRaceButton.click({ timeout: IRACING_TIMEOUTS.elementWait });

    const raceInfoContainer = page!
      .locator(IRACING_SELECTORS.wizard.stepContainers.raceInformation)
      .first();
    await raceInfoContainer.waitFor({
      state: 'attached',
      timeout: IRACING_TIMEOUTS.elementWait,
    });
    expect(await raceInfoContainer.count()).toBeGreaterThan(0);

    const sessionConfig = {
      sessionName: 'GridPilot Real – Cars flow',
      password: 'cars-flow-secret',
      description: 'Real-site cars flow short path',
    };
    const step3Result = await adapter.executeStep(StepId.create(3), sessionConfig);
    expect(step3Result.success).toBe(true);

    const carsSidebarLink = page!
      .locator(IRACING_SELECTORS.wizard.sidebarLinks.cars)
      .first();
    await carsSidebarLink.waitFor({
      state: 'attached',
      timeout: IRACING_TIMEOUTS.elementWait,
    });
    await carsSidebarLink.click({ timeout: IRACING_TIMEOUTS.elementWait });

    const carsContainer = page!
      .locator(IRACING_SELECTORS.wizard.stepContainers.cars)
      .first();
    await carsContainer.waitFor({
      state: 'attached',
      timeout: IRACING_TIMEOUTS.elementWait,
    });
    expect(await carsContainer.count()).toBeGreaterThan(0);
  }, 300_000);

  afterAll(async () => {
    if (adapter) {
      await adapter.disconnect();
    }
  });

  it(
    'opens Add Car UI on real site and lists at least one car',
    async () => {
      const page = adapter.getPage();
      expect(page).not.toBeNull();

      const carsContainer = page!
        .locator(IRACING_SELECTORS.wizard.stepContainers.cars)
        .first();
      await carsContainer.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });
      expect(await carsContainer.count()).toBeGreaterThan(0);

      const addCarButton = page!
        .locator(IRACING_SELECTORS.steps.addCarButton)
        .first();
      await addCarButton.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });
      expect(await addCarButton.count()).toBeGreaterThan(0);

      await addCarButton.click({ timeout: IRACING_TIMEOUTS.elementWait });

      const addCarModal = page!
        .locator(IRACING_SELECTORS.steps.addCarModal)
        .first();
      await addCarModal.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });
      expect(await addCarModal.count()).toBeGreaterThan(0);

      const carsTable = addCarModal
        .locator('table.table.table-striped tbody tr')
        .first();
      await carsTable.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });
      const rowCount = await addCarModal
        .locator('table.table.table-striped tbody tr')
        .count();
      expect(rowCount).toBeGreaterThan(0);
    },
    300_000,
  );
});