// Curated model catalog. The UI intentionally shows only the current usable
// set; provider plumbing is an implementation detail and never appears in the
// label. Availability is enforced by Workers AI or the configured gateway at
// call time — operators control which gateway model ids their users may access.

import type { Env } from "./types";

export type ModelRoute = "workers-ai" | "gateway-openai" | "gateway-anthropic";

export interface ModelEntry {
  id: string;
  route: ModelRoute;
  owned_by: string;
  context: number;
  reasoning: boolean;
  tools: boolean;
  vision: boolean;
  label: string;
}

export const MODELS: ModelEntry[] = [
  {
    id: "@cf/moonshotai/kimi-k2.7-code",
    route: "workers-ai",
    owned_by: "moonshotai",
    context: 262_144,
    reasoning: true,
    tools: true,
    vision: true,
    label: "Kimi K2.7 Code",
  },
  {
    id: "@cf/zai-org/glm-5.2",
    route: "workers-ai",
    owned_by: "zai",
    context: 262_144,
    reasoning: true,
    tools: true,
    vision: false,
    label: "GLM 5.2",
  },
  {
    id: "claude-opus-4-8",
    route: "gateway-anthropic",
    owned_by: "anthropic",
    context: 1_000_000,
    reasoning: true,
    tools: true,
    vision: true,
    label: "Opus 4.8",
  },
  {
    id: "gpt-5.5",
    route: "gateway-openai",
    owned_by: "openai",
    context: 400_000,
    reasoning: true,
    tools: true,
    vision: true,
    label: "GPT-5.5",
  },
];

export const DEFAULT_MODEL_ID = "@cf/moonshotai/kimi-k2.7-code";

function hasModelGateway(env: Env): boolean {
  return Boolean(env.LLM_GATEWAY_URL?.trim() && env.LLM_GATEWAY_TOKEN?.trim());
}

// Keep the catalog honest per installation. Workers AI rows are available in
// the public engine; gateway rows are visible only when the deployment supplied
// the private gateway URL and token needed to run them.
export function availableModels(env: Env): ModelEntry[] {
  return hasModelGateway(env) ? MODELS : MODELS.filter((model) => model.route === "workers-ai");
}

export function defaultModelId(_env: Env): string {
  return DEFAULT_MODEL_ID;
}

export function findModel(id: string): ModelEntry | undefined {
  return MODELS.find((model) => model.id === id);
}

/** Resolve a requested model id to a usable catalog entry. A stale or removed
 * id (e.g. a churned alpha model still pinned in a session/Settings) heals to
 * the default instead of hard-failing every turn with model_not_found. */
export function resolveModelId(id: string | undefined): string {
  return id && findModel(id) ? id : DEFAULT_MODEL_ID;
}
