/**
 * AI Provider Manager
 * 
 * Central manager for all AI providers
 * Handles provider registration, selection, and routing
 */

import { OpenAIProvider } from './openai-provider'
import { AnthropicProvider } from './anthropic-provider'
import type { AIProvider, AICompletionParams, AICompletionResponse } from './types'

export class AIProviderManager {
  private providers = new Map<string, AIProvider>()
  private defaultProvider?: string
  
  constructor() {
    // Register built-in providers
    this.registerProvider(new OpenAIProvider())
    this.registerProvider(new AnthropicProvider())
  }
  
  /**
   * Register a new AI provider
   */
  registerProvider(provider: AIProvider): void {
    this.providers.set(provider.type, provider)
    console.log(`[AIProviders] Registered provider: ${provider.name} (${provider.type})`)
  }
  
  /**
   * Get a provider by type
   */
  getProvider(type: string): AIProvider | undefined {
    return this.providers.get(type)
  }
  
  /**
   * Get all registered providers
   */
  getProviders(): AIProvider[] {
    return Array.from(this.providers.values())
  }
  
  /**
   * Get all configured (ready to use) providers
   */
  async getConfiguredProviders(): Promise<AIProvider[]> {
    const providers = this.getProviders()
    const configured: AIProvider[] = []
    
    for (const provider of providers) {
      if (await provider.isConfigured()) {
        configured.push(provider)
      }
    }
    
    return configured
  }
  
  /**
   * Set the default provider
   */
  setDefaultProvider(type: string): void {
    if (!this.providers.has(type)) {
      throw new Error(`Provider not found: ${type}`)
    }
    this.defaultProvider = type
  }
  
  /**
   * Get the default provider
   */
  getDefaultProvider(): AIProvider | undefined {
    if (this.defaultProvider) {
      return this.providers.get(this.defaultProvider)
    }
    
    // Return the first configured provider
    for (const provider of this.providers.values()) {
      return provider
    }
    
    return undefined
  }
  
  /**
   * Auto-detect and select the best provider for a model
   */
  async selectProviderForModel(model: string): Promise<AIProvider | undefined> {
    // OpenAI models
    if (model.startsWith('gpt-')) {
      const provider = this.providers.get('openai')
      if (provider && await provider.isConfigured()) {
        return provider
      }
    }
    
    // Anthropic models
    if (model.startsWith('claude-')) {
      const provider = this.providers.get('anthropic')
      if (provider && await provider.isConfigured()) {
        return provider
      }
    }
    
    // Fall back to default provider
    return this.getDefaultProvider()
  }
  
  /**
   * Perform completion with auto-provider selection
   */
  async complete(params: AICompletionParams): Promise<AICompletionResponse> {
    const provider = await this.selectProviderForModel(params.model)
    
    if (!provider) {
      throw new Error(`No configured provider found for model: ${params.model}`)
    }
    
    console.log(`[AIProviders] Using ${provider.name} for model: ${params.model}`)
    
    return provider.complete(params)
  }
  
  /**
   * Get available models across all configured providers
   */
  async getAvailableModels(): Promise<Record<string, string[]>> {
    const models: Record<string, string[]> = {}
    
    for (const [type, provider] of this.providers) {
      if (await provider.isConfigured()) {
        models[type] = await provider.getAvailableModels()
      }
    }
    
    return models
  }
  
  /**
   * Test all configured providers
   */
  async testAllProviders(): Promise<Record<string, boolean>> {
    const results: Record<string, boolean> = {}
    
    for (const [type, provider] of this.providers) {
      if (await provider.isConfigured()) {
        results[type] = await provider.testConnection()
      } else {
        results[type] = false
      }
    }
    
    return results
  }
}

// Global provider manager instance
export const aiProviderManager = new AIProviderManager()

