import { test, expect } from '../support/cross-app-fixtures';
import { mockAllAPIs } from '../support/cross-app-fixtures';
import { S, tid } from '../support/selectors';

test.describe('Navigation & Layout', () => {
  test.beforeEach(async ({ page, localePath }) => {
    await mockAllAPIs(page);
    await page.goto(localePath('onlineboard'));
    await page.waitForLoadState('networkidle');
  });

  test('1: Tab "Online Board" is visible and active by default', async ({ page, app }) => {
    const tab = page.locator(tid(S.NAV_ONLINEBOARD_TAB, app));
    await expect(tab).toBeVisible();
    await expect(tab).toHaveClass(/active|selected/);
  });

  test('2: Tab "Schedule" navigates to schedule page', async ({ page, app, locale }) => {
    const tab = page.locator(tid(S.NAV_SCHEDULE_TAB, app));
    await expect(tab).toBeVisible();
    await tab.click();
    await expect(page).toHaveURL(new RegExp(`/${locale}/schedule`));
  });

  test('3: Tab "Flights Map" navigates to flights map page', async ({ page, app, locale }) => {
    const tab = page.locator(tid(S.NAV_FLIGHTS_MAP_TAB, app));
    await expect(tab).toBeVisible();
    await tab.click();
    await expect(page).toHaveURL(new RegExp(`/${locale}/flights-map`));
  });

  test('4: Tab active state matches current route', async ({ page, app, locale }) => {
    // Navigate to schedule
    await page.goto(`/${locale}/schedule`);
    await page.waitForLoadState('networkidle');
    const scheduleTab = page.locator(tid(S.NAV_SCHEDULE_TAB, app));
    await expect(scheduleTab).toHaveClass(/active|selected/);
    const boardTab = page.locator(tid(S.NAV_ONLINEBOARD_TAB, app));
    await expect(boardTab).not.toHaveClass(/active|selected/);
  });

  test('5: Breadcrumbs show correct path on landing', async ({ page, app }) => {
    const breadcrumbs = page.locator(tid(S.LAYOUT_BREADCRUMBS, app));
    // Angular uses PrimeNG p-breadcrumb without data-testid; fall back to tag selector
    const fallback = page.locator('p-breadcrumb, nav[aria-label*="bread"]');
    const target = (await breadcrumbs.count()) > 0 ? breadcrumbs : fallback;
    await expect(target).toBeVisible();
  });

  test('6: Breadcrumbs show correct path on search results', async ({
    page,
    app,
    locale,
    localePath,
  }) => {
    // Navigate to a departure search
    const path = `onlineboard/departure/MOW-${formatToday()}`;
    const url = localePath(path);
    console.log('Test 6 URL:', url);
    await page.goto(url, {
      waitUntil: 'domcontentloaded',
    });
    console.log('Test 6 Current URL:', page.url());
    const breadcrumbs = page.locator(tid(S.LAYOUT_BREADCRUMBS, app));
    const fallback = page.locator('p-breadcrumb, nav[aria-label*="bread"]');
    const target = (await breadcrumbs.count()) > 0 ? breadcrumbs : fallback;
    await expect(target).toBeVisible();
    // Should have at least 1 link
    const links = target.locator('a');
    expect(await links.count()).toBeGreaterThanOrEqual(1);
  });

  test('7: Breadcrumbs show correct path on flight details', async ({ page, app, locale }) => {
    // Navigate to a search first, then open details
    await page.goto(`/${locale}/onlineboard/departure/MOW-${formatToday()}`);
    await page.waitForLoadState('networkidle');
    const firstFlight = page.locator(tid(S.BOARD_FLIGHT_RESULT, app)).first();
    // If results exist, click through to details
    const count = await firstFlight.count();
    if (count > 0) {
      await firstFlight.click();
      await page.waitForLoadState('networkidle');
      const breadcrumbs = page.locator(tid(S.LAYOUT_BREADCRUMBS, app));
      const fallback = page.locator('p-breadcrumb, nav[aria-label*="bread"]');
      const target = (await breadcrumbs.count()) > 0 ? breadcrumbs : fallback;
      await expect(target).toBeVisible();
      expect(await target.locator('a').count()).toBeGreaterThanOrEqual(2);
    }
  });

  test('8: Breadcrumbs links are clickable and navigate correctly', async ({
    page,
    app,
    locale,
  }) => {
    await page.goto(`/${locale}/schedule`);
    await page.waitForLoadState('networkidle');
    const breadcrumbs = page.locator(tid(S.LAYOUT_BREADCRUMBS, app));
    const fallback = page.locator('p-breadcrumb, nav[aria-label*="bread"]');
    const target = (await breadcrumbs.count()) > 0 ? breadcrumbs : fallback;
    const links = target.locator('a');
    if ((await links.count()) > 0) {
      // The first breadcrumb link typically navigates home or to main section
      const firstHref = await links.first().getAttribute('href');
      expect(firstHref).toBeTruthy();
    }
  });

  test('14: Feedback button is visible in layout', async ({ page, app }) => {
    const button = page.locator(tid(S.LAYOUT_FEEDBACK_BUTTON, app));
    if ((await button.count()) === 0) {
      test.skip(true, 'Feedback button not present in this app');
      return;
    }
    await expect(button).toBeVisible();
  });

  test('15: Feedback button opens feedback form on click', async ({ page, app }) => {
    const button = page.locator(tid(S.LAYOUT_FEEDBACK_BUTTON, app));
    if ((await button.count()) === 0) {
      test.skip(true, 'Feedback button not present in this app');
      return;
    }
    await button.click();
    await expect(page.locator('[role="dialog"], .feedback-form, .modal')).toBeVisible({
      timeout: 5000,
    });
  });

  test('16: Scroll-to-top button appears after scrolling down', async ({ page, app }) => {
    const scrollBtn = page.locator(tid(S.LAYOUT_SCROLL_TOP_BUTTON, app));
    // Some apps may not have this feature
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(500);
    if ((await scrollBtn.count()) === 0) {
      test.skip(true, 'Scroll-to-top button not present in this app');
      return;
    }
    await expect(scrollBtn).toBeVisible({ timeout: 5000 });
  });

  test('17: Scroll-to-top button scrolls page to top on click', async ({ page, app }) => {
    const scrollBtn = page.locator(tid(S.LAYOUT_SCROLL_TOP_BUTTON, app));
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(500);
    if ((await scrollBtn.count()) === 0) {
      test.skip(true, 'Scroll-to-top button not present in this app');
      return;
    }
    await expect(scrollBtn).toBeVisible({ timeout: 5000 });
    await scrollBtn.click();
    await page.waitForTimeout(500);
    const scrollY = await page.evaluate(() => window.scrollY);
    expect(scrollY).toBeLessThan(100);
  });

  test('18: Scroll-to-top button hides when at top', async ({ page, app }) => {
    const scrollBtn = page.locator(tid(S.LAYOUT_SCROLL_TOP_BUTTON, app));
    if ((await scrollBtn.count()) === 0) {
      test.skip(true, 'Scroll-to-top button not present in this app');
      return;
    }
    // At top of page, button should be hidden
    await expect(scrollBtn).toBeHidden();
  });
});

function formatToday(timeFrom = '0000', timeTo = '2359'): string {
  const d = new Date();
  const dateStr = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}`;
  return `${dateStr}-${timeFrom}${timeTo}`;
}
