import type { LanguageModel } from "ai";

import { createAnthropic } from "@ai-sdk/anthropic";
import { createOpenAI } from "@ai-sdk/openai";

import type { LlmHttpMetadata, ResolvedLlmConfig } from "./types";

export interface ProviderResult {
  http: LlmHttpMetadata | null;
  model: LanguageModel;
}

export function createProviderModel(config: ResolvedLlmConfig): ProviderResult {
  let httpMeta: LlmHttpMetadata | null = null;

  const observingFetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
    const fetchInit: Record<string, unknown> = { ...init };
    if (config.ignoreSSL) {
      fetchInit["tls"] = { rejectUnauthorized: false };
    }

    const response = await fetch(input, fetchInit);
    httpMeta = {
      headers: Object.fromEntries(response.headers),
      status: response.status,
      statusText: response.statusText,
    };
    return response;
  };

  const sharedOptions = {
    apiKey: config.key,
    baseURL: config.url,
    fetch: observingFetch as typeof fetch,
    headers: config.headers,
  };

  let model: LanguageModel;

  switch (config.provider) {
    case "anthropic": {
      const provider = createAnthropic({
        ...sharedOptions,
        ...(config.authToken ? { headers: { ...config.headers, Authorization: `Bearer ${config.authToken}` } } : {}),
      });
      model = provider.messages(config.model);
      break;
    }
    case "openai": {
      const provider = createOpenAI(sharedOptions);
      model = provider.chat(config.model);
      break;
    }
    case "openai-responses": {
      const provider = createOpenAI(sharedOptions);
      model = provider.responses(config.model);
      break;
    }
  }

  return { http: httpMeta, model };
}
