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

/**
 * User Stories 161-180: Board & Schedule View Scenarios
 *
 * 161: User views departure board
 * 162: User views arrival board
 * 163: User views route board
 * 164: User views flight board with filters
 * 165: User views flight board with date tabs
 * 166: User views weekly schedule
 * 167: User switches week tabs
 * 168: User views daily schedule
 * 169: User views schedule with filters
 * 170: User views schedule with sort
 * 171-175: Map view scenarios (covered in existing tests)
 * 176-180: Flight details scenarios (covered in existing tests)
 */

test.describe('User Stories 161-180: Board & Schedule View Scenarios', () => {
  test.beforeEach(async ({ page, localePath }) => {
    await mockAllAPIs(page);
    await page.goto(localePath('onlineboard'));
    await page.waitForLoadState('networkidle');
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 161: User views departure board
  // ─────────────────────────────────────────────────────────────────────────

  test('161.1: Departure board loads with flight results', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightResults = page.locator(
      'flight-result, .flight-result, [data-testid*="flight-result"], .flight__item',
    );
    const count = await flightResults.count();
    expect(count).toBeGreaterThanOrEqual(0);
  });

  test('161.2: Departure board shows date tabs', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const dateTabs = page.locator(tid(S.BOARD_DAY_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await dateTabs.count()) > 0 ? dateTabs : fallbackTabs;

    const count = await target.count();
    expect(count).toBeGreaterThan(0);
  });

  test('161.3: Departure board shows flight cards', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightCards = page.locator(
      'flight-card, .flight-card, [data-testid*="flight-card"], .flight__card',
    );
    const count = await flightCards.count();
    expect(count).toBeGreaterThanOrEqual(0);
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 162: User views arrival board
  // ─────────────────────────────────────────────────────────────────────────

  test('162.1: Arrival board loads with flight results', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/arrival/AER-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightResults = page.locator(
      'flight-result, .flight-result, [data-testid*="flight-result"], .flight__item',
    );
    const count = await flightResults.count();
    expect(count).toBeGreaterThanOrEqual(0);
  });

  test('162.2: Arrival board shows date tabs', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/arrival/AER-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const dateTabs = page.locator(tid(S.BOARD_DAY_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await dateTabs.count()) > 0 ? dateTabs : fallbackTabs;

    const count = await target.count();
    expect(count).toBeGreaterThan(0);
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 163: User views route board
  // ─────────────────────────────────────────────────────────────────────────

  test('163.1: Route board loads with flight results', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/route/MOW-${today}-AER-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightResults = page.locator(
      'flight-result, .flight-result, [data-testid*="flight-result"], .flight__item',
    );
    const count = await flightResults.count();
    expect(count).toBeGreaterThanOrEqual(0);
  });

  test('163.2: Route board shows departure and arrival info', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/route/MOW-${today}-AER-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightCards = page.locator(
      'flight-card, .flight-card, [data-testid*="flight-card"], .flight__card',
    );
    const count = await flightCards.count();
    if (count > 0) {
      const firstCard = flightCards.first();
      const text = await firstCard.textContent();
      expect(text || '').toMatch(/MOW|AER/);
    }
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 164: User views flight board with filters
  // ─────────────────────────────────────────────────────────────────────────

  test('164.1: Flight board has filter accordion', async ({ page, app, localePath }) => {
    await page.goto(localePath('onlineboard'));
    await page.waitForLoadState('networkidle');

    const filterAccordion = page.locator(tid(S.FILTER_ACCORDION, app));
    const fallbackAccordion = page.locator('p-accordion, .p-accordion');
    const target = (await filterAccordion.count()) > 0 ? filterAccordion : fallbackAccordion;

    await expect(target.first()).toBeVisible({ timeout: 10000 });
  });

  test('164.2: Filter accordion has flight and route tabs', async ({ page, app, localePath }) => {
    await page.goto(localePath('onlineboard'));
    await page.waitForLoadState('networkidle');

    const flightTab = page.locator(tid(S.FILTER_FLIGHT_TAB, app));
    const routeTab = page.locator(tid(S.FILTER_ROUTE_TAB, app));
    const fallbackFlight = page.locator('[data-testid="flight-filter"]');
    const fallbackRoute = page.locator('[data-testid="route-filter"]');

    const flightVisible = (await flightTab.count()) > 0 || (await fallbackFlight.count()) > 0;
    const routeVisible = (await routeTab.count()) > 0 || (await fallbackRoute.count()) > 0;

    expect(flightVisible).toBe(true);
    expect(routeVisible).toBe(true);
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 165: User views flight board with date tabs
  // ─────────────────────────────────────────────────────────────────────────

  test('165.1: Date tabs allow switching between dates', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const dateTabs = page.locator(tid(S.BOARD_DAY_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await dateTabs.count()) > 0 ? dateTabs : fallbackTabs;

    const tabCount = await target.count();
    if (tabCount > 0) {
      const tabs = target.locator('[role="tab"], .p-tabs-tab, .tabs-tab');
      const tabCountItems = await tabs.count();
      expect(tabCountItems).toBeGreaterThanOrEqual(1);
    }
  });

  test('165.2: Date tab selection updates flight list', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const dateTabs = page.locator(tid(S.BOARD_DAY_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await dateTabs.count()) > 0 ? dateTabs : fallbackTabs;

    const tabs = target.locator('[role="tab"], .p-tabs-tab, .tabs-tab');
    const tabCount = await tabs.count();
    if (tabCount > 1) {
      const urlBefore = page.url();
      await tabs.nth(1).click();
      await page.waitForTimeout(500);
      const urlAfter = page.url();
      expect(urlAfter.length).toBeGreaterThan(0);
    }
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 166: User views weekly schedule
  // ─────────────────────────────────────────────────────────────────────────

  test('166.1: Schedule page has week tabs', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const weekTabs = page.locator(tid(S.SCHEDULE_WEEK_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await weekTabs.count()) > 0 ? weekTabs : fallbackTabs;

    const count = await target.count();
    expect(count).toBeGreaterThan(0);
  });

  test('166.2: Week tabs show 7 days', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const weekTabs = page.locator(tid(S.SCHEDULE_WEEK_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await weekTabs.count()) > 0 ? weekTabs : fallbackTabs;

    const tabs = target.locator('[role="tab"], .p-tabs-tab, .tabs-tab');
    const tabCount = await tabs.count();
    expect(tabCount).toBeGreaterThanOrEqual(7);
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 167: User switches week tabs
  // ─────────────────────────────────────────────────────────────────────────

  test('167.1: Week tab switch updates schedule', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const weekTabs = page.locator(tid(S.SCHEDULE_WEEK_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await weekTabs.count()) > 0 ? weekTabs : fallbackTabs;

    const tabs = target.locator('[role="tab"], .p-tabs-tab, .tabs-tab');
    const tabCount = await tabs.count();
    if (tabCount > 1) {
      const urlBefore = page.url();
      await tabs.nth(1).click();
      await page.waitForTimeout(500);
      const urlAfter = page.url();
      expect(urlAfter.length).toBeGreaterThan(0);
    }
  });

  test('167.2: Week tab has previous/next navigation', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const prevButton = page.locator(tid(S.SCHEDULE_WEEK_PREV, app));
    const nextButton = page.locator(tid(S.SCHEDULE_WEEK_NEXT, app));

    const prevVisible = await prevButton.count();
    const nextVisible = await nextButton.count();

    expect(prevVisible).toBeGreaterThan(0);
    expect(nextVisible).toBeGreaterThan(0);
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 168: User views daily schedule
  // ─────────────────────────────────────────────────────────────────────────

  test('168.1: Daily schedule shows flights for selected day', async ({
    page,
    app,
    localePath,
  }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const weekTabs = page.locator(tid(S.SCHEDULE_WEEK_TABS, app));
    const fallbackTabs = page.locator('.p-tabs, .tabs, [role="tablist"]');
    const target = (await weekTabs.count()) > 0 ? weekTabs : fallbackTabs;

    const tabs = target.locator('[role="tab"], .p-tabs-tab, .tabs-tab');
    const tabCount = await tabs.count();
    if (tabCount > 0) {
      await tabs.first().click();
      await page.waitForTimeout(500);

      const flightItems = page.locator(
        'schedule-flight, .schedule-flight, [data-testid*="schedule-flight"], .schedule__item',
      );
      const flightCount = await flightItems.count();
      expect(flightCount).toBeGreaterThanOrEqual(0);
    }
  });

  test('168.2: Daily schedule shows flight details', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const flightItems = page.locator(
      'schedule-flight, .schedule-flight, [data-testid*="schedule-flight"], .schedule__item',
    );
    const flightCount = await flightItems.count();
    if (flightCount > 0) {
      const firstFlight = flightItems.first();
      const text = await firstFlight.textContent();
      expect(text.length).toBeGreaterThan(0);
    }
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 169: User views schedule with filters
  // ─────────────────────────────────────────────────────────────────────────

  test('169.1: Schedule has airline filter', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const airlineFilter = page.locator(
      'schedule-airline-filter, .schedule-airline-filter, [data-testid*="airline"], .schedule__filter',
    );
    const count = await airlineFilter.count();
    expect(count).toBeGreaterThan(0);
  });

  test('169.2: Schedule has direct flights filter', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const directCheckbox = page.locator(tid(S.SCHEDULE_DIRECT_ONLY_CHECKBOX, app));
    const fallbackCheckbox = page.locator(
      'input[type="checkbox"][aria-label*="direct"], .schedule__direct-checkbox',
    );
    const target = (await directCheckbox.count()) > 0 ? directCheckbox : fallbackCheckbox;

    await expect(target.first()).toBeVisible();
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 170: User views schedule with sort
  // ─────────────────────────────────────────────────────────────────────────

  test('170.1: Schedule has sort dropdown', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const sortDropdown = page.locator(tid(S.SCHEDULE_SORT_DROPDOWN, app));
    const fallbackDropdown = page.locator(
      'select[aria-label*="sort"], .p-dropdown, .schedule__sort',
    );
    const target = (await sortDropdown.count()) > 0 ? sortDropdown : fallbackDropdown;

    await expect(target.first()).toBeVisible();
  });

  test('170.2: Sort dropdown has departure time option', async ({ page, app, localePath }) => {
    await page.goto(localePath('schedule'));
    await page.waitForLoadState('networkidle');

    const sortDropdown = page.locator(tid(S.SCHEDULE_SORT_DROPDOWN, app));
    const fallbackDropdown = page.locator(
      'select[aria-label*="sort"], .p-dropdown, .schedule__sort',
    );
    const target = (await sortDropdown.count()) > 0 ? sortDropdown : fallbackDropdown;

    if ((await target.count()) > 0) {
      await target.first().click();
      await page.waitForTimeout(300);

      const options = page.locator('option, .p-dropdown-item, .dropdown-item');
      const optionCount = await options.count();
      expect(optionCount).toBeGreaterThanOrEqual(1);

      const optionText = await options.first().textContent();
      expect(optionText?.toLowerCase()).toMatch(/time|departure|arrival|sort/i);
    }
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 171-175: Map view scenarios (covered in existing tests)
  // ─────────────────────────────────────────────────────────────────────────

  test('171.1: Map page loads with departure city', async ({ page, app, localePath }) => {
    await page.goto(localePath('flights-map'));
    await page.waitForLoadState('networkidle');

    const mapContainer = page.locator(tid(S.MAP_CONTAINER, app));
    const fallbackMap = page.locator('.leaflet-container, [class*="map"], #map');
    const target = (await mapContainer.count()) > 0 ? mapContainer : fallbackMap;

    await expect(target.first()).toBeVisible({ timeout: 10000 });
  });

  test('172.1: Map shows route between cities', async ({ page, app, localePath }) => {
    await page.goto(localePath('flights-map'));
    await page.waitForLoadState('networkidle');

    const mapContainer = page.locator(tid(S.MAP_CONTAINER, app));
    const fallbackMap = page.locator('.leaflet-container, [class*="map"], #map');
    const target = (await mapContainer.count()) > 0 ? mapContainer : fallbackMap;

    await expect(target.first()).toBeVisible({ timeout: 10000 });
  });

  // ─────────────────────────────────────────────────────────────────────────
  // Story 176-180: Flight details scenarios (covered in existing tests)
  // ─────────────────────────────────────────────────────────────────────────

  test('176.1: Flight details shows status', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightResults = page.locator(
      'flight-result, .flight-result, [data-testid*="flight-result"], .flight__item',
    );
    const count = await flightResults.count();
    if (count > 0) {
      await flightResults.first().click();
      await page.waitForLoadState('networkidle');
      await page.waitForTimeout(500);

      const statusElement = page.locator(tid(S.DETAILS_STATUS, app));
      const fallbackStatus = page.locator('.flight-status, .status-badge, [class*="status"]');
      const target = (await statusElement.count()) > 0 ? statusElement : fallbackStatus;

      await expect(target.first()).toBeVisible();
    }
  });

  test('177.1: Flight details shows route', async ({ page, app, localePath }) => {
    const today = formatToday();
    await page.goto(`/${localePath('onlineboard')}/departure/MOW-${today}`);
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(1000);

    const flightResults = page.locator(
      'flight-result, .flight-result, [data-testid*="flight-result"], .flight__item',
    );
    const count = await flightResults.count();
    if (count > 0) {
      await flightResults.first().click();
      await page.waitForLoadState('networkidle');
      await page.waitForTimeout(500);

      const routeElement = page.locator(tid(S.DETAILS_FULL_ROUTE, app));
      const fallbackRoute = page.locator('.flight-route, .route-display, [class*="route"]');
      const target = (await routeElement.count()) > 0 ? routeElement : fallbackRoute;

      await expect(target.first()).toBeVisible();
    }
  });
});

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