// @vitest-environment jsdom
import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { useFlightDetails } from "./useFlightDetails.js";
import type { IBoardResponse, ISimpleFlight } from "../types.js";

const mockClient = { get: vi.fn() };

vi.mock("@/shared/api/provider.js", () => ({
  useApiClient: () => mockClient,
}));

vi.mock("../api.js", async () => {
  const actual = await vi.importActual<typeof import("../api.js")>("../api.js");
  return {
    ...actual,
    getFlightDetails: (_client: unknown, _params: unknown) => mockClient.get(),
  };
});

function makeFlight(id: string): ISimpleFlight {
  return {
    id,
    routeType: "Direct",
    flyingTime: "1h",
    status: "Scheduled",
    flightId: {
      carrier: "SU",
      flightNumber: "0022",
      suffix: "",
      date: "20260416",
    },
    operatingBy: {},
    leg: {
      arrival: {
        scheduled: {
          airport: "",
          airportCode: "",
          city: "",
          cityCode: "",
          countryCode: "",
        },
        latest: {
          airport: "",
          airportCode: "",
          city: "",
          cityCode: "",
          countryCode: "",
        },
        dispatch: "",
        gate: "",
        terminal: "",
        times: {
          scheduledArrival: {
            dayChange: { value: 0, title: "" },
            local: "",
            localTime: "",
            tzOffset: 0,
            utc: "",
          },
        },
      },
      dayChange: 0,
      departure: {
        scheduled: {
          airport: "",
          airportCode: "",
          city: "",
          cityCode: "",
          countryCode: "",
        },
        latest: {
          airport: "",
          airportCode: "",
          city: "",
          cityCode: "",
          countryCode: "",
        },
        dispatch: "",
        gate: "",
        terminal: "",
        checkingStatus: "Scheduled",
        parkingStand: "",
        times: {
          scheduledDeparture: {
            dayChange: { value: 0, title: "" },
            local: "",
            localTime: "",
            tzOffset: 0,
            utc: "",
          },
        },
      },
      equipment: {},
      flags: {
        checkinAvailable: false,
        returnToAirport: false,
        routeChanged: false,
      },
      flyingTime: "1h",
      index: 0,
      operatingBy: {},
      status: "Scheduled",
      updated: "",
    },
  } as unknown as ISimpleFlight;
}

describe("useFlightDetails", () => {
  beforeEach(() => {
    mockClient.get.mockReset();
  });

  it("returns first flight and full array in allFlights", async () => {
    const response: IBoardResponse = {
      data: {
        partners: [],
        routes: [
          makeFlight("SU0022-20260416"),
          makeFlight("SU0022-20260417"),
          makeFlight("SU0022-20260418"),
        ],
        daysOfFlight: [],
      },
    };
    mockClient.get.mockResolvedValue(response);

    const { result } = renderHook(() =>
      useFlightDetails({ flights: "SU0022", dates: "2026-04-16" }),
    );

    await waitFor(() => expect(result.current.loading).toBe(false));

    expect(result.current.flight?.id).toBe("SU0022-20260416");
    expect(result.current.allFlights).toHaveLength(3);
    expect(result.current.allFlights[0]?.id).toBe("SU0022-20260416");
  });

  it("returns empty allFlights array when response has no routes", async () => {
    const response: IBoardResponse = {
      data: { partners: [], routes: [], daysOfFlight: [] },
    };
    mockClient.get.mockResolvedValue(response);

    const { result } = renderHook(() =>
      useFlightDetails({ flights: "SU0022", dates: "2026-04-16" }),
    );

    await waitFor(() => expect(result.current.loading).toBe(false));

    expect(result.current.flight).toBeNull();
    expect(result.current.allFlights).toEqual([]);
    expect(result.current.daysOfFlight).toEqual([]);
  });

  it("returns daysOfFlight from response", async () => {
    const response: IBoardResponse = {
      data: {
        partners: [],
        routes: [makeFlight("SU0022-20260416")],
        daysOfFlight: ["20260415", "20260416", "20260417"],
      },
    };
    mockClient.get.mockResolvedValue(response);

    const { result } = renderHook(() =>
      useFlightDetails({ flights: "SU0022", dates: "2026-04-16" }),
    );

    await waitFor(() => expect(result.current.loading).toBe(false));

    expect(result.current.daysOfFlight).toEqual([
      "20260415",
      "20260416",
      "20260417",
    ]);
  });
});
