// @vitest-environment jsdom
/**
 * TZ §4.1.13.3 — Collapsed row audit (Tables 23–27)
 *
 * Each test maps to a specific column requirement from the TZ tables
 * and is labelled with the table + column reference for traceability.
 */
import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { FlightCard } from "./FlightCard.js";
import type { ISimpleFlight } from "@/features/online-board/types.js";

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

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

vi.mock("@/i18n/useLocale.js", () => ({
  useLocale: () => ({ language: "ru" }),
}));

vi.mock("@/shared/hooks/useDictionaries.js", () => ({
  useCityName: (code: string) => {
    const map: Record<string, string> = { SVO: "Москва", LED: "Санкт-Петербург" };
    return map[code] ?? "";
  },
}));

// IFlyWarning tries to render inside expanded panels but we only test collapsed
vi.mock("./IFlyWarning.js", () => ({
  IFlyWarning: () => null,
}));

// ---------------------------------------------------------------------------
// Fixture helpers
// ---------------------------------------------------------------------------

function makeTimesSet(local: string, dayChangeValue = 0) {
  return {
    dayChange: { value: dayChangeValue, title: "" },
    local,
    localTime: local.slice(11, 16),
    tzOffset: 0,
    utc: local,
  };
}

function makeLeg(overrides: {
  depCode?: string;
  depCity?: string;
  depAirport?: string;
  depTerminal?: string;
  depLocal?: string;
  depActualLocal?: string;
  depDayChange?: number;
  arrCode?: string;
  arrCity?: string;
  arrAirport?: string;
  arrTerminal?: string;
  arrLocal?: string;
  arrActualLocal?: string;
  arrDayChange?: number;
  routeChanged?: boolean;
  returnToAirport?: boolean;
  aircraftTitle?: string;
}) {
  const depLocal = overrides.depLocal ?? "2026-04-15T10:00:00+03:00";
  const arrLocal = overrides.arrLocal ?? "2026-04-15T12:30:00+03:00";

  return {
    dayChange: 0,
    index: 0,
    flyingTime: "02:30:00",
    status: "Scheduled" as const,
    updated: "",
    operatingBy: {},
    flags: {
      checkinAvailable: false,
      returnToAirport: overrides.returnToAirport ?? false,
      routeChanged: overrides.routeChanged ?? false,
    },
    equipment: {
      aircraft: overrides.aircraftTitle
        ? { actual: { title: overrides.aircraftTitle } }
        : undefined,
    },
    departure: {
      scheduled: {
        airport: overrides.depAirport ?? "Шереметьево",
        airportCode: overrides.depCode ?? "SVO",
        city: overrides.depCity ?? "Москва",
        cityCode: "MOW",
        countryCode: "RU",
      },
      terminal: overrides.depTerminal,
      checkingStatus: "Scheduled",
      times: {
        scheduledDeparture: makeTimesSet(depLocal, overrides.depDayChange ?? 0),
        ...(overrides.depActualLocal
          ? { actualBlockOff: makeTimesSet(overrides.depActualLocal, overrides.depDayChange ?? 0) }
          : {}),
      },
    },
    arrival: {
      scheduled: {
        airport: overrides.arrAirport ?? "Пулково",
        airportCode: overrides.arrCode ?? "LED",
        city: overrides.arrCity ?? "Санкт-Петербург",
        cityCode: "LED",
        countryCode: "RU",
      },
      terminal: overrides.arrTerminal,
      times: {
        scheduledArrival: makeTimesSet(arrLocal, overrides.arrDayChange ?? 0),
        ...(overrides.arrActualLocal
          ? { actualBlockOn: makeTimesSet(overrides.arrActualLocal, overrides.arrDayChange ?? 0) }
          : {}),
      },
    },
  };
}

function makeFlight(overrides: Parameters<typeof makeLeg>[0] & {
  status?: ISimpleFlight["status"];
  operatingByCarrier?: string;
  operatingByFlightNum?: string;
}): ISimpleFlight {
  return {
    id: "test-flight",
    routeType: "Direct",
    flyingTime: "02:30:00",
    status: overrides.status ?? "Scheduled",
    flightId: { carrier: "SU", flightNumber: "0022", suffix: "", date: "20260415" },
    operatingBy: {
      actual: overrides.operatingByCarrier ?? "SU",
      ...(overrides.operatingByFlightNum !== undefined
        ? { flightNumber: overrides.operatingByFlightNum }
        : {}),
    },
    leg: makeLeg(overrides) as never,
  };
}

function makeMultiLegFlight(legs: ReturnType<typeof makeLeg>[]): ISimpleFlight {
  return {
    id: "test-multi-flight",
    routeType: "MultiLeg",
    flyingTime: "05:00:00",
    status: "Scheduled",
    flightId: { carrier: "SU", flightNumber: "0100", suffix: "", date: "20260415" },
    operatingBy: { actual: "SU" },
    legs: legs as never[],
  };
}

// ---------------------------------------------------------------------------
// §4.1.13.3 Table 23 — Direct flight collapsed row
// ---------------------------------------------------------------------------

describe("4.1.13.3 Table 23 — Direct flight collapsed row", () => {

  it("T23-C1: renders marketing flight number in collapsed row", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    expect(screen.getByTestId("flight-carrier-number").textContent).toContain("SU 0022");
  });

  it("T23-C2: renders operator logo (full, not mini/round) for direct flight", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    const logo = screen.getByTestId("operator-logo");
    expect(logo).toBeTruthy();
    // full logo has no --round class
    expect(logo.className).not.toContain("operator-logo--round");
  });

  it("T23-C3: renders scheduled departure time", () => {
    render(<FlightCard flight={makeFlight({ depLocal: "2026-04-15T10:00:00+03:00" })} expandable />);
    expect(screen.getByText("10:00")).toBeTruthy();
  });

  it("T23-C3: shows actual departure time when available and scheduled is struck through", () => {
    render(
      <FlightCard
        flight={makeFlight({
          depLocal: "2026-04-15T10:00:00+03:00",
          depActualLocal: "2026-04-15T11:30:00+03:00",
        })}
        expandable
      />,
    );
    // actual time shown
    expect(screen.getByText("11:30")).toBeTruthy();
    // scheduled shown struck-through
    const struck = document.querySelector(".time-group__scheduled--delayed");
    expect(struck).toBeTruthy();
    expect(struck?.textContent).toContain("10:00");
  });

  it("T23-C4: renders +1 day-change chip on departure when dayChange=1", () => {
    render(
      <FlightCard
        flight={makeFlight({ depDayChange: 1 })}
        expandable
      />,
    );
    const chips = document.querySelectorAll(".time-group__day-change");
    const depChip = Array.from(chips).find((el) => el.textContent === "+1");
    expect(depChip).toBeTruthy();
  });

  it("T23-C4: day-change chip has tooltip (title) per TZ §4.1.4", () => {
    render(
      <FlightCard
        flight={makeFlight({ depDayChange: 1 })}
        expandable
      />,
    );
    const chips = document.querySelectorAll(".time-group__day-change");
    const depChip = Array.from(chips).find((el) => el.textContent === "+1");
    // TZ requires a tooltip ("день" for ±1, date for ≥2)
    expect(depChip?.getAttribute("title")).toBeTruthy();
  });

  it("T23-C4: -1 day-change chip renders correctly", () => {
    render(
      <FlightCard
        flight={makeFlight({ depDayChange: -1 })}
        expandable
      />,
    );
    const chips = document.querySelectorAll(".time-group__day-change");
    const chip = Array.from(chips).find((el) => el.textContent === "-1");
    expect(chip).toBeTruthy();
  });

  it("T23-C5: renders departure city name", () => {
    render(<FlightCard flight={makeFlight({ depCity: "Москва" })} expandable />);
    expect(screen.getByText("Москва")).toBeTruthy();
  });

  it("T23-C6: renders departure airport name", () => {
    render(<FlightCard flight={makeFlight({ depAirport: "Шереметьево" })} expandable />);
    expect(screen.getByText(/Шереметьево/)).toBeTruthy();
  });

  it("T23-C7: renders departure terminal when present", () => {
    render(<FlightCard flight={makeFlight({ depTerminal: "B" })} expandable />);
    expect(screen.getByText(/B/)).toBeTruthy();
  });

  it("T23-C7: does not render departure terminal section when absent", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    // Should not show "— undefined" or similar artefacts
    const text = document.body.textContent ?? "";
    expect(text).not.toContain("undefined");
  });

  it("T23-C8: renders flight status chip with plane icon", () => {
    render(<FlightCard flight={makeFlight({ status: "Delayed" })} expandable />);
    // FlightStatus renders inside flight-card__status
    const statusEl = document.querySelector(".flight-card__status");
    expect(statusEl).toBeTruthy();
    // status plane SVG present
    expect(statusEl?.querySelector("svg")).toBeTruthy();
  });

  it("T23-C8: status text key is rendered for each status", () => {
    const statuses: ISimpleFlight["status"][] = [
      "Scheduled", "Sent", "InFlight", "Landed", "Arrived", "Delayed", "Cancelled", "Unknown",
    ];
    for (const status of statuses) {
      const { unmount } = render(<FlightCard flight={makeFlight({ status })} expandable />);
      expect(screen.getByText(`FLIGHT-STATUSES.${status}`)).toBeTruthy();
      unmount();
    }
  });

  it("T23-C9: renders scheduled arrival time", () => {
    render(<FlightCard flight={makeFlight({ arrLocal: "2026-04-15T12:30:00+03:00" })} expandable />);
    expect(screen.getByText("12:30")).toBeTruthy();
  });

  it("T23-C10: renders +1 day-change chip on arrival when arrDayChange=1", () => {
    render(
      <FlightCard
        flight={makeFlight({ arrDayChange: 1 })}
        expandable
      />,
    );
    const chips = document.querySelectorAll(".time-group__day-change");
    const arrChip = Array.from(chips).find((el) => el.textContent === "+1");
    expect(arrChip).toBeTruthy();
  });

  it("T23-C10: arrival day-change chip has tooltip (title) per TZ §4.1.4", () => {
    render(
      <FlightCard
        flight={makeFlight({ arrDayChange: 1 })}
        expandable
      />,
    );
    const chips = document.querySelectorAll(".time-group__day-change");
    const arrChip = Array.from(chips).find((el) => el.textContent === "+1");
    expect(arrChip?.getAttribute("title")).toBeTruthy();
  });

  it("T23-C11: renders arrival city name", () => {
    render(<FlightCard flight={makeFlight({ arrCity: "Санкт-Петербург" })} expandable />);
    expect(screen.getByText("Санкт-Петербург")).toBeTruthy();
  });

  it("T23-C12: renders arrival airport name", () => {
    render(<FlightCard flight={makeFlight({ arrAirport: "Пулково" })} expandable />);
    expect(screen.getByText(/Пулково/)).toBeTruthy();
  });

  it("T23-C13: renders arrival terminal when present", () => {
    render(<FlightCard flight={makeFlight({ arrTerminal: "D" })} expandable />);
    expect(screen.getByText(/D/)).toBeTruthy();
  });

  it("T23-C14: renders expand/collapse chevron when expandable=true", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    expect(document.querySelector(".flight-card__chevron")).toBeTruthy();
  });

  it("T23-C14: chevron rotates to open state when row is expanded", () => {
    render(<FlightCard flight={makeFlight({})} expandable initialExpanded />);
    expect(document.querySelector(".flight-card__chevron--open")).toBeTruthy();
  });
});

// ---------------------------------------------------------------------------
// §4.1.13.3 Table 24 — Multi-leg / connecting flight collapsed row
// ---------------------------------------------------------------------------

describe("4.1.13.3 Table 24 — Multi-leg flight collapsed row", () => {

  it("T24-C1: renders flight number for multi-leg flight", () => {
    const legs = [makeLeg({}), makeLeg({ depCode: "LED", arrCode: "AER" })];
    const flight = makeMultiLegFlight(legs);
    render(<FlightCard flight={flight} expandable />);
    expect(screen.getByTestId("flight-carrier-number").textContent).toContain("SU 0100");
  });

  it("T24-C2: renders an operator logo per leg", () => {
    const legs = [makeLeg({}), makeLeg({ depCode: "LED", arrCode: "AER" })];
    const flight = makeMultiLegFlight(legs);
    render(<FlightCard flight={flight} expandable />);
    const logos = screen.getAllByTestId("operator-logo");
    expect(logos.length).toBeGreaterThanOrEqual(1);
  });

  it("T24-C15: renders route-changed icon when flags.routeChanged=true", () => {
    const legs = [makeLeg({ routeChanged: true }), makeLeg({ depCode: "LED", arrCode: "AER" })];
    const flight = makeMultiLegFlight(legs);
    render(<FlightCard flight={flight} expandable />);
    expect(screen.getByTestId("flight-event-change-route")).toBeTruthy();
  });

  it("T24-C16: renders return-to-airport icon when flags.returnToAirport=true", () => {
    const legs = [makeLeg({ returnToAirport: true }), makeLeg({ depCode: "LED", arrCode: "AER" })];
    const flight = makeMultiLegFlight(legs);
    render(<FlightCard flight={flight} expandable />);
    expect(screen.getByTestId("flight-event-reroute")).toBeTruthy();
  });

  it("T24-C15+16: does NOT render flag icons when flags are false", () => {
    const legs = [makeLeg({}), makeLeg({ depCode: "LED", arrCode: "AER" })];
    const flight = makeMultiLegFlight(legs);
    render(<FlightCard flight={flight} expandable />);
    expect(document.querySelector("[data-testid='flight-event-change-route']")).toBeNull();
    expect(document.querySelector("[data-testid='flight-event-reroute']")).toBeNull();
  });

  it("T24-C15: renders route-changed icon for direct flight with routeChanged=true", () => {
    render(
      <FlightCard
        flight={makeFlight({ routeChanged: true })}
        expandable
      />,
    );
    expect(screen.getByTestId("flight-event-change-route")).toBeTruthy();
  });

  it("T24-C16: renders return-to-airport icon for direct flight with returnToAirport=true", () => {
    render(
      <FlightCard
        flight={makeFlight({ returnToAirport: true })}
        expandable
      />,
    );
    expect(screen.getByTestId("flight-event-reroute")).toBeTruthy();
  });
});

// ---------------------------------------------------------------------------
// §4.1.23 — "Уточняется" fallback for missing city/airport names
// ---------------------------------------------------------------------------

describe("4.1.23 — Уточняется fallback for missing station fields", () => {

  it("T23-fallback: shows SHARED.UNSPECIFIED fallback when departure city is empty string", () => {
    render(<FlightCard flight={makeFlight({ depCity: "" })} expandable />);
    // The useCityName mock returns "" for unknown codes when city is empty.
    // StationDisplay should emit either SHARED.UNSPECIFIED or real text — at
    // minimum, at least one station element is rendered.
    const stationEls = document.querySelectorAll(".station__city--bold");
    expect(stationEls.length).toBeGreaterThan(0);
  });

  it("T23-fallback: does not show raw empty string for terminal when terminal data absent", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    const text = document.body.textContent ?? "";
    expect(text).not.toMatch(/— $/m);
    expect(text).not.toContain("undefined");
  });
});

// ---------------------------------------------------------------------------
// Row interaction / state
// ---------------------------------------------------------------------------

describe("4.1.13.3 — Collapsed row state", () => {

  it("row has role=button and aria-expanded=false when expandable and collapsed", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    const row = document.querySelector("[role='button']");
    expect(row).toBeTruthy();
    expect(row?.getAttribute("aria-expanded")).toBe("false");
  });

  it("row aria-expanded=true when initialExpanded", () => {
    render(<FlightCard flight={makeFlight({})} expandable initialExpanded />);
    const row = document.querySelector("[role='button']");
    expect(row?.getAttribute("aria-expanded")).toBe("true");
  });

  it("expanded panel is present when initialExpanded=true", () => {
    render(<FlightCard flight={makeFlight({})} expandable initialExpanded />);
    expect(screen.getByTestId("flight-card-expanded")).toBeTruthy();
  });

  it("expanded panel is absent in collapsed state", () => {
    render(<FlightCard flight={makeFlight({})} expandable />);
    expect(document.querySelector("[data-testid='flight-card-expanded']")).toBeNull();
  });
});

// ---------------------------------------------------------------------------
// §4.1.13.4 — Expanded representation (Table 25 / §4.1.13.4.3)
// ---------------------------------------------------------------------------

function makeTransitionItem(status: "InProgress" | "Finished" | "Expected" = "InProgress") {
  return {
    start: {
      dayChange: { value: 0, title: "" },
      local: "2026-04-15T09:00:00+03:00",
      localTime: "09:00",
      tzOffset: 3,
      utc: "2026-04-15T06:00:00Z",
    },
    end: {
      dayChange: { value: 0, title: "" },
      local: "2026-04-15T09:30:00+03:00",
      localTime: "09:30",
      tzOffset: 3,
      utc: "2026-04-15T06:30:00Z",
    },
    status,
    isActual: true,
  } as const;
}

/**
 * Build a full ISimpleFlight with boarding transition + gate/dispatch override.
 */
function makeFlightWithBoarding(opts: {
  gate?: string;
  dispatch?: string;
  bagBelt?: string;
  /**
   * Which transition phase to simulate as isActual. Both blocks now
   * render side-by-side when both are active (TIRREDESIGN-7), so tests
   * that assert on a single `transition-gate` testid need to scope to
   * one direction at a time.
   */
  direction?: "departure" | "arrival";
}): ISimpleFlight {
  const base = makeFlight({});
  const transition = makeTransitionItem();
  const baseLeg = (base as ReturnType<typeof makeFlight> & { leg: ReturnType<typeof makeLeg> }).leg;
  const transitionMap =
    opts.direction === "arrival"
      ? { deboarding: transition }
      : { boarding: transition };
  const depGate = opts.direction === "arrival" ? undefined : opts.gate;
  const arrGate = opts.direction === "arrival" ? opts.gate : undefined;
  return {
    ...base,
    leg: {
      ...baseLeg,
      transition: transitionMap,
      departure: {
        ...baseLeg.departure,
        gate: depGate,
        dispatch: opts.dispatch,
      },
      arrival: {
        ...baseLeg.arrival,
        gate: arrGate,
        bagBelt: opts.bagBelt,
      },
    },
  } as unknown as ISimpleFlight;
}

describe("4.1.13.4 — Expanded row content (TZ §4.1.13.4.3)", () => {

  it("4.1.13.4-R: expanded row shows scheduled departure time with label", () => {
    const flight = makeFlight({ depLocal: "2026-04-15T10:00:00+03:00" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} />);
    const expanded = screen.getByTestId("flight-card-expanded");
    // Scheduled time in expanded body
    const text = expanded.textContent ?? "";
    expect(text).toContain("10:00");
  });

  it("4.1.13.4-R: expanded row shows scheduled arrival time with label", () => {
    const flight = makeFlight({ arrLocal: "2026-04-15T12:30:00+03:00" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} />);
    const expanded = screen.getByTestId("flight-card-expanded");
    expect(expanded.textContent).toContain("12:30");
  });

  it("4.1.13.4-R: expanded row shows actual departure time when available with SHARED.ACTUAL caption", () => {
    const flight = makeFlight({
      depLocal: "2026-04-15T10:00:00+03:00",
      depActualLocal: "2026-04-15T11:15:00+03:00",
    });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} />);
    const expanded = screen.getByTestId("flight-card-expanded");
    // Actual time and caption key
    expect(expanded.textContent).toContain("11:15");
    expect(expanded.textContent).toContain("SHARED.ACTUAL");
  });

  it("4.1.13.4-R: boarding row shows status + start + end times when transition present", () => {
    const flight = makeFlightWithBoarding({});
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="departure" />);
    const expanded = screen.getByTestId("flight-card-expanded");
    // Label key
    expect(expanded.textContent).toContain("DETAILS.BOARDING");
    // Status key
    expect(expanded.textContent).toContain("BOARDING-STATUSES.InProgress");
  });

  it("4.1.13.4-R: deboarding row shown when deboarding transition is active (§4.1.13.4.3)", () => {
    const flight = makeFlightWithBoarding({ direction: "arrival" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="arrival" />);
    const expanded = screen.getByTestId("flight-card-expanded");
    expect(expanded.textContent).toContain("DETAILS.DEBOARDING");
  });

  it("4.1.13.4-R: boarding gate rendered when departure.gate is set (§4.1.13.4.3 Table 29)", () => {
    const flight = makeFlightWithBoarding({ gate: "B12", direction: "departure" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="departure" />);
    expect(screen.getByTestId("transition-gate")).toBeTruthy();
    expect(screen.getByTestId("transition-gate").textContent).toContain("B12");
  });

  it("4.1.13.4-R: gate is NOT rendered when gate is absent", () => {
    const flight = makeFlightWithBoarding({});
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="departure" />);
    expect(document.querySelector("[data-testid='transition-gate']")).toBeNull();
  });

  it("4.1.13.4-R: dispatch (трап/автобус) rendered when departure.dispatch is set (§4.1.13.4.3 Table 29)", () => {
    const flight = makeFlightWithBoarding({ dispatch: "Bridge" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="departure" />);
    expect(screen.getByTestId("transition-dispatch")).toBeTruthy();
    // The dispatch value goes through t("DISPATCH.Bridge") which returns "DISPATCH.Bridge" in mock
    expect(screen.getByTestId("transition-dispatch").textContent).toContain("Bridge");
  });

  it("4.1.13.4-R: dispatch NOT rendered when departure.dispatch absent", () => {
    const flight = makeFlightWithBoarding({});
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="departure" />);
    expect(document.querySelector("[data-testid='transition-dispatch']")).toBeNull();
  });

  it("4.1.13.4-R: baggage belt rendered for deboarding (arrival) when arrival.bagBelt is set (§4.1.13.4.3 Table 30)", () => {
    const flight = makeFlightWithBoarding({ bagBelt: "3", direction: "arrival" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="arrival" />);
    expect(screen.getByTestId("transition-bag-belt")).toBeTruthy();
    expect(screen.getByTestId("transition-bag-belt").textContent).toContain("3");
  });

  it("4.1.13.4-R: baggage belt NOT rendered for departure direction", () => {
    const flight = makeFlightWithBoarding({ bagBelt: "3" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="departure" />);
    expect(document.querySelector("[data-testid='transition-bag-belt']")).toBeNull();
  });

  it("4.1.13.4-R: arrival gate rendered in deboarding row when arrival.gate is set", () => {
    const flight = makeFlightWithBoarding({ gate: "C7", direction: "arrival" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} direction="arrival" />);
    expect(screen.getByTestId("transition-gate")).toBeTruthy();
    expect(screen.getByTestId("transition-gate").textContent).toContain("C7");
  });

  it("4.1.13.4-R: share button always present in expanded actions row", () => {
    render(<FlightCard flight={makeFlight({})} expandable initialExpanded onViewDetails={() => {}} />);
    expect(screen.getByTestId("flight-share-button")).toBeTruthy();
  });

  it("4.1.13.4-R: Details button present in expanded actions row", () => {
    render(<FlightCard flight={makeFlight({})} expandable initialExpanded onViewDetails={() => {}} />);
    expect(screen.getByTestId("flight-details-button")).toBeTruthy();
  });

  it("4.1.13.4-R: aircraft type shown under operator column when expanded (TZ Table 25 C3)", () => {
    const flight = makeFlight({ aircraftTitle: "Airbus A320" });
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} />);
    const number = screen.getByTestId("flight-carrier-number");
    // Aircraft name rendered inside the number/header column when expanded
    expect(number.textContent).toContain("Airbus A320");
  });

  it("4.1.13.4-R: no transition row shown when no transition data", () => {
    const flight = makeFlight({});
    render(<FlightCard flight={flight} expandable initialExpanded onViewDetails={() => {}} />);
    const expanded = screen.getByTestId("flight-card-expanded");
    // Neither boarding nor deboarding label should appear when transition is absent
    expect(expanded.textContent).not.toContain("DETAILS.BOARDING");
    expect(expanded.textContent).not.toContain("DETAILS.DEBOARDING");
  });
});
