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

// ─── Constants ─────────────────────────────────────────────────────────────
export const BASE_URL = process.env.BASE_URL || 'http://127.0.0.1:3001';

export const TEST_USER = {
  username: 'e2etest',
  password: 'Test12345!',
  email: 'e2etest@cucunote.local',
};

// ─── Helpers ───────────────────────────────────────────────────────────────

/**
 * Sign in via Auth.tsx form using real data-testid selectors.
 * Returns true on success, false on failure.
 */
export async function login(
  page: Page,
  username = TEST_USER.username,
  password = TEST_USER.password,
): Promise<boolean> {
  // Already logged in
  if (page.url().includes('/app')) return true;

  await page.goto(`${BASE_URL}/auth`, { waitUntil: 'domcontentloaded' });

  // If redirect lands on /app already
  if (page.url().includes('/app')) return true;

  try {
    await page.locator('[data-testid="auth-username"]').waitFor({ state: 'visible', timeout: 15000 });
    await page.locator('[data-testid="auth-username"]').fill(username);
    await page.locator('[data-testid="auth-password"]').fill(password);
    await page.locator('[data-testid="auth-submit"]').click();
    await page.waitForURL(/\/app/, { timeout: 20000 });
    return true;
  } catch (e) {
    console.warn('[auth helper] login failed:', e);
    return false;
  }
}

/**
 * Register a new account. Returns the username created.
 */
export async function register(
  page: Page,
  username: string,
  password: string,
  email: string,
): Promise<boolean> {
  await page.goto(`${BASE_URL}/auth?mode=signup`, { waitUntil: 'domcontentloaded' });

  try {
    await page.locator('[data-testid="auth-username"]').waitFor({ state: 'visible', timeout: 12000 });
    await page.locator('[data-testid="auth-username"]').fill(username);

    const emailInput = page.locator('[data-testid="auth-email"]');
    if (await emailInput.isVisible({ timeout: 2000 }).catch(() => false)) {
      await emailInput.fill(email);
    }

    await page.locator('[data-testid="auth-password"]').fill(password);
    await page.locator('[data-testid="auth-submit"]').click();
    await page.waitForURL(/\/app/, { timeout: 20000 });
    return true;
  } catch (e) {
    console.warn('[auth helper] register failed:', e);
    return false;
  }
}

/**
 * Ensures the test user exists and is logged in.
 * First tries login; if it fails (user doesn't exist), registers then logs in.
 */
export async function ensureLoggedIn(page: Page): Promise<void> {
  const loggedIn = await login(page);
  if (!loggedIn) {
    // Try registering the test user
    await register(page, TEST_USER.username, TEST_USER.password, TEST_USER.email);
  }
  await expect(page).toHaveURL(/\/app/, { timeout: 15000 });
}

/**
 * Clear all auth state (cookies + storage) to simulate logged-out state.
 */
export async function clearAuthState(page: Page): Promise<void> {
  await page.context().clearCookies();
  await page.evaluate(() => {
    try {
      window.localStorage.clear();
      window.sessionStorage.clear();
    } catch {}
  });
}
