import type { Page } from "@playwright/test";

export class LoginPage {
  private page: Page;
  constructor(page: Page) {
    this.page = page;
  }

  async goto() {
    await this.page.goto("/");
  }

  private async openAuthPage() {
    const maxAttempts = 2;
    let lastError: unknown;
    for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
      try {
        await this.page.getByRole("button", { name: "Sign in" }).click();
        await this.page.getByLabel(/email/i).waitFor();
        return;
      } catch (err) {
        lastError = err;
        if (attempt < maxAttempts - 1) {
          console.warn(`openAuthPage attempt ${attempt + 1}/${maxAttempts} failed, retrying`);
          await this.page.waitForTimeout(500);
        }
      }
    }
    throw lastError;
  }

  private async submitCredentials(email: string, password: string) {
    await this.page.getByLabel(/email/i).waitFor();
    await this.page.getByLabel(/email/i).fill(email);
    await this.page.getByPlaceholder("Password").fill(password);
    await this.page.getByPlaceholder("Password").press("Enter");
  }

  async login(email: string, password: string) {
    await this.goto();
    await this.openAuthPage();
    await this.submitCredentials(email, password);
    // Auth redirects through `/?code=...` before landing on the app root.
    // Waiting on networkidle is brittle here, so wait for the final app URL
    // and a stable post-login navigation element instead.
    await this.page.waitForURL((url) => url.pathname === "/" && !url.searchParams.has("code"), {
      waitUntil: "domcontentloaded",
    });
    await this.page.getByRole("link", { name: /users/i }).waitFor();
  }
}
