import { afterEach, describe, expect, it, vi } from "vitest";
import {
  fetchAllCursorPages,
  fetchAllCursorPagesMainThread,
} from "../../../common/core/pagination";

describe("common cursor pagination fetch", () => {
  afterEach(() => {
    vi.unstubAllGlobals();
  });

  it("follows nextCursor until the API reports the final page", async () => {
    const fetchMock = vi
      .fn()
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          items: [{ id: "tenant-1" }],
          nextCursor: "cursor-1",
        }),
      })
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          items: [{ id: "tenant-2" }],
        }),
      });
    vi.stubGlobal("fetch", fetchMock);

    const response = await fetchAllCursorPagesMainThread<{ id: string }>({
      baseUrl: "/api",
      path: "/v1/admin/tenants",
      pageSize: 1,
      params: { parentId: "parent-1" },
      headers: { Authorization: "Bearer token" },
    });

    expect(response.items).toEqual([{ id: "tenant-1" }, { id: "tenant-2" }]);
    expect(fetchMock).toHaveBeenCalledTimes(2);
    expect(fetchMock.mock.calls[0][0].toString()).toContain(
      "/api/v1/admin/tenants?parentId=parent-1&limit=1",
    );
    expect(fetchMock.mock.calls[0][0].toString()).not.toContain("offset=");
    expect(fetchMock.mock.calls[1][0].toString()).toContain("cursor=cursor-1");
    expect(fetchMock.mock.calls[1][0].toString()).not.toContain("offset=");
    expect(fetchMock.mock.calls[0][1]).toMatchObject({
      headers: { Authorization: "Bearer token" },
      credentials: "same-origin",
    });
  });

  it("uses the main thread path during browser test mode", async () => {
    const fetchMock = vi.fn().mockResolvedValue({
      ok: true,
      json: async () => ({
        items: [{ id: "tenant-1" }],
      }),
    });
    vi.stubGlobal("fetch", fetchMock);
    Object.defineProperty(window, "_IS_TEST_MODE", {
      value: true,
      configurable: true,
    });

    const response = await fetchAllCursorPages<{ id: string }>({
      baseUrl: "/api",
      path: "/v1/admin/tenants",
    });

    expect(response.items).toEqual([{ id: "tenant-1" }]);
    expect(fetchMock).toHaveBeenCalledTimes(1);
  });
});
