/**
 * Integration tests for the Online Board flight details page.
 *
 * Verifies flight info renders with mocked API data including
 * flight number, status, legs, operating carrier, and SEO head.
 *
 * @vitest-environment jsdom
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen } from "@testing-library/react";
import { OnlineBoardDetailsPage } from "@/features/online-board/components/OnlineBoardDetailsPage.js";
import type { IParsedFlightId, ISimpleFlight } from "@/features/online-board/types.js";
import { DIRECT_FLIGHT, MULTI_LEG_FLIGHT } from "./fixtures.js";

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

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

vi.mock("@/ui/layout/PageTabs.js", () => ({
  PageTabs: () => <div data-testid="page-tabs" />,
}));

vi.mock("@/features/flights-map/hooks/useFeatureFlag.js", () => ({
  useFeatureFlag: () => false,
}));

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

const mockUseFlightDetails = vi.fn();
vi.mock("@/features/online-board/hooks/useFlightDetails.js", () => ({
  useFlightDetails: (...args: unknown[]) => mockUseFlightDetails(...args),
}));

const mockUseLiveFlightDetails = vi.fn();
vi.mock("@/features/online-board/hooks/useLiveFlightDetails.js", () => ({
  useLiveFlightDetails: (...args: unknown[]) => mockUseLiveFlightDetails(...args),
}));

vi.mock("@/shared/hooks/useAppSettings.js", () => ({
  useAppSettings: () => ({
    onlineboardSearchFrom: 2,
    onlineboardSearchTo: 14,
    scheduleSearchFrom: 30,
    scheduleSearchTo: 30,
    loading: false,
    error: null,
  }),
}));

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

const FLIGHT_ID: IParsedFlightId = {
  carrier: "SU",
  flightNumber: "0100",
  date: "20250115",
};

function setupWithFlight(flight: ISimpleFlight = DIRECT_FLIGHT) {
  mockUseFlightDetails.mockReturnValue({
    flight,
    allFlights: [flight],
    daysOfFlight: ["20250115"],
    loading: false,
    error: null,
  });
  mockUseLiveFlightDetails.mockReturnValue({
    flight,
    connectionStatus: "idle" as const,
  });
}

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

describe("Flight details page integration", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("renders flight details container", () => {
    setupWithFlight();
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("flight-details")).toBeTruthy();
  });

  it("renders flight number heading", () => {
    setupWithFlight();
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    // Flight number appears in both heading and FlightCard
    expect(screen.getAllByText("SU 0100").length).toBeGreaterThanOrEqual(1);
  });

  it("renders flight status", () => {
    setupWithFlight();
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    // Status appears in both overall status and leg status
    expect(screen.getAllByText("Scheduled").length).toBeGreaterThanOrEqual(1);
  });

  it("renders flight legs for direct flight", () => {
    setupWithFlight(DIRECT_FLIGHT);
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("flight-legs")).toBeTruthy();
    expect(screen.getByTestId("flight-leg-0")).toBeTruthy();
  });

  it("renders multiple legs for multi-leg flight", () => {
    setupWithFlight(MULTI_LEG_FLIGHT);
    render(
      <OnlineBoardDetailsPage
        flightId={{
          carrier: "SU",
          flightNumber: "0300",
          date: "20250115",
        }}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("flight-leg-0")).toBeTruthy();
    expect(screen.getByTestId("flight-leg-1")).toBeTruthy();
  });

  it("renders FullRouteTimeline and a TransferBar between legs for multi-leg", () => {
    setupWithFlight(MULTI_LEG_FLIGHT);
    render(
      <OnlineBoardDetailsPage
        flightId={{
          carrier: "SU",
          flightNumber: "0300",
          date: "20250115",
        }}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("full-route-timeline")).toBeTruthy();
    expect(screen.getAllByTestId("transfer-bar")).toHaveLength(1);
    // transfer-bar should include the intermediate-landing label and a computed transfer-time
    const bar = screen.getByTestId("transfer-bar");
    expect(bar.textContent).toContain("SHARED.INTERMEDIATE-LANDING");
    expect(bar.querySelector('[data-testid="transfer-time"]')).toBeTruthy();
  });

  it("does not render FullRouteTimeline or TransferBar for direct flight", () => {
    setupWithFlight(DIRECT_FLIGHT);
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.queryByTestId("full-route-timeline")).toBeNull();
    expect(screen.queryByTestId("transfer-bar")).toBeNull();
  });

  it("renders operating carrier info", () => {
    setupWithFlight();
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("operating-carrier")).toBeTruthy();
    expect(screen.getByText(/Operated by: SU/)).toBeTruthy();
  });

  it("renders flying time", () => {
    setupWithFlight();
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("flying-time")).toBeTruthy();
  });

  it("renders error state when API fails", () => {
    mockUseFlightDetails.mockReturnValue({
      flight: null,
      allFlights: [],
      daysOfFlight: [],
      loading: false,
      error: new Error("API error"),
    });
    mockUseLiveFlightDetails.mockReturnValue({
      flight: null,
      connectionStatus: "idle" as const,
    });

    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("flight-details-error")).toBeTruthy();
  });

  it("renders not-found state when flight is null without error", () => {
    mockUseFlightDetails.mockReturnValue({
      flight: null,
      allFlights: [],
      daysOfFlight: [],
      loading: false,
      error: null,
    });
    mockUseLiveFlightDetails.mockReturnValue({
      flight: null,
      connectionStatus: "idle" as const,
    });

    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    expect(screen.getByTestId("flight-details-not-found")).toBeTruthy();
  });

  it("renders airport codes in leg stations", () => {
    setupWithFlight();
    render(
      <OnlineBoardDetailsPage
        flightId={FLIGHT_ID}
        locale="ru"
        canonicalOrigin="https://www.aeroflot.ru"
      />,
    );
    // Airport codes appear in both FlightCard and FlightLegs
    expect(screen.getAllByText("SVO").length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText("JFK").length).toBeGreaterThanOrEqual(1);
  });
});
