import type { Browser } from "webdriverio";
import { TestIDs } from "./selectors";

const DEFAULT_TIMEOUT = 15_000;

/**
 * Build a UiAutomator selector for a resource-id.
 * React Native on Android maps testID to resource-id (not content-desc).
 */
function byTestId(testId: string): string {
  return `android=new UiSelector().resourceId("${testId}")`;
}

/**
 * Wait for an element with the given testID to exist and be displayed.
 */
export async function waitForTestId(
  driver: Browser,
  testId: string,
  timeout = DEFAULT_TIMEOUT,
) {
  const element = driver.$(byTestId(testId));
  await element.waitForDisplayed({ timeout });
  return element;
}

/**
 * Check if an element with the given testID is currently visible.
 */
export async function isTestIdVisible(
  driver: Browser,
  testId: string,
): Promise<boolean> {
  try {
    const element = driver.$(byTestId(testId));
    return await element.isDisplayed();
  } catch {
    return false;
  }
}

/**
 * Navigate to the login screen. If already logged in (auto-login),
 * go to Settings and tap Logout first.
 */
export async function ensureOnLoginScreen(driver: Browser): Promise<void> {
  const onLogin = await isTestIdVisible(driver, TestIDs.LOGIN_TITLE);
  if (onLogin) return;

  // We're on the main app — navigate to Settings and logout
  const settingsTab = driver.$(byTestId(TestIDs.TAB_SETTINGS));
  await settingsTab.waitForDisplayed({ timeout: DEFAULT_TIMEOUT });
  await settingsTab.click();

  const logoutButton = await waitForTestId(
    driver,
    TestIDs.SETTINGS_LOGOUT_BUTTON,
  );
  await logoutButton.click();

  // Wait for login screen to appear
  await waitForTestId(driver, TestIDs.LOGIN_TITLE);
}

/**
 * Perform login with the given credentials.
 */
export async function performLogin(
  driver: Browser,
  identifier: string,
  password: string,
): Promise<void> {
  const identifierInput = await waitForTestId(
    driver,
    TestIDs.LOGIN_IDENTIFIER_INPUT,
  );
  await identifierInput.clearValue();
  await identifierInput.setValue(identifier);

  const passwordInput = await waitForTestId(
    driver,
    TestIDs.LOGIN_PASSWORD_INPUT,
  );
  await passwordInput.clearValue();
  await passwordInput.setValue(password);

  const loginButton = await waitForTestId(driver, TestIDs.LOGIN_BUTTON);
  await loginButton.click();
}

/**
 * Ensure the user is logged in. If on the login screen, perform login
 * with test credentials.
 */
export async function ensureLoggedIn(driver: Browser): Promise<void> {
  const testUser = process.env.TEST_USER || "test";
  const testPassword = process.env.TEST_PASSWORD || "test";

  const onLogin = await isTestIdVisible(driver, TestIDs.LOGIN_TITLE);
  if (onLogin) {
    await performLogin(driver, testUser, testPassword);
    // Wait for chat screen to appear after login
    await waitForTestId(driver, TestIDs.CHAT_MESSAGE_INPUT, 30_000);
  }
}
