// AI 模型管理器 - 统一调用接口，支持多 Provider fallback
import type { AIProvider, ChatRequest, ChatResponse, ChatMessage, StreamChunk, EmbeddingRequest, EmbeddingResponse } from './types';
import { ZhipuProvider } from './providers/zhipu';
import { OpenAIProvider } from './providers/openai';
import { getConfig } from '../../config';
import { createLogger } from '../../utils/logger';

const log = createLogger('AIManager');

export class AIManager {
  private providers: Map<string, AIProvider> = new Map();
  private defaultProvider: string;

  constructor() {
    const config = getConfig();
    this.defaultProvider = config.ai.provider;

    // 注册智谱 GLM
    if (config.ai.zhipuApiKey) {
      this.providers.set('zhipu', new ZhipuProvider(config.ai.zhipuApiKey));
      log.info('Zhipu GLM provider registered');
    }

    // 注册 OpenAI 兼容
    if (config.ai.openaiApiKey) {
      this.providers.set('openai', new OpenAIProvider(config.ai.openaiApiKey, config.ai.openaiBaseUrl));
      log.info('OpenAI provider registered');
    }

    if (this.providers.size === 0) {
      log.warn('No AI providers configured. Set ZCLAW_ZHIPU_API_KEY or ZCLAW_OPENAI_API_KEY.');
    }
  }

  getProvider(name?: string): AIProvider {
    const providerName = name || this.defaultProvider;
    const provider = this.providers.get(providerName);
    if (!provider) {
      // fallback: 尝试其他可用 provider
      const fallback = this.providers.values().next().value;
      if (fallback) {
        log.warn(`Provider '${providerName}' not available, falling back to '${fallback.name}'`);
        return fallback;
      }
      throw new Error(`No AI provider available. Configure at least one API key.`);
    }
    return provider;
  }

  async chat(request: ChatRequest, providerName?: string): Promise<ChatResponse> {
    const provider = this.getProvider(providerName);
    const config = getConfig();

    const enrichedRequest: ChatRequest = {
      ...request,
      model: request.model || config.ai.defaultModel,
      temperature: request.temperature ?? config.ai.temperature,
      maxTokens: request.maxTokens ?? config.ai.maxTokens,
    };

    log.debug(`Chat via ${provider.name}`, { model: enrichedRequest.model, messages: enrichedRequest.messages.length });

    try {
      const response = await provider.chat(enrichedRequest);
      log.debug(`Chat response: ${response.usage.totalTokens} tokens`);
      return response;
    } catch (error: any) {
      log.error(`Chat failed via ${provider.name}: ${error.message}`);
      // 尝试 fallback
      for (const [name, fallbackProvider] of this.providers) {
        if (name !== provider.name) {
          log.info(`Retrying with fallback provider: ${name}`);
          try {
            return await fallbackProvider.chat(enrichedRequest);
          } catch {
            continue;
          }
        }
      }
      throw error;
    }
  }

  async chatStream(request: ChatRequest, providerName?: string): Promise<AsyncIterable<StreamChunk>> {
    const provider = this.getProvider(providerName);
    if (!provider.chatStream) {
      throw new Error(`Provider '${provider.name}' does not support streaming`);
    }
    return provider.chatStream(request);
  }

  async embed(request: EmbeddingRequest, providerName?: string): Promise<EmbeddingResponse> {
    const provider = this.getProvider(providerName);
    if (!provider.embed) {
      throw new Error(`Provider '${provider.name}' does not support embeddings`);
    }
    return provider.embed(request);
  }

  // 便捷方法：单次对话
  async ask(prompt: string, systemPrompt?: string): Promise<string> {
    const messages: ChatMessage[] = [];
    if (systemPrompt) {
      messages.push({ role: 'system', content: systemPrompt });
    }
    messages.push({ role: 'user', content: prompt });

    const response = await this.chat({ messages });
    return response.content;
  }

  // 便捷方法：带上下文的多轮对话
  async chatWithHistory(messages: ChatMessage[], systemPrompt?: string): Promise<string> {
    const allMessages: ChatMessage[] = [];
    if (systemPrompt) {
      allMessages.push({ role: 'system', content: systemPrompt });
    }
    allMessages.push(...messages);

    const response = await this.chat({ messages: allMessages });
    return response.content;
  }

  // 便捷方法：JSON 输出
  async askJson<T = any>(prompt: string, systemPrompt?: string): Promise<T> {
    const jsonSystemPrompt = (systemPrompt || '') + '\n\n请严格以 JSON 格式输出，不要包含 markdown 代码块标记。';
    const content = await this.ask(prompt, jsonSystemPrompt);

    // 清理可能的 markdown 代码块包裹
    const cleaned = content.replace(/^```(?:json)?\s*\n?/i, '').replace(/\n?```\s*$/i, '').trim();
    return JSON.parse(cleaned) as T;
  }
}

let _manager: AIManager | null = null;

export function getAIManager(): AIManager {
  if (!_manager) {
    _manager = new AIManager();
  }
  return _manager;
}
