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 smoke – login and wizard entry (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);
  }, 180_000);

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

  it(
    'logs in, reaches Hosted Racing, and opens Create Race wizard',
    async () => {
      const step1Result = await adapter.executeStep(StepId.create(1), {});
      expect(step1Result.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);

      const hostedTab = page!
        .locator(IRACING_SELECTORS.hostedRacing.hostedTab)
        .first();
      await hostedTab.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });

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

      const modalSelector = IRACING_SELECTORS.hostedRacing.createRaceModal;
      const modal = page!.locator(modalSelector).first();
      await modal.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });

      const newRaceButton = page!
        .locator(IRACING_SELECTORS.hostedRacing.newRaceButton)
        .first();
      await newRaceButton.waitFor({
        state: 'attached',
        timeout: IRACING_TIMEOUTS.elementWait,
      });

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

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

      const modalContent = await page!
        .locator(IRACING_SELECTORS.wizard.modalContent)
        .first()
        .count();
      expect(
        modalContent,
        'Race creation wizard modal content should be present',
      ).toBeGreaterThan(0);
    },
    300_000,
  );

  it(
    'detects login guard and does not attempt Create a Race when not authenticated',
    async () => {
      const step1Result = await adapter.executeStep(StepId.create(1), {});
      expect(step1Result.success).toBe(true);

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

      const currentUrl = page!.url();
      expect(currentUrl).not.toEqual('about:blank');
      expect(currentUrl.toLowerCase()).toContain('iracing');
      expect(currentUrl.toLowerCase()).toSatisfy((u: string) =>
        u.includes('oauth.iracing.com') ||
        u.includes('members.iracing.com') ||
        u.includes('/login'),
      );

      const emailInput = page!
        .locator(IRACING_SELECTORS.login.emailInput)
        .first();
      const passwordInput = page!
        .locator(IRACING_SELECTORS.login.passwordInput)
        .first();

      const hasEmail = (await emailInput.count()) > 0;
      const hasPassword = (await passwordInput.count()) > 0;

      if (!hasEmail && !hasPassword) {
        return;
      }

      await emailInput.waitFor({
        state: 'visible',
        timeout: IRACING_TIMEOUTS.elementWait,
      });
      await passwordInput.waitFor({
        state: 'visible',
        timeout: IRACING_TIMEOUTS.elementWait,
      });

      const createRaceButton = page!
        .locator(IRACING_SELECTORS.hostedRacing.createRaceButton)
        .first();
      const createRaceCount = await createRaceButton.count();

      expect(createRaceCount).toBe(0);
    },
    300_000,
  );
});