/**
 * header.steps.ts
 * Step definitions for unified App Header testing
 */

import { Given, When, Then, expect } from '../fixtures/bdd-fixtures';

// Header Navigation & Title Steps

Then('the app header should be visible', async ({ page }) => {
  const header = page.locator('header').first();
  await expect(header).toBeVisible();
});

Then('the page title should show {string} with icon', async ({ page }, title: string) => {
  const heading = page.getByRole('heading', { name: new RegExp(title, 'i') });
  await expect(heading).toBeVisible();
});

// Header Navigation Links - Navigate to pages

When('I click on the {string} link in the header', async ({ page }, linkName: string) => {
  const pageKey = mapPageName(linkName);
  const link = page.getByTestId(`header-nav-${pageKey}`);
  await expect(link).toBeVisible();
  await link.click();
  await page.waitForLoadState('networkidle').catch(() => {});
});

Then('I should be on the {string} page', async ({ page }, pageName: string) => {
  const path = mapPagePath(pageName);
  await expect(page).toHaveURL(new RegExp(path));
});

Then('the {string} link in the header should be highlighted', async ({ page }, linkName: string) => {
  const pageKey = mapPageName(linkName);
  const link = page.getByTestId(`header-nav-${pageKey}`);
  // Check for active state (font-bold and text-gold)
  const classes = await link.getAttribute('class');
  expect(classes).toMatch(/font-bold|text-gold/);
});

// Scoring Card Steps

Then('the scoring card should be visible', async ({ page }) => {
  const scoringCard = page.getByTestId('scoring-card');
  await expect(scoringCard).toBeVisible();
});

Then('the gold value should be displayed', async ({ page }) => {
  const goldCard = page.getByTestId('scoring-card-gold');
  await expect(goldCard).toBeVisible();
});

Then('the completed quests count should be displayed', async ({ page }) => {
  const questsCard = page.getByTestId('scoring-card-quests');
  await expect(questsCard).toBeVisible();
});

Then('the average savings value should show {string}', async ({ page }, expectedValue: string) => {
  const savingsCard = page.getByTestId('scoring-card-savings');
  await expect(savingsCard).toContainText(expectedValue);
});

Then('the average savings percentage should be displayed', async ({ page }) => {
  const savingsCard = page.getByTestId('scoring-card-savings');
  const savingsText = await savingsCard.textContent();
  // Should contain a percentage value (e.g., "15.50%") not "—"
  expect(savingsText).toMatch(/%/);
});

// Logout Steps (specific to header)

When('I click the {string} button in the header', async ({ page }, buttonName: string) => {
  const button = page.getByTestId('header-logout-button');
  await expect(button).toBeVisible();
  await button.click();
  // Wait for navigation or redirect
  await page.waitForTimeout(1000);
});

// Then 'I should be logged out' and 'I should be redirected to the login page' already exist in common.steps.ts

// Responsive Steps

When('I resize the browser to mobile size', async ({ page }) => {
  await page.setViewportSize({ width: 375, height: 667 });
});

Then('the header should be visible and functional', async ({ page }) => {
  const header = page.locator('header').first();
  await expect(header).toBeVisible();
});

Then('navigation links should be accessible', async ({ page }) => {
  const viewportWidth = page.viewportSize()?.width ?? 1280;
  const isMobile = viewportWidth < 768;

  if (isMobile) {
    // On mobile the nav is hidden behind the hamburger menu.
    // Verify the hamburger toggle exists and opens the nav.
    const hamburger = page.getByTestId('header-mobile-menu-btn');
    await expect(hamburger).toBeVisible();

    // Open the menu and confirm the nav becomes visible
    await hamburger.click();
    const nav = page.getByTestId('header-navigation');
    await expect(nav).toBeVisible();

    // Close the menu again to leave the page in a clean state
    await hamburger.click();
  } else {
    // On desktop the nav is always visible
    const nav = page.getByTestId('header-navigation');
    await expect(nav).toBeVisible();
  }
});

// Dynamic Update Steps

When('I complete a quest from the dashboard', async ({ page }) => {
  // Find and click a "Complete Quest" button
  const completeButton = page.getByRole('button', { name: /complete quest/i }).first();
  if (await completeButton.isVisible({ timeout: 2000 }).catch(() => false)) {
    await completeButton.click();
  }
  // Wait for the update
  await page.waitForTimeout(1000);
});

Then('the completed quests count in the header should increase', async ({ page }) => {
  const questsCard = page.getByTestId('scoring-card-quests');
  await expect(questsCard).toBeVisible();
  const text = await questsCard.textContent();
  expect(text).toBeTruthy();
});

Then('the scoring card should reflect the new count', async ({ page }) => {
  const scoringCard = page.getByTestId('scoring-card');
  await expect(scoringCard).toBeVisible();
});

// Zero Values Step

Then('the scoring card should show:', async ({ page }, table: any) => {
  const rows = table.hashes();
  for (const row of rows) {
    const label = row.field;
    const value = row.value;
    
    if (label === 'gold') {
      const goldCard = page.getByTestId('scoring-card-gold');
      await expect(goldCard).toContainText(value);
    } else if (label === 'completed quests') {
      const questsCard = page.getByTestId('scoring-card-quests');
      await expect(questsCard).toContainText(value);
    } else if (label === 'average savings') {
      const savingsCard = page.getByTestId('scoring-card-savings');
      await expect(savingsCard).toContainText(value);
    }
  }
});

// ===== Helper Functions =====

function mapPageName(pageName: string): string {
  const mapping: Record<string, string> = {
    'Dashboard': 'dashboard',
    'Quests': 'quests',
    'Middle-Earth Map': 'map',
    'Inventory': 'inventory',
  };
  return mapping[pageName] || pageName.toLowerCase();
}

function mapPagePath(pageName: string): string {
  const mapping: Record<string, string> = {
    'dashboard': '/dashboard',
    'quests': '/quests',
    'map': '/map',
    'inventory': '/inventory',
  };
  return mapping[pageName.toLowerCase()] || `/${pageName.toLowerCase()}`;
}
