/**
 * Tests for OnlineBoardDetailsPage component.
 *
 * Verifies rendering in loading, error, not-found, and success states.
 *
 * @vitest-environment jsdom
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen } from "@testing-library/react";
import { OnlineBoardDetailsPage } from "./OnlineBoardDetailsPage.js";
import type { IParsedFlightId, IDirectFlight, IMultiLegFlight, IFlightLeg } from "../types.js";

const mockFlightId: IParsedFlightId = {
  carrier: "SU",
  flightNumber: "100",
  date: "20250115",
};

const mockFlight: IDirectFlight = {
  id: "SU100-20250115",
  flightId: { carrier: "SU", flightNumber: "100", suffix: "", date: "20250115" },
  routeType: "Direct",
  status: "Scheduled",
  flyingTime: "10:30",
  operatingBy: {},
  leg: {
    index: 0,
    status: "Scheduled",
    flyingTime: "10:30",
    dayChange: 0,
    updated: "2025-01-15T00:00:00Z",
    operatingBy: {},
    equipment: { name: "Boeing 777-300ER", code: "77W" },
    flags: { checkinAvailable: false, returnToAirport: false, routeChanged: false },
    departure: {
      scheduled: {
        airport: "Sheremetyevo",
        airportCode: "SVO",
        city: "Moscow",
        cityCode: "MOW",
        countryCode: "RU",
      },
      checkingStatus: "open",
      times: {
        scheduledDeparture: {
          dayChange: { value: 0, title: "" },
          local: "10:00",
          localTime: "10:00",
          tzOffset: 3,
          utc: "07:00",
        },
      },
    },
    arrival: {
      scheduled: {
        airport: "John F. Kennedy",
        airportCode: "JFK",
        city: "New York",
        cityCode: "NYC",
        countryCode: "US",
      },
      times: {
        scheduledArrival: {
          dayChange: { value: 0, title: "" },
          local: "14:30",
          localTime: "14:30",
          tzOffset: -5,
          utc: "19:30",
        },
      },
    },
  },
};

// Mutable state for test control
let mockState = {
  flight: mockFlight as IDirectFlight | IMultiLegFlight | null,
  allFlights: [mockFlight] as (IDirectFlight | IMultiLegFlight)[],
  daysOfFlight: ["20250115"] as string[],
  loading: false,
  error: null as Error | null,
};

vi.mock("../hooks/useFlightDetails.js", () => ({
  useFlightDetails: () => mockState,
}));

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

vi.mock("../hooks/useLiveFlightDetails.js", () => ({
  useLiveFlightDetails: (_id: unknown, initialFlight: unknown) => ({
    flight: initialFlight,
    connectionStatus: "idle" as const,
  }),
}));

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

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

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

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

describe("OnlineBoardDetailsPage", () => {
  beforeEach(() => {
    mockState = {
      flight: mockFlight,
      allFlights: [mockFlight],
      daysOfFlight: ["20250115"],
      loading: false,
      error: null,
    };
  });

  it("renders flight details", () => {
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    expect(screen.getByTestId("flight-details")).toBeTruthy();
    // "SU 100" appears in both the header and FlightCard
    expect(screen.getAllByText("SU 100").length).toBeGreaterThanOrEqual(1);
  });

  it("renders loading skeleton", () => {
    mockState = { flight: null, allFlights: [], daysOfFlight: [], loading: true, error: null };
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    expect(screen.queryByTestId("flight-details")).toBeNull();
  });

  it("renders error state", () => {
    mockState = { flight: null, allFlights: [], daysOfFlight: [], loading: false, error: new Error("fail") };
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    expect(screen.getByTestId("flight-details-error")).toBeTruthy();
  });

  it("renders not-found state", () => {
    mockState = { flight: null, allFlights: [], daysOfFlight: [], loading: false, error: null };
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    expect(screen.getByTestId("flight-details-not-found")).toBeTruthy();
  });

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

  it("displays departure and arrival stations", () => {
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    // SVO and JFK appear in both FlightCard and FlightLegs sections
    expect(screen.getAllByText("SVO").length).toBeGreaterThanOrEqual(1);
    expect(screen.getAllByText("JFK").length).toBeGreaterThanOrEqual(1);
  });

  it("displays aircraft info", () => {
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    expect(screen.getByText("Aircraft: Boeing 777-300ER (77W)")).toBeTruthy();
  });

  it("displays flying time", () => {
    render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://www.aeroflot.ru" />);
    expect(screen.getByTestId("flying-time")).toBeTruthy();
    expect(screen.getByText("Total flying time: 10:30")).toBeTruthy();
  });

  describe("accordion integration", () => {
    it("does not render accordion when leg has no transition or extended equipment", () => {
      // Default mockFlight has no transition/equipment.aircraft/meal/services
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.queryByTestId("flight-details-accordion")).toBeNull();
    });

    it("renders accordion when leg has transition data", () => {
      const flightWithTransition: IDirectFlight = {
        ...mockFlight,
        leg: {
          ...mockFlight.leg,
          transition: {
            registration: {
              start: {
                dayChange: { value: 0, title: "" },
                local: "10:00",
                localTime: "10:00",
                tzOffset: 0,
                utc: "10:00",
              },
              end: {
                dayChange: { value: 0, title: "" },
                local: "",
                localTime: "",
                tzOffset: 0,
                utc: "",
              },
              status: "InProgress",
              isActual: true,
            },
          },
        },
      };
      mockState = { flight: flightWithTransition, allFlights: [flightWithTransition], daysOfFlight: ["20250115"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.getByTestId("flight-details-accordion")).toBeTruthy();
    });
  });

  describe("mini-list integration", () => {
    it("renders mini-list when multiple flights are returned", () => {
      const first = mockFlight;
      const second = { ...mockFlight, id: "SU0022-20260417", flightId: { ...mockFlight.flightId, date: "20260417" } };
      mockState = { flight: first, allFlights: [first, second], daysOfFlight: ["20250115", "20260417"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.getByTestId("flights-mini-list")).toBeTruthy();
    });

    it("does not render mini-list when only one flight is returned", () => {
      mockState = { flight: mockFlight, allFlights: [mockFlight], daysOfFlight: ["20250115"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.queryByTestId("flights-mini-list")).toBeNull();
    });

    it("renders inside PageLayout (has page-layout class)", () => {
      mockState = { flight: mockFlight, allFlights: [mockFlight], daysOfFlight: ["20250115"], loading: false, error: null };
      const { container } = render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(container.querySelector(".page-layout")).toBeTruthy();
    });
  });

  describe("day tabs integration", () => {
    it("renders DayTabs as sticky content", () => {
      mockState = { flight: mockFlight, allFlights: [mockFlight], daysOfFlight: ["20260416"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.getByTestId("day-tabs")).toBeTruthy();
    });
  });

  describe("board details header integration", () => {
    it("renders BoardDetailsHeader at top of details", () => {
      mockState = { flight: mockFlight, allFlights: [mockFlight], daysOfFlight: ["20260416"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.getByTestId("board-details-header")).toBeTruthy();
    });
  });

  describe("back button integration", () => {
    it("renders DetailsBackButton in headerLeft", () => {
      mockState = { flight: mockFlight, allFlights: [mockFlight], daysOfFlight: ["20260416"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.getByTestId("details-back-button")).toBeTruthy();
    });
  });

  describe("multi-leg timeline integration", () => {
    function makeLeg(index: number, overrides: Partial<IFlightLeg> = {}): IFlightLeg {
      return {
        ...mockFlight.leg,
        index,
        ...overrides,
      } as IFlightLeg;
    }

    it("does not render FullRouteTimeline for Direct flights", () => {
      render(
        <OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />,
      );
      expect(screen.queryByTestId("full-route-timeline")).toBeNull();
      expect(screen.queryByTestId("transfer-bar")).toBeNull();
    });

    it("renders FullRouteTimeline for MultiLeg flights", () => {
      const multiLeg: IMultiLegFlight = {
        id: "SU100-20250115",
        flightId: { carrier: "SU", flightNumber: "100", suffix: "", date: "20250115" },
        routeType: "MultiLeg",
        status: "Scheduled",
        flyingTime: "12:00",
        operatingBy: {},
        legs: [makeLeg(0), makeLeg(1)],
      };
      mockState = {
        flight: multiLeg,
        allFlights: [multiLeg],
        daysOfFlight: ["20250115"],
        loading: false,
        error: null,
      };
      render(
        <OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />,
      );
      expect(screen.getByTestId("full-route-timeline")).toBeTruthy();
    });

    it("interleaves one TransferBar between two legs", () => {
      const multiLeg: IMultiLegFlight = {
        id: "SU100-20250115",
        flightId: { carrier: "SU", flightNumber: "100", suffix: "", date: "20250115" },
        routeType: "MultiLeg",
        status: "Scheduled",
        flyingTime: "12:00",
        operatingBy: {},
        legs: [makeLeg(0), makeLeg(1)],
      };
      mockState = {
        flight: multiLeg,
        allFlights: [multiLeg],
        daysOfFlight: ["20250115"],
        loading: false,
        error: null,
      };
      render(
        <OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />,
      );
      expect(screen.getAllByTestId("transfer-bar")).toHaveLength(1);
    });
  });

  describe("flight schedule integration", () => {
    it("renders FlightSchedule when firstLeg.daysOfWeek is present", () => {
      const flightWithDaysOfWeek = {
        ...mockFlight,
        leg: {
          ...mockFlight.leg,
          daysOfWeek: { current: "1000010", flight: "1111111" },
        },
      };
      mockState = { flight: flightWithDaysOfWeek, allFlights: [flightWithDaysOfWeek], daysOfFlight: ["20260416"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.getByTestId("flight-schedule")).toBeTruthy();
    });

    it("does not render FlightSchedule when daysOfWeek is absent", () => {
      mockState = { flight: mockFlight, allFlights: [mockFlight], daysOfFlight: ["20260416"], loading: false, error: null };
      render(<OnlineBoardDetailsPage flightId={mockFlightId} locale="ru" canonicalOrigin="https://example.com" />);
      expect(screen.queryByTestId("flight-schedule")).toBeNull();
    });
  });
});
