import { Browser } from 'playwright';
import { TOTP } from 'totp-generator';

import { defaultUserAdmin, routes } from '../../../config';
import { User } from '../../../types';
import { extractEmailSecret } from '../../db/extractEmailSecret';
import { waitForBase } from '../../waitForBase';
import { acceptRecovery } from '../acceptRecovery';
import { loginBasic } from '../login';
import { logout } from '../logout';

export type EnableEmailResult = {
  secret: string;
  recoveryCodes?: string[];
};

export const setupSMTP = async (browser: Browser) => {
  const context = await browser.newContext();
  const page = await context.newPage();
  await waitForBase(page);
  await loginBasic(page, defaultUserAdmin);
  await page.goto(routes.base + routes.settings.smtp);
  await page.getByTestId('smtp-card-basic-configure').click();
  await page.getByTestId('field-smtp_server').waitFor({ state: 'visible' });
  await page.getByTestId('field-smtp_server').fill('testServer.com');
  await page.getByTestId('field-smtp_port').fill('543');
  await page.getByTestId('field-smtp_user').fill('testuser');
  await page.getByTestId('field-smtp_password').fill('test');
  await page.getByTestId('field-smtp_sender').fill('test@test.com');
  const saveButton = await page.getByTestId('submit');
  if (await saveButton.isEnabled()) {
    await saveButton.click();
  }
  await logout(page);
  await context.close();
};

export const enableEmailMFA = async (
  browser: Browser,
  user: User,
): Promise<EnableEmailResult> => {
  await setupSMTP(browser);
  const context = await browser.newContext();
  const page = await context.newPage();
  await waitForBase(page);
  await loginBasic(page, user);
  await page.goto(routes.base + routes.profile + user.username);
  await page.getByTestId('email-codes-row').locator('.icon-button').click();
  await page.getByTestId('enable-email').click();
  await page.getByTestId('field-code').waitFor({ state: 'visible' });
  const secret = await extractEmailSecret(user.username);
  const { otp: code } = await TOTP.generate(secret, {
    digits: 6,
    period: 300,
  });
  await page.getByTestId('field-code').fill(code);
  await page.getByTestId('submit').click();
  const recovery = await acceptRecovery(page);
  await context.close();
  return {
    secret,
    recoveryCodes: recovery,
  };
};
