import { describe, expect, it } from "vitest";

import {
  API_KEY_PROVIDERS,
  KNOWN_PROVIDERS,
  applyProviderChange,
  defaultModelFor,
  draftsToRoutingInput,
  toRoutingDrafts,
  type RoutingDraft,
} from "./providers";

describe("KNOWN_PROVIDERS", () => {
  it("includes kimi-code as an OAuth provider with a fixed model", () => {
    const kc = KNOWN_PROVIDERS.find((p) => p.id === "kimi-code");
    expect(kc).toBeDefined();
    expect(kc?.auth).toBe("oauth");
    expect(kc?.defaultModel).toBe("kimi-for-coding");
  });

  it("API_KEY_PROVIDERS excludes the OAuth provider", () => {
    expect(API_KEY_PROVIDERS.some((p) => p.id === "kimi-code")).toBe(false);
    expect(API_KEY_PROVIDERS.some((p) => p.id === "deepseek")).toBe(true);
  });

  it("includes kimi-code-key as an api_key provider with a fixed model", () => {
    const kck = KNOWN_PROVIDERS.find((p) => p.id === "kimi-code-key");
    expect(kck).toBeDefined();
    expect(kck?.auth).toBe("api_key");
    expect(kck?.defaultModel).toBe("kimi-for-coding");
  });

  it("API_KEY_PROVIDERS includes the static-key Kimi Code provider", () => {
    expect(API_KEY_PROVIDERS.some((p) => p.id === "kimi-code-key")).toBe(true);
  });
});

describe("defaultModelFor", () => {
  it("returns the OAuth provider's fixed model", () => {
    expect(defaultModelFor("kimi-code")).toBe("kimi-for-coding");
  });

  it("returns the static-key Kimi Code provider's fixed model", () => {
    expect(defaultModelFor("kimi-code-key")).toBe("kimi-for-coding");
  });

  it("returns empty string for api_key providers / unknown", () => {
    expect(defaultModelFor("deepseek")).toBe("");
    expect(defaultModelFor("nope")).toBe("");
  });
});

describe("toRoutingDrafts", () => {
  it("expands to all tiers, filling missing ones empty", () => {
    const drafts = toRoutingDrafts([
      { tier: "writer", provider: "deepseek", model: "deepseek-chat" },
    ]);
    expect(drafts.map((d) => d.tier)).toEqual(["writer", "analyst", "light"]);
    expect(drafts[0]).toEqual({
      tier: "writer",
      provider: "deepseek",
      model: "deepseek-chat",
    });
    expect(drafts[1]).toEqual({ tier: "analyst", provider: "", model: "" });
  });
});

describe("applyProviderChange", () => {
  it("auto-fills the OAuth provider's fixed model", () => {
    const next = applyProviderChange(
      { tier: "writer", provider: "", model: "" },
      "kimi-code",
    );
    expect(next).toEqual({
      tier: "writer",
      provider: "kimi-code",
      model: "kimi-for-coding",
    });
  });

  it("clears the model when switching to an api_key provider", () => {
    const next = applyProviderChange(
      { tier: "writer", provider: "kimi-code", model: "kimi-for-coding" },
      "deepseek",
    );
    expect(next).toEqual({ tier: "writer", provider: "deepseek", model: "" });
  });

  it("does not mutate the input draft", () => {
    const draft: RoutingDraft = { tier: "writer", provider: "", model: "" };
    applyProviderChange(draft, "kimi-code");
    expect(draft).toEqual({ tier: "writer", provider: "", model: "" });
  });
});

describe("draftsToRoutingInput", () => {
  it("keeps only rows with both provider and model", () => {
    const input = draftsToRoutingInput([
      { tier: "writer", provider: "kimi-code", model: "kimi-for-coding" },
      { tier: "analyst", provider: "", model: "" },
      { tier: "light", provider: "deepseek", model: "" },
    ]);
    expect(input).toEqual([
      { tier: "writer", provider: "kimi-code", model: "kimi-for-coding" },
    ]);
  });
});
