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

/**
 * Page Object Model for Navigation
 * Encapsulates header nav, footer nav, and mobile menu interactions
 */
export class NavigationPage {
  readonly page: Page;
  readonly header: Locator;
  readonly footer: Locator;
  readonly logo: Locator;
  readonly mobileMenuButton: Locator;

  readonly navLinks = {
    home: '/href="/"',
    about: '/about',
    services: '/services',
    portfolio: '/portfolio',
    blog: '/blog',
    contact: '/contact',
  };

  constructor(page: Page) {
    this.page = page;
    this.header = page.locator('header');
    this.footer = page.locator('footer');
    this.logo = page.locator('header a').first();
    this.mobileMenuButton = page.locator('button[aria-label*="menu"], button[aria-expanded], [data-menu-toggle]').first();
  }

  async clickNavLink(path: string) {
    await this.page.locator(`header a[href="${path}"]`).first().click();
    await expect(this.page).toHaveURL(path);
  }

  async openMobileMenu() {
    if (await this.mobileMenuButton.isVisible()) {
      await this.mobileMenuButton.click();
      await this.page.waitForTimeout(300); // Wait for animation
    }
  }

  async closeMobileMenu() {
    if (await this.mobileMenuButton.isVisible()) {
      const isOpen = await this.mobileMenuButton.getAttribute('aria-expanded');
      if (isOpen === 'true') {
        await this.mobileMenuButton.click();
        await this.page.waitForTimeout(300);
      }
    }
  }

  async scrollToFooter() {
    await this.footer.scrollIntoViewIfNeeded();
    await this.page.waitForTimeout(200);
  }

  async clickFooterLink(path: string) {
    const link = this.footer.locator(`a[href="${path}"]`).first();
    await link.click();
    await expect(this.page).toHaveURL(path);
  }

  async verifyNoHorizontalOverflow(tolerance = 20) {
    const bodyWidth = await this.page.evaluate(() => document.body.scrollWidth);
    const viewportWidth = this.page.viewportSize()?.width ?? 1280;
    expect(bodyWidth).toBeLessThanOrEqual(viewportWidth + tolerance);
  }
}
