/**
 * Tests for FlightsMiniListItem — a single row in the flights mini-list sidebar.
 *
 * @vitest-environment jsdom
 */

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

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>
  ),
}));

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

function makeDirectFlight(overrides: Partial<IDirectFlight> = {}): IDirectFlight {
  return {
    id: "SU0022-20260416",
    routeType: "Direct" as const,
    flyingTime: "1h 30m",
    status: "Scheduled" as const,
    flightId: { carrier: "SU", flightNumber: "0022", suffix: "", date: "20260416" },
    operatingBy: {},
    leg: {
      arrival: {
        scheduled: { airport: "Pulkovo", airportCode: "LED", city: "St Petersburg", cityCode: "LED", countryCode: "RU" },
        latest: { airport: "Pulkovo", airportCode: "LED", city: "St Petersburg", cityCode: "LED", countryCode: "RU" },
        dispatch: "", gate: "", terminal: "",
        times: { scheduledArrival: { dayChange: { value: 0, title: "" }, local: "12:30", localTime: "12:30", tzOffset: 3, utc: "09:30" } },
      },
      dayChange: 0,
      departure: {
        scheduled: { airport: "Sheremetyevo", airportCode: "SVO", city: "Moscow", cityCode: "MOW", countryCode: "RU" },
        latest: { airport: "Sheremetyevo", airportCode: "SVO", city: "Moscow", cityCode: "MOW", countryCode: "RU" },
        dispatch: "", gate: "", terminal: "", checkingStatus: "Scheduled", parkingStand: "",
        times: { scheduledDeparture: { dayChange: { value: 0, title: "" }, local: "10:00", localTime: "10:00", tzOffset: 3, utc: "07:00" } },
      },
      equipment: {},
      flags: { checkinAvailable: false, returnToAirport: false, routeChanged: false },
      flyingTime: "1h 30m",
      index: 0,
      operatingBy: {},
      status: "Scheduled" as const,
      updated: "",
    },
    ...overrides,
  } as IDirectFlight;
}

describe("FlightsMiniListItem", () => {
  it("renders flight number", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    expect(screen.getByText(/SU\s*0022/)).toBeTruthy();
  });

  it("renders departure and arrival times", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    expect(screen.getByText("10:00")).toBeTruthy();
    expect(screen.getByText("12:30")).toBeTruthy();
  });

  it("renders departure and arrival station city + airport names", () => {
    // Angular parity: the mini-list item shows city name with airport name
    // as the underlined secondary line (not the IATA code).
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    expect(screen.getByText("Moscow")).toBeTruthy();
    expect(screen.getByText("St Petersburg")).toBeTruthy();
    expect(screen.getByText("Sheremetyevo")).toBeTruthy();
    expect(screen.getByText("Pulkovo")).toBeTruthy();
  });

  it("has data-testid based on flight id", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    expect(screen.getByTestId("mini-list-item-SU0022-20260416")).toBeTruthy();
  });

  it("applies selected modifier when isSelected", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={true} lang="ru" />);
    const item = screen.getByTestId("mini-list-item-SU0022-20260416");
    expect(item.className).toMatch(/--selected/);
  });

  it("does not apply selected modifier when not selected", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    const item = screen.getByTestId("mini-list-item-SU0022-20260416");
    expect(item.className).not.toMatch(/--selected/);
  });

  it("link points to the flight details URL", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    const link = screen.getByTestId("mini-list-item-SU0022-20260416") as HTMLAnchorElement;
    expect(link.getAttribute("href")).toBe("/ru/onlineboard/SU0022-20260416");
  });

  // ── TZ §4.1.15.2-R19 + §4.1.16.2-R19: SVO/VKO airport name as hyperlink ──

  it("4.1.15.2-R19: SVO airport code renders a role=link span with testid", () => {
    // Flight departure is SVO (Sheremetyevo). TZ requires it appears as a link.
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    const svoLink = screen.getByTestId("mini-list-airport-link-SVO");
    expect(svoLink).toBeTruthy();
    expect(svoLink.getAttribute("role")).toBe("link");
  });

  it("4.1.15.2-R19: SVO link opens www.svo.aero/ru/main on click via window.open", () => {
    const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    const svoLink = screen.getByTestId("mini-list-airport-link-SVO");
    svoLink.click();
    expect(openSpy).toHaveBeenCalledWith(
      "https://www.svo.aero/ru/main",
      "_blank",
      "noopener,noreferrer",
    );
    openSpy.mockRestore();
  });

  it("4.1.15.2-R20: VKO airport code renders a role=link span with testid", () => {
    // Use a flight whose departure is VKO.
    const vkoFlight = makeDirectFlight({
      leg: {
        ...makeDirectFlight().leg,
        departure: {
          ...makeDirectFlight().leg.departure,
          scheduled: {
            airport: "Vnukovo",
            airportCode: "VKO",
            city: "Moscow",
            cityCode: "MOW",
            countryCode: "RU",
          },
        },
      },
    });
    render(<FlightsMiniListItem flight={vkoFlight} isSelected={false} lang="ru" />);
    const vkoLink = screen.getByTestId("mini-list-airport-link-VKO");
    expect(vkoLink).toBeTruthy();
    expect(vkoLink.getAttribute("role")).toBe("link");
  });

  it("4.1.15.2-R20: VKO link opens www.vnukovo.ru on click via window.open", () => {
    const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
    const vkoFlight = makeDirectFlight({
      leg: {
        ...makeDirectFlight().leg,
        departure: {
          ...makeDirectFlight().leg.departure,
          scheduled: {
            airport: "Vnukovo",
            airportCode: "VKO",
            city: "Moscow",
            cityCode: "MOW",
            countryCode: "RU",
          },
        },
      },
    });
    render(<FlightsMiniListItem flight={vkoFlight} isSelected={false} lang="ru" />);
    const vkoLink = screen.getByTestId("mini-list-airport-link-VKO");
    vkoLink.click();
    expect(openSpy).toHaveBeenCalledWith(
      "http://www.vnukovo.ru",
      "_blank",
      "noopener,noreferrer",
    );
    openSpy.mockRestore();
  });

  it("4.1.15.2-R18: non-SVO/VKO airports render as plain div (no role=link)", () => {
    // Arrival is LED (Pulkovo) — no hyperlink needed
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    expect(screen.queryByTestId("mini-list-airport-link-LED")).toBeNull();
  });

  it("4.1.15.2-R18: renders departure and arrival dates", () => {
    const flight = makeDirectFlight();
    render(<FlightsMiniListItem flight={flight} isSelected={false} lang="ru" />);
    // Dep time local is "10:00", arr time is "12:30" — dates are derived from ISO strings
    expect(screen.getByText("10:00")).toBeTruthy();
    expect(screen.getByText("12:30")).toBeTruthy();
  });
});
