/**
 * AI Service
 * 支持 6 个主流 AI 服务商进行文档智能分析
 * - GLM (智谱 AI)
 * - MiniMax
 * - DeepSeek
 * - Kimi (月之暗面)
 * - OpenAI
 * - Anthropic (Claude)
 */

import { prisma } from '../lib/prisma';

// AI Provider 类型
export type AIProviderType = 'glm' | 'minimax' | 'deepseek' | 'kimi' | 'openai' | 'anthropic';

// AI 分析结果
export interface AIAnalysisResult {
  suggested_tags: string[];
  suggested_category?: string;
  summary?: string;
  raw_response: string;
  provider: AIProviderType;
  model: string;
}

// AI Provider 配置
export interface AIProviderConfig {
  apiKey: string;
  apiUrl: string;
  model: string;
}

// Provider 配置映射
export interface AIConfig {
  defaultProvider: AIProviderType;
  glm: AIProviderConfig;
  minimax: AIProviderConfig;
  deepseek: AIProviderConfig;
  kimi: AIProviderConfig;
  openai: AIProviderConfig;
  anthropic: AIProviderConfig;
}

// 分析选项
export interface AnalyzeOptions {
  provider?: AIProviderType;
  config?: AIConfig;
  generateSummary?: boolean;
  maxTags?: number;
}

// API 响应接口
interface ChatMessage {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

interface ChatCompletionResponse {
  choices: Array<{
    message: {
      content: string;
    };
  }>;
  usage?: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
}

interface AnthropicResponse {
  content: Array<{
    type: string;
    text: string;
  }>;
  usage?: {
    input_tokens: number;
    output_tokens: number;
  };
}

/**
 * AI 服务类
 */
export class AIService {
  /**
   * 从环境变量或用户配置获取 AI 配置
   */
  private static getAIConfig(_userId: string): AIConfig {
    return {
      defaultProvider: 'glm',
      glm: {
        apiKey: process.env.GLM_API_KEY || '',
        apiUrl: process.env.GLM_API_URL || 'https://open.bigmodel.cn/api/paas/v4/chat/completions',
        model: process.env.GLM_MODEL || 'glm-4-flash',
      },
      minimax: {
        apiKey: process.env.MINIMAX_API_KEY || '',
        apiUrl: process.env.MINIMAX_API_URL || 'https://api.minimax.chat/v1/chat/completions',
        model: process.env.MINIMAX_MODEL || 'abab6.5s-chat',
      },
      deepseek: {
        apiKey: process.env.DEEPSEEK_API_KEY || '',
        apiUrl: process.env.DEEPSEEK_API_URL || 'https://api.deepseek.com/v1/chat/completions',
        model: process.env.DEEPSEEK_MODEL || 'deepseek-chat',
      },
      kimi: {
        apiKey: process.env.KIMI_API_KEY || '',
        apiUrl: process.env.KIMI_API_URL || 'https://api.moonshot.cn/v1/chat/completions',
        model: process.env.KIMI_MODEL || 'moonshot-v1-8k',
      },
      openai: {
        apiKey: process.env.OPENAI_API_KEY || '',
        apiUrl: process.env.OPENAI_API_URL || 'https://api.openai.com/v1/chat/completions',
        model: process.env.OPENAI_MODEL || 'gpt-4o-mini',
      },
      anthropic: {
        apiKey: process.env.ANTHROPIC_API_KEY || '',
        apiUrl: process.env.ANTHROPIC_API_URL || 'https://api.anthropic.com/v1/messages',
        model: process.env.ANTHROPIC_MODEL || 'claude-3-5-sonnet-20241022',
      },
    };
  }

  /**
   * 调用 OpenAI 兼容的 API (GLM, MiniMax, DeepSeek, Kimi, OpenAI)
   */
  private static async callOpenAICompatibleAPI(
    config: AIProviderConfig,
    messages: ChatMessage[]
  ): Promise<string> {
    const response = await fetch(config.apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${config.apiKey}`,
      },
      body: JSON.stringify({
        model: config.model,
        messages,
        temperature: 0.3,
        max_tokens: 1000,
      }),
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`API 请求失败 (${response.status}): ${errorText}`);
    }

    const data = await response.json() as ChatCompletionResponse;
    return data.choices[0]?.message?.content || '';
  }

  /**
   * 调用 Anthropic Claude API
   */
  private static async callAnthropicAPI(
    config: AIProviderConfig,
    messages: ChatMessage[]
  ): Promise<string> {
    // Anthropic API 需要提取 system 消息
    const systemMessage = messages.find(m => m.role === 'system')?.content || '';
    const userMessages = messages.filter(m => m.role !== 'system');

    const response = await fetch(config.apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': config.apiKey,
        'anthropic-version': '2023-06-01',
      },
      body: JSON.stringify({
        model: config.model,
        system: systemMessage,
        messages: userMessages,
        max_tokens: 1000,
      }),
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`Anthropic API 请求失败 (${response.status}): ${errorText}`);
    }

    const data = await response.json() as AnthropicResponse;
    return data.content[0]?.text || '';
  }

  /**
   * 调用 AI Provider 分析文档
   */
  private static async callAIProvider(
    provider: AIProviderType,
    config: AIConfig,
    content: string,
    prompt: string
  ): Promise<string> {
    const providerConfig = config[provider];

    if (!providerConfig.apiKey) {
      throw new Error(`${provider} API Key 未配置`);
    }

    const messages: ChatMessage[] = [
      {
        role: 'system',
        content: `你是一个智能文档分析助手。${prompt}`,
      },
      {
        role: 'user',
        content: `请分析以下文档内容：\n\n${content}`,
      },
    ];

    // Anthropic 使用不同的 API 格式
    if (provider === 'anthropic') {
      return this.callAnthropicAPI(providerConfig, messages);
    }

    // 其他 Provider 使用 OpenAI 兼容格式
    return this.callOpenAICompatibleAPI(providerConfig, messages);
  }

  /**
   * 解析 AI 响应，提取结构化数据
   */
  private static parseAIResponse(response: string): {
    tags: string[];
    category?: string;
    summary?: string;
  } {
    const result = {
      tags: [] as string[],
      category: undefined as string | undefined,
      summary: undefined as string | undefined,
    };

    // 尝试解析 JSON 格式响应
    try {
      // 查找 JSON 块
      const jsonMatch = response.match(/\{[\s\S]*\}/);
      if (jsonMatch) {
        const parsed = JSON.parse(jsonMatch[0]);
        result.tags = parsed.tags || [];
        result.category = parsed.category;
        result.summary = parsed.summary;
        return result;
      }
    } catch (e) {
      // JSON 解析失败，使用文本解析
    }

    // 文本解析：按行查找标签、分类和摘要
    const lines = response.split('\n');
    for (const line of lines) {
      const lowerLine = line.toLowerCase().trim();

      if (lowerLine.startsWith('标签:') || lowerLine.startsWith('tags:')) {
        const tags = line.substring(line.indexOf(':') + 1).trim();
        result.tags = tags.split(/[,，、]/).map(t => t.trim()).filter(t => t);
      } else if (lowerLine.startsWith('分类:') || lowerLine.startsWith('category:')) {
        result.category = line.substring(line.indexOf(':') + 1).trim();
      } else if (lowerLine.startsWith('摘要:') || lowerLine.startsWith('summary:')) {
        result.summary = line.substring(line.indexOf(':') + 1).trim();
      }
    }

    // 如果没有找到标签，尝试从响应中提取关键词
    if (result.tags.length === 0) {
      const words = response.match(/[\u4e00-\u9fa5]{2,4}/g) || [];
      result.tags = [...new Set(words)].slice(0, 5);
    }

    return result;
  }

  /**
   * 分析文档内容，生成智能标签和分类
   */
  static async analyzeDocument(
    documentId: string,
    userId: string,
    options: AnalyzeOptions = {}
  ): Promise<AIAnalysisResult> {
    // 获取文档
    const document = await prisma.document.findFirst({
      where: {
        id: documentId,
        user_id: userId,
      },
    });

    if (!document) {
      throw new Error('文档不存在或无权访问');
    }

    // 获取 AI 配置
    const config = options.config || this.getAIConfig(userId);
    const provider = options.provider || config.defaultProvider;

    // 检查 API Key
    const providerConfig = config[provider];
    if (!providerConfig.apiKey) {
      throw new Error(`${provider} API Key 未配置，请在设置页面配置`);
    }

    // 构建分析提示词
    const prompt = `请分析文档内容，返回以下信息（JSON 格式）：
{
  "tags": ["标签1", "标签2", "标签3"],  // 3-5个关键词标签
  "category": "建议的分类名称",           // 可选
  "summary": "一句话摘要"                // 可选
}

要求：
1. 标签应该能体现文档的核心内容
2. 分类应该简洁明了（如：工作、学习、生活、技术等）
3. 摘要应该简洁概括文档要点
4. 直接返回 JSON，不要有其他内容`;

    // 调用 AI API
    try {
      const rawResponse = await this.callAIProvider(
        provider,
        config,
        document.content,
        prompt
      );

      // 解析响应
      const parsed = this.parseAIResponse(rawResponse);

      // 限制标签数量
      const maxTags = options.maxTags || 5;
      const suggestedTags = parsed.tags.slice(0, maxTags);

      // 保存分析结果到数据库
      await prisma.aIAnalysis.upsert({
        where: { document_id: documentId },
        create: {
          document_id: documentId,
          provider,
          model: providerConfig.model,
          suggested_tags: JSON.stringify(suggestedTags),
          suggested_category: parsed.category,
          summary: parsed.summary,
          raw_response: rawResponse,
        },
        update: {
          provider,
          model: providerConfig.model,
          suggested_tags: JSON.stringify(suggestedTags),
          suggested_category: parsed.category,
          summary: parsed.summary,
          raw_response: rawResponse,
        },
      });

      return {
        suggested_tags: suggestedTags,
        suggested_category: parsed.category,
        summary: parsed.summary,
        raw_response: rawResponse,
        provider,
        model: providerConfig.model,
      };
    } catch (error) {
      console.error('[AI] 分析失败:', error);
      throw error;
    }
  }

  /**
   * 获取文档的 AI 分析结果
   */
  static async getAnalysis(documentId: string, userId: string) {
    // 验证文档所有权
    const document = await prisma.document.findFirst({
      where: {
        id: documentId,
        user_id: userId,
      },
    });

    if (!document) {
      throw new Error('文档不存在或无权访问');
    }

    const analysis = await prisma.aIAnalysis.findUnique({
      where: { document_id: documentId },
    });

    if (!analysis) {
      return null;
    }

    return {
      ...analysis,
      suggested_tags: JSON.parse(analysis.suggested_tags),
    };
  }

  /**
   * 删除文档的 AI 分析结果
   */
  static async deleteAnalysis(documentId: string, userId: string) {
    // 验证文档所有权
    const document = await prisma.document.findFirst({
      where: {
        id: documentId,
        user_id: userId,
      },
    });

    if (!document) {
      throw new Error('文档不存在或无权访问');
    }

    await prisma.aIAnalysis.delete({
      where: { document_id: documentId },
    });
  }

  /**
   * 测试 AI Provider 连接
   */
  static async testProvider(
    provider: AIProviderType,
    config?: Partial<AIConfig>
  ): Promise<{
    success: boolean;
    message: string;
    error?: string;
  }> {
    try {
      const fullConfig = config ? { ...this.getAIConfig(''), ...config } : this.getAIConfig('');
      const providerConfig = fullConfig[provider];

      if (!providerConfig.apiKey) {
        return {
          success: false,
          message: 'API Key 未配置',
          error: `${provider} API Key 未配置`,
        };
      }

      // 发送简单测试请求
      const messages: ChatMessage[] = [
        {
          role: 'user',
          content: 'Hi',
        },
      ];

      if (provider === 'anthropic') {
        await this.callAnthropicAPI(providerConfig, messages);
      } else {
        await this.callOpenAICompatibleAPI(providerConfig, messages);
      }

      return {
        success: true,
        message: `${provider} 连接成功`,
      };
    } catch (error) {
      return {
        success: false,
        message: '连接失败',
        error: error instanceof Error ? error.message : String(error),
      };
    }
  }
}
