import * as plugins from './plugins.js';
import type { ISmartAiModelSetup, ISmartAiOptions, LanguageModelV3 } from './smartai.interfaces.js';
import { createOllamaModel } from './smartai.provider.ollama.js';
import { createAnthropicCachingMiddleware } from './smartai.middleware.anthropic.js';
import { createOpenAiChatGptInstructionsMiddleware } from './smartai.middleware.openai.js';
import { createOpenAiChatGptProviderSettings } from './smartai.auth.openai.js';

/**
 * Returns a LanguageModelV3 for the given provider and model.
 * This is the primary API — consumers use the returned model with AI SDK's
 * generateText(), streamText(), etc.
 */
export function getModel(options: ISmartAiOptions): LanguageModelV3 {
  switch (options.provider) {
    case 'anthropic': {
      const p = plugins.createAnthropic({ apiKey: options.apiKey });
      const base = p(options.model) as LanguageModelV3;
      if (options.promptCaching === false) return base;
      return plugins.wrapLanguageModel({
        model: base,
        middleware: createAnthropicCachingMiddleware(
          typeof options.promptCaching === 'object' ? options.promptCaching : undefined,
        ),
      }) as unknown as LanguageModelV3;
    }
    case 'openai': {
      const p = plugins.createOpenAI(
        options.openAiChatGptAuth
          ? createOpenAiChatGptProviderSettings(options.openAiChatGptAuth)
          : { apiKey: options.apiKey },
      );
      const base = p(options.model) as LanguageModelV3;
      return options.openAiChatGptAuth
        ? plugins.wrapLanguageModel({
            model: base,
            middleware: createOpenAiChatGptInstructionsMiddleware(),
          }) as unknown as LanguageModelV3
        : base;
    }
    case 'google': {
      const p = plugins.createGoogleGenerativeAI({ apiKey: options.apiKey });
      return p(options.model) as LanguageModelV3;
    }
    case 'groq': {
      const p = plugins.createGroq({ apiKey: options.apiKey });
      return p(options.model) as LanguageModelV3;
    }
    case 'mistral': {
      const p = plugins.createMistral({ apiKey: options.apiKey });
      return p(options.model) as LanguageModelV3;
    }
    case 'xai': {
      const p = plugins.createXai({ apiKey: options.apiKey });
      return p(options.model) as LanguageModelV3;
    }
    case 'perplexity': {
      const p = plugins.createPerplexity({ apiKey: options.apiKey });
      return p(options.model) as LanguageModelV3;
    }
    case 'ollama':
      return createOllamaModel(options);
    default:
      throw new Error(`Unknown provider: ${(options as ISmartAiOptions).provider}`);
  }
}

/**
 * Returns the model plus request-time providerOptions for AI SDK calls.
 */
export function getModelSetup(options: ISmartAiOptions): ISmartAiModelSetup {
  const model = getModel(options);
  return options.providerOptions ? { model, providerOptions: options.providerOptions } : { model };
}
