/**
 * Integration tests for the Online Board start page.
 *
 * Verifies the page layout renders with accordion filter tabs,
 * info tiles, and page tabs matching the e2e test expectations.
 *
 * @vitest-environment jsdom
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import { OnlineBoardStartPage } from "@/features/online-board/components/OnlineBoardStartPage.js";

// ---------------------------------------------------------------------------
// Mocks
// ---------------------------------------------------------------------------

const navigateSpy = vi.fn();

vi.mock("@modern-js/runtime/router", () => ({
  useNavigate: () => navigateSpy,
  useParams: () => ({ lang: "ru-ru" }),
  useLocation: () => ({ state: null, pathname: "/ru/onlineboard" }),
  Link: ({ children, to, ...props }: { children: React.ReactNode; to: string; [k: string]: unknown }) => (
    <a href={to} {...props}>{children}</a>
  ),
}));

vi.mock("@/i18n/provider.js", () => ({
  useTranslation: () => ({
    t: (key: string) => key,
  }),
}));

vi.mock("@/features/popular-requests/components/PopularRequestsPanel.js", () => ({
  PopularRequestsPanel: () => <div data-testid="popular-requests">Popular</div>,
}));

vi.mock("@/shared/hooks/useCitySearch.js", () => ({
  useCitySearch: () => ({ suggestions: [], search: vi.fn() }),
}));

vi.mock("@/shared/hooks/useSearchHistory.js", () => ({
  useSearchHistory: () => ({ items: [], add: vi.fn(), clear: vi.fn() }),
}));

vi.mock("@/shared/dictionaries/index.js", () => ({
  useDictionaries: () => ({ dictionaries: null, loading: false, error: null }),
  findCityByCoord: () => null,
}));

vi.mock("@/features/online-board/hooks/useCalendarDays.js", () => ({
  useCalendarDays: () => ({ days: [], loading: false }),
}));

vi.mock("@/ui/city-autocomplete/index.js", () => ({
  CityAutocomplete: (props: Record<string, unknown>) => (
    <input
      data-testid={`${(props["testIdPrefix"] as string) ?? "city-autocomplete"}-input`}
      placeholder={props["placeholder"] as string}
    />
  ),
  SwapCityButton: (props: { onClick: () => void; testId?: string }) => (
    <button type="button" data-testid={props.testId} onClick={props.onClick} />
  ),
}));

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

describe("Start page integration", () => {
  beforeEach(() => {
    vi.clearAllMocks();

    // Stub matchMedia for useIsMobileViewport (jsdom doesn't implement it).
    Object.defineProperty(window, "matchMedia", {
      value: vi.fn().mockImplementation((query: string) => ({
        matches: false,
        media: query,
        addEventListener: () => {},
        removeEventListener: () => {},
        dispatchEvent: () => false,
      })),
      configurable: true,
    });

    // Stub geolocation for useGeoCityDefault (jsdom doesn't implement it).
    Object.defineProperty(navigator, "geolocation", {
      value: {
        getCurrentPosition: vi.fn().mockImplementation(
          (_s: PositionCallback, onErr: PositionErrorCallback) => {
            onErr({ code: 1, message: "denied" } as GeolocationPositionError);
          },
        ),
      },
      configurable: true,
    });
  });

  it("renders the page layout with data-testid", () => {
    render(<OnlineBoardStartPage />);
    expect(screen.getByTestId("online-board-start")).toBeTruthy();
  });

  it("renders page tabs for onlineboard and schedule", () => {
    render(<OnlineBoardStartPage />);
    expect(screen.getByTestId("onlineboard-tab")).toBeTruthy();
    expect(screen.getByTestId("schedule-tab")).toBeTruthy();
  });

  it("renders the search form with flight filter", () => {
    render(<OnlineBoardStartPage />);
    expect(screen.getByTestId("flight-filter")).toBeTruthy();
    expect(screen.getByTestId("search-form")).toBeTruthy();
  });

  it.skip("shows flight number input in the flight filter by default", () => {
    // Filter now defaults to route tab; flight number input only renders when flight tab is selected
    render(<OnlineBoardStartPage />);
    expect(screen.getByTestId("flight-number-input")).toBeTruthy();
  });

  it("renders all 4 info tiles", () => {
    render(<OnlineBoardStartPage />);
    expect(screen.getByText("BOARD.BOARD-START-TITLE1")).toBeTruthy();
    expect(screen.getByText("BOARD.BOARD-START-TITLE2")).toBeTruthy();
    expect(screen.getByText("BOARD.BOARD-START-TITLE3")).toBeTruthy();
    expect(screen.getByText("BOARD.BOARD-START-TITLE4")).toBeTruthy();
  });

  it("renders the info section heading", () => {
    render(<OnlineBoardStartPage />);
    expect(screen.getByText("BOARD.BOARD-START")).toBeTruthy();
  });

  it("renders the popular requests panel", () => {
    render(<OnlineBoardStartPage />);
    expect(screen.getByTestId("popular-requests")).toBeTruthy();
  });

  it.skip("navigates to correct URL on flight search submit", () => {
    // Filter now defaults to route tab; flight submit test requires switching tabs first
    render(<OnlineBoardStartPage />);
    const input = screen.getByTestId("flight-number-input");
    // User enters just the number (SU prefix is built in)
    fireEvent.change(input, { target: { value: "0100" } });

    const form = screen.getByTestId("search-form");
    fireEvent.submit(form);

    expect(navigateSpy).toHaveBeenCalledTimes(1);
    const url = navigateSpy.mock.calls[0]?.[0] as string;
    expect(url).toMatch(/^\/ru\/onlineboard\/flight\/SU/);
  });

  it("switches to route tab and shows route fields", () => {
    render(<OnlineBoardStartPage />);
    // Click the route accordion header
    const routeHeader = screen.getByTestId("search-type-route");
    const routeLink = routeHeader.querySelector("a");
    expect(routeLink).toBeTruthy();
    fireEvent.click(routeLink!);
    expect(screen.getByTestId("route-departure-input")).toBeTruthy();
    expect(screen.getByTestId("route-arrival-input")).toBeTruthy();
  });
});
