import { beforeEach, describe, expect, it, vi } from "vitest";
import * as client from "./client";
import {
  createFleetProvider,
  deleteFleetOidcConfig,
  deleteFleetProvider,
  fetchFleetAgentConfig,
  fetchFleetOidcConfig,
  fetchFleetProviders,
  resetBreakglassAdminPassword,
  updateFleetAgentConfig,
  updateFleetOidcConfig,
  updateFleetProvider,
} from "./fleet-settings";

vi.mock("./client");

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

describe("fetchFleetProviders", (): void => {
  it("calls providers list endpoint", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce([] as never);

    await fetchFleetProviders();

    expect(client.apiGet).toHaveBeenCalledWith("/api/fleet-settings/providers");
  });
});

describe("createFleetProvider", (): void => {
  it("posts provider payload", async (): Promise<void> => {
    vi.mocked(client.apiPost).mockResolvedValueOnce({ id: "provider-1" } as never);

    await createFleetProvider({
      name: "openai-main",
      displayName: "OpenAI Main",
      type: "openai",
      baseUrl: "https://api.openai.com/v1",
      apiKey: "sk-test",
      models: [
        { id: "gpt-4.1-mini", name: "gpt-4.1-mini" },
        { id: "gpt-4o-mini", name: "gpt-4o-mini" },
      ],
    });

    expect(client.apiPost).toHaveBeenCalledWith("/api/fleet-settings/providers", {
      name: "openai-main",
      displayName: "OpenAI Main",
      type: "openai",
      baseUrl: "https://api.openai.com/v1",
      apiKey: "sk-test",
      models: [
        { id: "gpt-4.1-mini", name: "gpt-4.1-mini" },
        { id: "gpt-4o-mini", name: "gpt-4o-mini" },
      ],
    });
  });
});

describe("updateFleetProvider", (): void => {
  it("patches provider endpoint with updates", async (): Promise<void> => {
    vi.mocked(client.apiPatch).mockResolvedValueOnce(undefined as never);

    await updateFleetProvider("provider-1", { displayName: "OpenAI Updated", isActive: true });

    expect(client.apiPatch).toHaveBeenCalledWith("/api/fleet-settings/providers/provider-1", {
      displayName: "OpenAI Updated",
      isActive: true,
    });
  });
});

describe("deleteFleetProvider", (): void => {
  it("deletes provider endpoint", async (): Promise<void> => {
    vi.mocked(client.apiDelete).mockResolvedValueOnce(undefined as never);

    await deleteFleetProvider("provider-1");

    expect(client.apiDelete).toHaveBeenCalledWith("/api/fleet-settings/providers/provider-1");
  });
});

describe("fetchFleetAgentConfig", (): void => {
  it("calls agent config endpoint", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce({
      primaryModel: null,
      fallbackModels: [],
      personality: null,
    } as never);

    await fetchFleetAgentConfig();

    expect(client.apiGet).toHaveBeenCalledWith("/api/fleet-settings/agent-config");
  });
});

describe("updateFleetAgentConfig", (): void => {
  it("patches agent config", async (): Promise<void> => {
    vi.mocked(client.apiPatch).mockResolvedValueOnce(undefined as never);

    await updateFleetAgentConfig({
      primaryModel: "openai:gpt-4o-mini",
      fallbackModels: ["openai:gpt-4.1-mini"],
      personality: "System behavior",
    });

    expect(client.apiPatch).toHaveBeenCalledWith("/api/fleet-settings/agent-config", {
      primaryModel: "openai:gpt-4o-mini",
      fallbackModels: ["openai:gpt-4.1-mini"],
      personality: "System behavior",
    });
  });
});

describe("fetchFleetOidcConfig", (): void => {
  it("calls oidc endpoint", async (): Promise<void> => {
    vi.mocked(client.apiGet).mockResolvedValueOnce({ configured: false } as never);

    await fetchFleetOidcConfig();

    expect(client.apiGet).toHaveBeenCalledWith("/api/fleet-settings/oidc");
  });
});

describe("updateFleetOidcConfig", (): void => {
  it("issues a PUT request with payload", async (): Promise<void> => {
    vi.mocked(client.apiRequest).mockResolvedValueOnce(undefined as never);

    await updateFleetOidcConfig({
      issuerUrl: "https://issuer.example.com",
      clientId: "mosaic-client",
      clientSecret: "top-secret",
    });

    expect(client.apiRequest).toHaveBeenCalledWith("/api/fleet-settings/oidc", {
      method: "PUT",
      body: JSON.stringify({
        issuerUrl: "https://issuer.example.com",
        clientId: "mosaic-client",
        clientSecret: "top-secret",
      }),
    });
  });
});

describe("deleteFleetOidcConfig", (): void => {
  it("deletes oidc endpoint", async (): Promise<void> => {
    vi.mocked(client.apiDelete).mockResolvedValueOnce(undefined as never);

    await deleteFleetOidcConfig();

    expect(client.apiDelete).toHaveBeenCalledWith("/api/fleet-settings/oidc");
  });
});

describe("resetBreakglassAdminPassword", (): void => {
  it("posts breakglass reset payload", async (): Promise<void> => {
    vi.mocked(client.apiPost).mockResolvedValueOnce(undefined as never);

    await resetBreakglassAdminPassword({
      username: "admin",
      newPassword: "new-password-123",
    });

    expect(client.apiPost).toHaveBeenCalledWith("/api/fleet-settings/breakglass/reset-password", {
      username: "admin",
      newPassword: "new-password-123",
    });
  });
});
