import { describe, it, expect, vi } from "vitest";
import { fetchDictionaries } from "./api.js";
import type { ApiClient } from "@/shared/api/client.js";

function makeClient(
  responses: Record<string, unknown>,
): ApiClient {
  return {
    get: vi.fn(async (path: string) => {
      const match = Object.keys(responses).find((k) => path.includes(k));
      if (!match) throw new Error(`Unexpected path: ${path}`);
      return responses[match];
    }),
  } as unknown as ApiClient;
}

describe("fetchDictionaries", () => {
  it("fetches four endpoints in parallel and returns a combined shape", async () => {
    const client = makeClient({
      world_regions: [{ world_region_id: 1, title: { ru: "Европа" } }],
      countries: [{ code: "RU", title: { ru: "Россия" }, world_region_id: 1 }],
      cities: [
        { code: "MOW", title: { ru: "Москва" }, country_code: "RU" },
      ],
      airports: [
        { code: "SVO", city_code: "MOW", title: { ru: "Шереметьево" }, has_afl_flights: true },
      ],
    });

    const result = await fetchDictionaries(client);

    expect(result.regions).toHaveLength(1);
    expect(result.countries).toHaveLength(1);
    expect(result.cities).toHaveLength(1);
    expect(result.airports).toHaveLength(1);
    expect(result.cities[0]!.code).toBe("MOW");
  });

  it("calls exactly the four dictionary paths", async () => {
    const getMock = vi.fn(async (_path: string) => []);
    const client = { get: getMock } as unknown as ApiClient;

    await fetchDictionaries(client);

    const calledPaths = getMock.mock.calls.map((c) => c[0] as string);
    expect(calledPaths).toContain("dictionary/1/world_regions");
    expect(calledPaths).toContain("dictionary/1/countries");
    expect(calledPaths).toContain("dictionary/1/cities");
    expect(calledPaths).toContain("dictionary/1/airports");
    expect(getMock).toHaveBeenCalledTimes(4);
  });

  it("propagates a rejection from any endpoint", async () => {
    const client = {
      get: vi.fn(async (path: string) => {
        if (path.includes("airports")) throw new Error("boom");
        return [];
      }),
    } as unknown as ApiClient;

    await expect(fetchDictionaries(client)).rejects.toThrow("boom");
  });
});
