import { test, expect, type BrowserContext, type Page, type Locator } from '@playwright/test';
import { RegistrationPage } from '../../pages/RegistrationPage';
import { waitForActivationCode } from '../../utils/ActivationCodeUtils';

let context: BrowserContext;
let page: Page;
let registrationPage: RegistrationPage;
let email: string;
let password: string;

async function isVisible(locator: Locator, timeout = 1500): Promise<boolean> {
  return locator.isVisible({ timeout }).catch(() => false);
}

async function closeWelcomePopupOnly(page: Page, appearanceTimeout = 10000) {
  const welcomePopup = page.getByText(/Welcome to RoboCorp!/i).first();
  const welcomeModal = page.locator(
    "xpath=//div[.//*[contains(normalize-space(.), 'Welcome to RoboCorp!')] and .//input[@type='checkbox']]"
  ).first();
  const primaryCloseButton = page.locator('#welcome-cards-banner button.absolute').first();
  const fallbackCloseButton = welcomeModal.locator('button.absolute').first();

  const deadline = Date.now() + appearanceTimeout;
  while (Date.now() < deadline) {
    if (await isVisible(welcomePopup, 1000)) break;
    await page.waitForTimeout(250);
  }

  if (!(await isVisible(welcomePopup, 1000))) return;

  for (const closeButton of [primaryCloseButton, fallbackCloseButton]) {
    if (!(await isVisible(closeButton, 1500))) continue;

    await closeButton.click({ force: true }).catch(() => {});
    let closed = await welcomePopup.waitFor({ state: 'hidden', timeout: 3000 }).then(() => true).catch(() => false);
    if (!closed) {
      await closeButton.click({ force: true }).catch(() => {});
      closed = await welcomePopup.waitFor({ state: 'hidden', timeout: 3000 }).then(() => true).catch(() => false);
    }
    if (closed) return;
  }

  await page.keyboard.press('Escape').catch(() => {});
  await expect(welcomePopup).toBeHidden({ timeout: 3000 });
}

async function advanceTipsToChat(page: Page) {
  const continueButton = page.getByRole('button', { name: /^Continue$/i }).first();
  const tipsText = page.getByText(/Here is tips how to use our platform|Traditional search engines return links/i).first();
  const chatInput = page.getByPlaceholder('Ask anything...').first();
  const welcomeBanner = page.locator('#welcome-cards-banner');

  for (let i = 0; i < 6; i++) {
    const chatReady = await chatInput.isVisible({ timeout: 1000 }).catch(() => false);
    const tipsVisible = await tipsText.isVisible({ timeout: 1000 }).catch(() => false);
    if (chatReady && !tipsVisible) {
      return;
    }

    if (!(await continueButton.isVisible({ timeout: 1000 }).catch(() => false))) {
      break;
    }

    await continueButton.click();
    await Promise.race([
      welcomeBanner.waitFor({ state: 'visible', timeout: 3000 }).catch(() => null),
      page.waitForTimeout(800)
    ]);
  }
}

test.describe.serial('Business Users / B5 User', () => {
  test.describe.configure({ timeout: 180000 });

  test.beforeAll(async ({ browser }) => {
    context = await browser.newContext();
    page = await context.newPage();
    registrationPage = new RegistrationPage(page);

    email = `automation.b5+${Date.now()}@datafab.ai`;
    password = process.env.USER_PASSWORD?.trim() || 'Password123!';

    await registrationPage.gotoSignIn();
    await registrationPage.openSignUpFromSignIn();
    await registrationPage.submitSignUpCredentials(email, password);
    await registrationPage.submitFullName('Automation B5 User');

    await registrationPage.waitForVerificationScreen();
    const code = await waitForActivationCode(email, { timeoutMs: 90000, intervalMs: 3000 });
    await registrationPage.enterVerificationCode(code);
    await registrationPage.clickVerify();
  });

  test.afterAll(async () => {
    await context?.close();
  });

  test('should register and activate successfully', async () => {
    await expect(page).toHaveURL(/\/sign-in\/account/i, { timeout: 30000 });
    await expect(page.locator('body')).not.toContainText(/please check your email/i, { timeout: 10000 });
  });

  test('should keep the user on the account selection milestone', async () => {
    await expect(page).toHaveURL(/\/sign-in\/account/i, { timeout: 10000 });
    await expect(page.locator('body')).toContainText(/What best describes you\?/i, { timeout: 30000 });
  });

  test('should show both account type options', async () => {
    await expect(registrationPage.individualUserOption).toBeVisible({ timeout: 30000 });
    await expect(registrationPage.businessUserOption).toBeVisible({ timeout: 30000 });
  });

  test('should complete business user type selection after activation', async () => {
    await registrationPage.completeBusinessUserConsumerFlow();
    await registrationPage.waitForTipsOrOnboarding();
    await expect(page.locator('body')).toContainText(/Here is tips how to use our platform|Traditional search engines return links/i, {
      timeout: 30000
    });
  });

  test('should close the welcome popup after full registration', async () => {
    await advanceTipsToChat(page);
    await closeWelcomePopupOnly(page);

    await expect(page.getByText(/Welcome to RoboCorp!/i).first()).toBeHidden({ timeout: 5000 });
    await expect(page.getByPlaceholder('Ask anything...').first()).toBeVisible({ timeout: 30000 });
  });
});
