//
//  ProviderRegistry.swift
//  Confab
//
//  Registry for managing multiple AI providers
//
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
// Copyright (C) 2026 Rune Olsen
//
// This file is part of Confab.
//
// Confab is licensed under the PolyForm Noncommercial License 1.0.0.
// You may use, study, modify, and share it for any noncommercial
// purpose. Commercial use — including selling Confab or any part of
// it, standalone or bundled into another product or service —
// requires a separate commercial license from the copyright holder.
//
// See the LICENSE file or
// <https://polyformproject.org/licenses/noncommercial/1.0.0> for
// the full license text. For commercial licensing, contact Rune
// Olsen via <https://confab.no>.


import Foundation
import os

class ProviderRegistry {
    static let shared = ProviderRegistry()
    
    private var providers: [Settings.Provider: AIProvider] = [:]
    private let settings = SettingsService.shared
    
    private init() {}
    
    // MARK: - Get Provider
    
    func getProvider(for providerType: Settings.Provider) -> AIProvider? {
        // Return cached provider if exists
        if let provider = providers[providerType] {
            return provider
        }
        
        // Create new provider based on type
        let provider: AIProvider?

        switch providerType {
        case .openrouter:
            guard let apiKey = settings.openrouterAPIKey, !apiKey.isEmpty else {
                Log.api.warning("No API key configured for OpenRouter")
                return nil
            }
            provider = OpenRouterProvider(apiKey: apiKey)

        case .anthropic:
            guard let apiKey = settings.anthropicAPIKey, !apiKey.isEmpty else {
                Log.api.warning("No API key configured for Anthropic")
                return nil
            }
            provider = AnthropicProvider(apiKey: apiKey)

        case .openai:
            guard let apiKey = settings.openaiAPIKey, !apiKey.isEmpty else {
                Log.api.warning("No API key configured for OpenAI")
                return nil
            }
            provider = OpenAIProvider(apiKey: apiKey)

        case .ollama:
            provider = OllamaProvider(baseURL: settings.ollamaEffectiveURL)

        case .appleOnDevice:
            provider = AppleFoundationProvider()
        }
        
        // Cache and return
        if let provider = provider {
            Log.api.info("Created \(providerType.rawValue) provider")
            providers[providerType] = provider
        }
        
        return provider
    }
    
    // MARK: - Current Provider
    
    func getCurrentProvider() -> AIProvider? {
        let currentProviderType = settings.defaultProvider
        return getProvider(for: currentProviderType)
    }
    
    // MARK: - Clear Cache
    
    func clearCache() {
        providers.removeAll()
    }
    
    // MARK: - Validate API Key
    
    func hasValidAPIKey(for providerType: Settings.Provider) -> Bool {
        switch providerType {
        case .openrouter:
            return settings.openrouterAPIKey != nil && !settings.openrouterAPIKey!.isEmpty
        case .anthropic:
            return AnthropicOAuthService.shared.isAuthenticated
                || (settings.anthropicAPIKey != nil && !settings.anthropicAPIKey!.isEmpty)
        case .openai:
            return settings.openaiAPIKey != nil && !settings.openaiAPIKey!.isEmpty
        case .ollama:
            return settings.ollamaConfigured
        case .appleOnDevice:
            return true  // no API key needed
        }
    }

    /// Providers that have credentials configured (API key or, for Ollama, a saved URL)
    var configuredProviders: [Settings.Provider] {
        Settings.Provider.allCases.filter { hasValidAPIKey(for: $0) }
    }
}
