import { Injectable, Logger } from '@nestjs/common';
import {
  LLMProvider,
  ChatMessage,
  ChatOptions,
  ChatResponse,
  StreamCallbacks,
} from '../interfaces/llm-provider.interface';

/**
 * Mock LLM Provider
 * 
 * 用于开发和测试环境，模拟 LLM 响应
 */
@Injectable()
export class MockLLMProvider implements LLMProvider {
  private readonly logger = new Logger(MockLLMProvider.name);

  /**
   * 预设的模拟响应
   */
  private readonly mockResponses: Record<string, string> = {
    default: '感谢您的提问！作为企业智能助手，我可以帮助您解答 IT、HR、行政等方面的问题。请问有什么可以帮助您的？',
    
    it: '关于 IT 相关问题，我可以帮您解答：\n\n1. **密码重置**: 请访问 IT 自助服务门户或联系 IT 热线\n2. **VPN 连接**: 请确保已安装最新版本的 VPN 客户端\n3. **软件安装**: 请通过软件中心申请安装\n\n如需进一步帮助，可以选择"转人工"让 IT 团队为您服务。',
    
    hr: '关于 HR 相关问题，以下是常见解答：\n\n1. **请假申请**: 请通过 OA 系统提交请假申请\n2. **社保查询**: 请登录人事自助系统查看\n3. **报销流程**: 请在费用系统提交报销单\n\n如有其他问题，请咨询您的 HRBP。',
    
    admin: '关于行政服务：\n\n1. **会议室预约**: 请使用日历系统预约\n2. **办公用品**: 请联系行政前台\n3. **快递收发**: 请到前台登记\n\n行政服务热线: 内线 1000',
    
    greeting: '您好！我是企业智能助手，很高兴为您服务。\n\n我可以帮您解答以下类型的问题：\n- 🖥️ IT 技术支持\n- 👥 人力资源咨询\n- 🏢 行政服务\n\n请告诉我您需要什么帮助？',
    
    escalate: '我理解您的问题可能需要更专业的支持。建议您可以：\n\n1. 点击"转人工"按钮，将问题升级给专业团队\n2. 详细描述您的问题，以便我们更好地为您服务\n\n转人工后，相关团队会尽快与您联系。',
  };

  constructor() {
    this.logger.log('Mock LLM Provider 已初始化（开发/测试模式）');
  }

  /**
   * 发送聊天消息并获取完整响应
   */
  async chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse> {
    // 模拟网络延迟
    await this.delay(500);

    const lastUserMessage = this.getLastUserMessage(messages);
    const response = this.generateResponse(lastUserMessage);

    return {
      content: response,
      finishReason: 'stop',
      usage: {
        promptTokens: this.estimateTokens(messages),
        completionTokens: this.estimateTokens([{ role: 'assistant', content: response }]),
        totalTokens: this.estimateTokens(messages) + this.estimateTokens([{ role: 'assistant', content: response }]),
      },
    };
  }

  /**
   * 发送聊天消息并获取流式响应
   */
  async streamChat(
    messages: ChatMessage[],
    callbacks: StreamCallbacks,
    options?: ChatOptions,
  ): Promise<void> {
    const lastUserMessage = this.getLastUserMessage(messages);
    const response = this.generateResponse(lastUserMessage);

    // 模拟流式输出
    const words = response.split('');
    let fullContent = '';

    for (const char of words) {
      await this.delay(20); // 模拟打字效果
      fullContent += char;
      callbacks.onToken(char);
    }

    callbacks.onComplete(fullContent, {
      promptTokens: this.estimateTokens(messages),
      completionTokens: this.estimateTokens([{ role: 'assistant', content: fullContent }]),
      totalTokens: this.estimateTokens(messages) + this.estimateTokens([{ role: 'assistant', content: fullContent }]),
    });
  }

  /**
   * 检查服务是否可用
   */
  async isAvailable(): Promise<boolean> {
    return true;
  }

  /**
   * 生成模拟响应
   */
  private generateResponse(userMessage: string): string {
    const lowerMessage = userMessage.toLowerCase();

    // 问候语
    if (this.containsAny(lowerMessage, ['你好', '您好', 'hello', 'hi', '早上好', '下午好', '晚上好'])) {
      return this.mockResponses.greeting;
    }

    // IT 相关
    if (this.containsAny(lowerMessage, ['密码', 'vpn', '网络', '电脑', '软件', '系统', 'it', '邮箱', '打印'])) {
      return this.mockResponses.it;
    }

    // HR 相关
    if (this.containsAny(lowerMessage, ['请假', '社保', '公积金', '工资', '报销', 'hr', '福利', '考勤', '入职', '离职'])) {
      return this.mockResponses.hr;
    }

    // 行政相关
    if (this.containsAny(lowerMessage, ['会议室', '快递', '办公用品', '行政', '访客', '前台'])) {
      return this.mockResponses.admin;
    }

    // 转人工
    if (this.containsAny(lowerMessage, ['转人工', '人工', '客服', '帮不了', '解决不了'])) {
      return this.mockResponses.escalate;
    }

    // 默认响应
    return this.mockResponses.default;
  }

  /**
   * 获取最后一条用户消息
   */
  private getLastUserMessage(messages: ChatMessage[]): string {
    const userMessages = messages.filter((m) => m.role === 'user');
    return userMessages[userMessages.length - 1]?.content || '';
  }

  /**
   * 检查字符串是否包含指定关键词
   */
  private containsAny(str: string, keywords: string[]): boolean {
    return keywords.some((keyword) => str.includes(keyword));
  }

  /**
   * 估算 Token 数量（简单估算）
   */
  private estimateTokens(messages: ChatMessage[]): number {
    const totalChars = messages.reduce((sum, m) => sum + m.content.length, 0);
    // 大约 2 个中文字符 = 1 个 token，4 个英文字符 = 1 个 token
    return Math.ceil(totalChars / 2);
  }

  /**
   * 延迟函数
   */
  private delay(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
}
