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

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function createMockClient(responseBody: unknown, status = 200) {
  const mockFetch = vi.fn<typeof fetch>().mockResolvedValue(
    new Response(JSON.stringify(responseBody), {
      status,
      headers: { "Content-Type": "application/json" },
    }),
  );

  const client = new ApiClient({
    baseUrl: "https://api.test.com",
    locale: "ru",
    fetchImpl: mockFetch,
    retry: { maxRetries: 0 },
  });

  return { client, mockFetch };
}

function extractUrl(mockFetch: ReturnType<typeof vi.fn>): URL {
  const call = mockFetch.mock.calls[0] as [string, ...unknown[]];
  return new URL(call[0]);
}

const POPULAR_RESPONSE: PopularRequest[] = [
  {
    mode: "FlightNumber",
    carrier: "SU",
    flightNumber: "9027",
    type: "Onlineboard",
  },
  {
    mode: "FlightNumber",
    carrier: "SU",
    flightNumber: "9006",
    type: "Onlineboard",
  },
  {
    mode: "Route",
    departure: "KUF",
    arrival: "ABA",
    type: "Onlineboard",
  },
  {
    mode: "Route",
    departure: "RTW",
    arrival: "ABA",
    type: "Onlineboard",
  },
];

// ---------------------------------------------------------------------------
// getPopularRequests
// ---------------------------------------------------------------------------

describe("getPopularRequests", () => {
  it("calls the correct API path", async () => {
    const { client, mockFetch } = createMockClient(POPULAR_RESPONSE);

    await getPopularRequests(client);

    const url = extractUrl(mockFetch);
    expect(url.pathname).toBe("/Requests/1/getpopular");
  });

  it("returns the deserialized PopularRequest[]", async () => {
    const { client } = createMockClient(POPULAR_RESPONSE);

    const result = await getPopularRequests(client);

    expect(result).toEqual(POPULAR_RESPONSE);
  });

  it("throws ApiHttpError on 404", async () => {
    const { client } = createMockClient({ error: "not found" }, 404);

    await expect(getPopularRequests(client)).rejects.toThrow("HTTP 404");
  });

  it("throws ApiHttpError on 500", async () => {
    const { client } = createMockClient({ error: "internal" }, 500);

    await expect(getPopularRequests(client)).rejects.toThrow("HTTP 500");
  });
});
