import { describe, it, expect, vi, beforeEach } from "vitest";
import * as client from "./client";
import { fetchAdminUsers, inviteUser, updateUser, deactivateUser } from "./admin";

vi.mock("./client");

beforeEach((): void => {
  vi.clearAllMocks();
});

describe("fetchAdminUsers", (): void => {
  it("calls admin/users endpoint without params when none provided", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce({ data: [], meta: {} } as never);
    await fetchAdminUsers();
    expect(client.apiGet).toHaveBeenCalledWith("/api/admin/users");
  });

  it("appends page and limit params when provided", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce({ data: [], meta: {} } as never);
    await fetchAdminUsers(2, 50);
    expect(client.apiGet).toHaveBeenCalledWith("/api/admin/users?page=2&limit=50");
  });

  it("throws on API error", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockRejectedValueOnce(new Error("Network error"));
    await expect(fetchAdminUsers()).rejects.toThrow("Network error");
  });
});

describe("inviteUser", (): void => {
  it("posts to invite endpoint", async (): Promise<void> => {
    vi.mocked(client.apiPost).mockResolvedValueOnce({ id: "inv-1" } as never);
    await inviteUser({
      email: "a@b.com",
      name: "Alice",
      workspaceId: "ws-1",
      role: "MEMBER" as never,
    });
    expect(client.apiPost).toHaveBeenCalledWith(
      "/api/admin/users/invite",
      expect.objectContaining({ email: "a@b.com" })
    );
  });
});

describe("updateUser", (): void => {
  it("patches correct endpoint with dto", async (): Promise<void> => {
    vi.mocked(client.apiPatch).mockResolvedValueOnce({ id: "u1", name: "Bob" } as never);
    await updateUser("u1", { name: "Bob" });
    expect(client.apiPatch).toHaveBeenCalledWith("/api/admin/users/u1", { name: "Bob" });
  });
});

describe("deactivateUser", (): void => {
  it("deletes correct endpoint", async (): Promise<void> => {
    vi.mocked(client.apiDelete).mockResolvedValueOnce({} as never);
    await deactivateUser("u1");
    expect(client.apiDelete).toHaveBeenCalledWith("/api/admin/users/u1");
  });
});
