import { Conversation } from './classes.conversation.js';
import * as plugins from './plugins.js';
import { AnthropicProvider } from './provider.anthropic.js';
import { OllamaProvider } from './provider.ollama.js';
import { OpenAiProvider } from './provider.openai.js';
import { PerplexityProvider } from './provider.perplexity.js';
import { ExoProvider } from './provider.exo.js';
import { GroqProvider } from './provider.groq.js';
import { XAIProvider } from './provider.xai.js';


export interface ISmartAiOptions {
  openaiToken?: string;
  anthropicToken?: string;
  perplexityToken?: string;
  groqToken?: string;
  xaiToken?: string;
  exo?: {
    baseUrl?: string;
    apiKey?: string;
  };
  ollama?: {
    baseUrl?: string;
    model?: string;
    visionModel?: string;
  };
}

export type TProvider = 'openai' | 'anthropic' | 'perplexity' | 'ollama' | 'exo' | 'groq' | 'xai';

export class SmartAi {
  public options: ISmartAiOptions;

  public openaiProvider: OpenAiProvider;
  public anthropicProvider: AnthropicProvider;
  public perplexityProvider: PerplexityProvider;
  public ollamaProvider: OllamaProvider;
  public exoProvider: ExoProvider;
  public groqProvider: GroqProvider;
  public xaiProvider: XAIProvider;

  constructor(optionsArg: ISmartAiOptions) {
    this.options = optionsArg;
  }

  public async start() {
    if (this.options.openaiToken) {
      this.openaiProvider = new OpenAiProvider({
        openaiToken: this.options.openaiToken,
      });
      await this.openaiProvider.start();
    }
    if (this.options.anthropicToken) {
      this.anthropicProvider = new AnthropicProvider({
        anthropicToken: this.options.anthropicToken,
      });
      await this.anthropicProvider.start();
    }
    if (this.options.perplexityToken) {
      this.perplexityProvider = new PerplexityProvider({
        perplexityToken: this.options.perplexityToken,
      });
      await this.perplexityProvider.start();
    }
    if (this.options.groqToken) {
      this.groqProvider = new GroqProvider({
        groqToken: this.options.groqToken,
      });
      await this.groqProvider.start();
    }
    if (this.options.xaiToken) {
      this.xaiProvider = new XAIProvider({
        xaiToken: this.options.xaiToken,
      });
      await this.xaiProvider.start();
    }
    if (this.options.ollama) {
      this.ollamaProvider = new OllamaProvider({
        baseUrl: this.options.ollama.baseUrl,
        model: this.options.ollama.model,
        visionModel: this.options.ollama.visionModel,
      });
      await this.ollamaProvider.start();
    }
    if (this.options.exo) {
      this.exoProvider = new ExoProvider({
        exoBaseUrl: this.options.exo.baseUrl,
        apiKey: this.options.exo.apiKey,
      });
      await this.exoProvider.start();
    }
  }

  public async stop() {}
  
  /**
   * create a new conversation
   */
  createConversation(provider: TProvider) {
    switch (provider) {
      case 'exo':
        return Conversation.createWithExo(this);
      case 'openai':
        return Conversation.createWithOpenAi(this);
      case 'anthropic':
        return Conversation.createWithAnthropic(this);
      case 'perplexity':
        return Conversation.createWithPerplexity(this);
      case 'ollama':
        return Conversation.createWithOllama(this);
      case 'groq':
        return Conversation.createWithGroq(this);
      case 'xai':
        return Conversation.createWithXai(this);
      default:
        throw new Error('Provider not available');
    }
  }
}