import { createAnthropic } from "@ai-sdk/anthropic";
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { createOpenAI } from "@ai-sdk/openai";
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { createXai } from "@ai-sdk/xai";
import { wrapLanguageModel, type LanguageModel } from "ai";
import {
  assertProviderApiKey,
  type ProviderApiKeys,
  type ProviderId,
  resolveApiKey,
} from "./keys";
import {
  getOpenCodeGenerationSettings,
  OPENCODE_GO_KIMI_MODELS,
  OPENCODE_GO_MESSAGES_MODELS,
} from "./opencode-go-settings";

export type AIProviderName = ProviderId;

const OPENCODE_GO_BASE = "https://opencode.ai/zen/go/v1";

export const PROVIDER_OPTIONS = [
  {
    value: "opencode-go" as const,
    label: "OpenCode Go",
    models: [
      "deepseek-v4-flash",
      "deepseek-v4-pro",
      "glm-5.1",
      "glm-5",
      "kimi-k2.7-code",
      "kimi-k2.6",
      "kimi-k2.5",
      "mimo-v2.5",
      "mimo-v2.5-pro",
      "minimax-m3",
      "minimax-m2.7",
      "minimax-m2.5",
      "qwen3.7-max",
      "qwen3.7-plus",
      "qwen3.6-plus",
      "qwen3.5-plus",
    ],
  },
  { value: "xai" as const, label: "Grok (xAI)", models: ["grok-3", "grok-3-fast", "grok-2-1212"] },
  { value: "openai" as const, label: "OpenAI", models: ["gpt-4o", "gpt-4o-mini"] },
  {
    value: "anthropic" as const,
    label: "Anthropic",
    models: ["claude-sonnet-4-20250514", "claude-3-5-haiku-20241022"],
  },
  { value: "google" as const, label: "Google", models: ["gemini-2.0-flash", "gemini-1.5-pro"] },
] as const;

function applyOpenCodeModelDefaults(model: LanguageModel, modelId: string): LanguageModel {
  if (!OPENCODE_GO_KIMI_MODELS.has(modelId)) return model;

  return wrapLanguageModel({
    model,
    modelId,
    providerId: "opencode-go",
    middleware: {
      transformParams: async ({ params }) => ({
        ...params,
        temperature: 1,
      }),
    },
  });
}

function getOpenCodeGoModel(model: string, apiKey: string): LanguageModel {
  let resolved: LanguageModel;

  if (OPENCODE_GO_MESSAGES_MODELS.has(model)) {
    resolved = createAnthropic({
      apiKey,
      baseURL: OPENCODE_GO_BASE,
    })(model);
  } else {
    const provider = createOpenAICompatible({
      name: "opencode-go",
      baseURL: OPENCODE_GO_BASE,
      apiKey,
    });
    resolved = provider(model);
  }

  return applyOpenCodeModelDefaults(resolved, model);
}

export function getModel(
  provider: string,
  model: string,
  apiKeys: ProviderApiKeys = {}
): LanguageModel {
  const id = provider as ProviderId;
  assertProviderApiKey(id, apiKeys);
  const apiKey = resolveApiKey(id, apiKeys)!;

  switch (id) {
    case "opencode-go":
      return getOpenCodeGoModel(model, apiKey);
    case "openai":
      return createOpenAI({ apiKey })(model);
    case "anthropic":
      return createAnthropic({ apiKey })(model);
    case "google":
      return createGoogleGenerativeAI({ apiKey })(model);
    case "xai":
    default:
      return createXai({ apiKey })(model);
  }
}

export function getModelGenerationSettings(provider: string, model: string) {
  return getOpenCodeGenerationSettings(provider, model);
}