import { expect, Page } from '@playwright/test';

// Import the seed and switch to the user based on the ID.
// '01' -> user 111
// otherwise -> user 000
// (... which is a weird convention but I haven't taken the time to change it)
export async function importUser(page: Page, id?: string): Promise<string> {
  let seedPhrase, userName, did;

  // Set seed phrase and DID based on user ID
  switch(id) {
    case '01':
      seedPhrase = 'island fever beef wine urban aim vacant quit afford total poem flame service calm better adult neither color gaze forum month sister imitate excite';
      userName = 'User One';
      did = 'did:ethr:0x111d15564f824D56C7a07b913aA7aDd03382aA39';
      break;
    default: // to user 00
      seedPhrase = 'rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage';
      userName = 'User Zero';
      did = 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F';
  }

  // Import ID
  await page.goto('./start');
  await page.getByText('You have a seed').click();
  await page.getByPlaceholder('Seed Phrase').fill(seedPhrase);
  await page.getByRole('button', { name: 'Import' }).click();

  // Check DID
  await expect(page.getByRole('code')).toContainText(did);
  // ... and ensure the app retrieves the registration status
  await expect(page.locator('#sectionUsageLimits').getByText('Checking')).toBeHidden();
  return did;
}

export async function importUserAndCloseOnboarding(page: Page, id?: string): Promise<string> {
  const did = await importUser(page, id);
  await page.goto('./');
  await page.getByTestId('closeOnboardingAndFinish').click();
  return did;
}

// This is to switch to someone already in the identity table. It doesn't include registration.
export async function switchToUser(page: Page, did: string): Promise<void> {
  // This is the direct approach but users have to tap on things so we'll do that instead.
  //await page.goto('./identity-switcher');

  await page.goto('./account');
  await page.getByRole('heading', { name: 'Advanced' }).click();
  await page.getByRole('link', { name: 'Switch Identifier' }).click();
  const didElem = await page.locator(`code:has-text("${did}")`);
  await didElem.isVisible();
  await didElem.click();
  // wait for the switch to happen and the account page to fully load
  await page.getByTestId('didWrapper').locator('code:has-text("did:")');
}

function createContactName(did: string): string {
  return "User " + did.slice(11, 14);
}

export async function deleteContact(page: Page, did: string): Promise<void> {
  await page.goto('./contacts');
  const contactName = createContactName(did);
  // go to the detail page for this contact
  await page.locator(`li[data-testid="contactListItem"] h2:has-text("${contactName}") + span svg.fa-circle-info`).click();
  // delete the contact
  await page.locator('button > svg.fa-trash-can').click();
  await page.locator('div[role="alert"] button:has-text("Yes")').click();
  // for some reason, .isHidden() (without expect) doesn't work
  await expect(page.locator('div[role="alert"] button:has-text("Yes")')).toBeHidden();
}

export async function generateNewEthrUser(page: Page): Promise<string> {
  await page.goto('./start');
  await page.getByTestId('newSeed').click();
  await expect(page.locator('span:has-text("Created")')).toBeVisible();

  await page.goto('./account');
  const didElem = await page.getByTestId('didWrapper').locator('code:has-text("did:")');
  const newDid = await didElem.innerText();
  return newDid;
}

// Generate a new random user and register them.
// Note that this makes 000 the active user. Use switchToUser to switch to this DID.
export async function generateAndRegisterEthrUser(page: Page): Promise<string> {
  const newDid = await generateNewEthrUser(page);

  await importUser(page, '000'); // switch to user 000

  await page.goto('./contacts');
  const contactName = createContactName(newDid);
  await page.getByPlaceholder('URL or DID, Name, Public Key').fill(`${newDid}, ${contactName}`);
  await page.locator('button > svg.fa-plus').click();
  // register them
  await page.locator('div[role="alert"] button:has-text("Yes")').click();
  // wait for it to disappear because the next steps may depend on alerts being gone
  await expect(page.locator('div[role="alert"] button:has-text("Yes")')).toBeHidden();
  await expect(page.locator('li', { hasText: contactName })).toBeVisible();

  return newDid;
}

// Function to generate a random string of specified length
export async function generateRandomString(length: number): Promise<string> {
  return Math.random().toString(36).substring(2, 2 + length);
}

// Function to create an array of unique strings
export async function createUniqueStringsArray(count: number): Promise<string[]> {
  const stringsArray = [];
  const stringLength = 16;

  for (let i = 0; i < count; i++) {
    let randomString = await generateRandomString(stringLength);
    stringsArray.push(randomString);
  }

  return stringsArray;
}

// Function to create an array of two-digit non-zero numbers
export async function createRandomNumbersArray(count: number): Promise<number[]> {
  const numbersArray = [];

  for (let i = 0; i < count; i++) {
    let randomNumber = Math.floor(Math.random() * 99) + 1;
    numbersArray.push(randomNumber);
  }

  return numbersArray;
}

export function isLinuxEnvironment() {
    return process.platform === 'linux';
}

export function getOSSpecificTimeout(): number {
  // Increase base timeout for Linux
  const isLinux = process.platform === 'linux';
  return isLinux ? 180000 : 60000; // 3 minutes for Linux, 1 minute for others
}

export function getOSSpecificConfig() {
    if (isLinuxEnvironment()) {
        return {
            retries: 2,
            timeout: 90000,  // Increased global timeout
            expect: {
                timeout: 30000  // Increased expect timeout
            },
            // Add video recording for failed tests on Linux
            use: {
                video: 'retain-on-failure',
                trace: 'retain-on-failure'
            }
        };
    }
    return {};
}

// Add helper for test grouping
export function isResourceIntensiveTest(testPath: string): boolean {
    return testPath.includes('35-record-gift-from-image-share') || 
           testPath.includes('40-add-contact');
}
