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

/**
 * Base page object that all page objects inherit from
 * Contains common methods and properties used across pages
 */
export class BasePage {
  protected readonly page: Page;
  protected readonly baseUrl: string = 'https://wordpress-974670-5399585.cloudwaysapps.com';

  constructor(page: Page) {
    this.page = page;
  }

  /**
   * Log a message to the console
   */
  protected log(message: string): void {
    console.log(`[${this.constructor.name}] ${message}`);
  }

  /**
   * Wait for page to be fully loaded
   */
  async waitForPageLoad(): Promise<void> {
    await this.page.waitForLoadState('domcontentloaded');
    await this.page.waitForLoadState('networkidle');
  }

  /**
   * Get the current page title
   */
  async getTitle(): Promise<string> {
    return await this.page.title();
  }

  /**
   * Get the current page URL
   */
  async getUrl(): Promise<string> {
    return this.page.url();
  }

  /**
   * Navigate to a specific URL path
   * @param path The path to navigate to (relative to baseUrl)
   */
  async navigateTo(path: string): Promise<void> {
    await this.page.goto(`${this.baseUrl}${path}`);
    await this.waitForPageLoad();
  }

  /**
   * Take a screenshot and return the buffer
   * @param name Optional name for the screenshot
   */
  async takeScreenshot(name?: string): Promise<Buffer> {
    const screenshotName = name || `${this.constructor.name}-${new Date().getTime()}`;
    return await this.page.screenshot({ 
      path: `./screenshots/${screenshotName}.png`,
      fullPage: true 
    });
  }

  /**
   * Check if an element is visible on the page
   * @param selector The selector for the element
   */
  async isVisible(selector: string): Promise<boolean> {
    return await this.page.isVisible(selector);
  }

  /**
   * Get text content of an element
   * @param selector The selector for the element
   */
  async getText(selector: string): Promise<string | null> {
    return await this.page.textContent(selector);
  }

  /**
   * Click an element and wait for navigation
   * @param selector The selector for the element to click
   */
  async clickAndWaitForNavigation(selector: string): Promise<void> {
    await Promise.all([
      this.page.waitForNavigation(),
      this.page.click(selector)
    ]);
    await this.waitForPageLoad();
  }
}