import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';

/**
 * [AI_NLP_01] 自然语言处理服务
 * @description 文本分析、情感分析、实体识别、关键词提取，支持多语言
 */
export class NaturalLanguageProcessingService {
  private static readonly NLP_TABLE = 'cf_ai_nlp_processing';
  private static readonly MODEL_TABLE = 'cf_ai_nlp_model';

  /**
   * 初始化表结构
   */
  static async initTable() {
    // 创建NLP处理记录表
    const hasNlpTable = await db.schema.hasTable(this.NLP_TABLE);
    if (!hasNlpTable) {
      console.log(`📦 Creating ${this.NLP_TABLE} table...`);
      await db.schema.createTable(this.NLP_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.text('text_content').notNullable();
        table.string('text_hash', 64).unique();
        table.string('language', 10).defaultTo('zh'); // 语言代码
        table.json('analysis_results'); // 分析结果
        table.json('sentiment_results'); // 情感分析结果
        table.json('entity_results'); // 实体识别结果
        table.json('keyword_results'); // 关键词提取结果
        table.string('status', 16).defaultTo('PROCESSED');
        table.decimal('processing_time', 8, 3); // 处理时间(秒)
        table.integer('text_length'); // 文本长度
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['tenant_id', 'created_at']);
        table.index(['text_hash']);
        table.index(['language']);
      });
    }

    // 创建模型配置表
    const hasModelTable = await db.schema.hasTable(this.MODEL_TABLE);
    if (!hasModelTable) {
      console.log(`📦 Creating ${this.MODEL_TABLE} table...`);
      await db.schema.createTable(this.MODEL_TABLE, (table) => {
        table.increments('id').primary();
        table.string('tenant_id', 64).notNullable();
        table.string('model_name', 100).notNullable();
        table.string('model_type', 50).notNullable(); // sentiment, entity, keyword, analysis
        table.string('language', 10).defaultTo('zh');
        table.json('model_config'); // 模型配置
        table.string('status', 16).defaultTo('ACTIVE');
        table.decimal('accuracy', 5, 2); // 准确率
        table.timestamp('last_trained').defaultTo(db.fn.now());
        table.timestamp('created_at').defaultTo(db.fn.now());
        table.index(['tenant_id', 'model_type', 'language']);
      });
    }

    logger.info('[NaturalLanguageProcessingService] Tables initialized successfully');
  }

  /**
   * 文本处理
   */
  static async processText(params: {
    tenantId: string;
    text: string;
    language?: string;
    tasks: ('analysis' | 'sentiment' | 'entity' | 'keyword')[];
  }): Promise<{
    nlpId: number;
    results: any;
    processingTime: number;
  }> {
    const startTime = Date.now();
    
    try {
      // 1. 验证输入参数
      if (!params.text || params.text.trim().length === 0) {
        throw new Error('Text content cannot be empty');
      }

      // 2. 检测语言（如果未指定）
      const language = params.language || await this.detectLanguage(params.text);
      
      // 3. 计算文本哈希（用于去重）
      const textHash = await this.calculateTextHash(params.text);
      
      // 4. 检查是否已处理过相同文本
      const existingRecord = await db(this.NLP_TABLE)
        .where({ tenant_id: params.tenantId, text_hash: textHash })
        .first();
      
      if (existingRecord) {
        logger.info(`[NLP] Text already processed: ${textHash}`);
        return {
          nlpId: existingRecord.id,
          results: existingRecord.analysis_results,
          processingTime: existingRecord.processing_time || 0
        };
      }

      // 5. 执行NLP处理任务
      const results = await this.executeNlpTasks(params.text, language, params.tasks);
      
      // 6. 保存处理结果
      const nlpId = await db(this.NLP_TABLE).insert({
        tenant_id: params.tenantId,
        text_content: params.text,
        text_hash: textHash,
        language: language,
        analysis_results: results.analysis,
        sentiment_results: results.sentiment,
        entity_results: results.entity,
        keyword_results: results.keyword,
        processing_time: (Date.now() - startTime) / 1000,
        text_length: params.text.length,
        status: 'PROCESSED'
      }).returning('id');

      logger.info(`[NLP] Text processed successfully: ${nlpId}`);
      
      return {
        nlpId: nlpId[0].id,
        results,
        processingTime: (Date.now() - startTime) / 1000
      };

    } catch (error: any) {
      logger.error(`[NLP] Text processing failed: ${error.message}`);
      throw error;
    }
  }

  /**
   * 执行NLP处理任务
   */
  private static async executeNlpTasks(text: string, language: string, tasks: string[]): Promise<any> {
    const results: any = {};
    
    // 模拟NLP处理（实际项目中应集成真实的NLP库）
    if (tasks.includes('analysis')) {
      results.analysis = await this.analyzeText(text, language);
    }
    
    if (tasks.includes('sentiment')) {
      results.sentiment = await this.analyzeSentiment(text, language);
    }
    
    if (tasks.includes('entity')) {
      results.entity = await this.extractEntities(text, language);
    }
    
    if (tasks.includes('keyword')) {
      results.keyword = await this.extractKeywords(text, language);
    }
    
    return results;
  }

  /**
   * 文本分析
   */
  private static async analyzeText(text: string, language: string): Promise<any> {
    // 模拟文本分析逻辑
    const sentences = text.split(/[.!?。！？]/).filter(s => s.trim().length > 0);
    const words = text.split(/\s+/).filter(w => w.length > 0);
    
    return {
      sentenceCount: sentences.length,
      wordCount: words.length,
      avgSentenceLength: words.length / Math.max(sentences.length, 1),
      readabilityScore: parseFloat((Math.random() * 0.3 + 0.7).toFixed(2)),
      complexity: words.length > 100 ? 'high' : words.length > 50 ? 'medium' : 'low',
      language: language
    };
  }

  /**
   * 情感分析
   */
  private static async analyzeSentiment(text: string, language: string): Promise<any> {
    // 模拟情感分析逻辑
    const positiveWords = ['好', '优秀', '满意', '喜欢', '推荐', 'great', 'excellent', 'love'];
    const negativeWords = ['差', '糟糕', '不满意', '讨厌', '不推荐', 'bad', 'terrible', 'hate'];
    
    let positiveScore = 0;
    let negativeScore = 0;
    
    const words = text.toLowerCase().split(/\s+/);
    
    words.forEach(word => {
      if (positiveWords.some(pw => word.includes(pw))) positiveScore++;
      if (negativeWords.some(nw => word.includes(nw))) negativeScore++;
    });
    
    const totalScore = positiveScore + negativeScore;
    const sentimentScore = totalScore > 0 ? (positiveScore - negativeScore) / totalScore : 0;
    
    let sentiment: string;
    if (sentimentScore > 0.3) sentiment = 'positive';
    else if (sentimentScore < -0.3) sentiment = 'negative';
    else sentiment = 'neutral';
    
    return {
      sentiment: sentiment,
      confidence: parseFloat((Math.random() * 0.3 + 0.7).toFixed(2)),
      positiveScore,
      negativeScore,
      overallScore: parseFloat(sentimentScore.toFixed(2))
    };
  }

  /**
   * 实体识别
   */
  private static async extractEntities(text: string, language: string): Promise<any> {
    // 模拟实体识别逻辑
    const entityTypes = ['PERSON', 'ORGANIZATION', 'LOCATION', 'PRODUCT', 'DATE'];
    const entities: any[] = [];
    
    // 简单的实体识别规则
    const patterns = {
      PERSON: /\b(张|李|王|刘|陈|杨|赵|黄|周|吴|林|孙|马|朱|胡|郭|何|高|罗|郑|梁|谢|宋|唐|许|韩|冯|邓|曹|彭|曾|肖|田|董|袁|潘|于|蒋|蔡|余|杜|叶|程|苏|魏|吕|丁|任|沈|姚|卢|姜|崔|钟|谭|陆|汪|范|金|石|廖|贾|夏|韦|傅|方|白|邹|孟|熊|秦|邱|江|尹|薛|闫|段|雷|侯|龙|史|陶|黎|贺|顾|毛|郝|龚|邵|万|钱|严|覃|武|戴|莫|孔|向|汤)\w+\b/g,
      ORGANIZATION: /\b(公司|集团|企业|银行|医院|学校|机构|中心)\b/g,
      LOCATION: /\b(北京|上海|广州|深圳|杭州|成都|武汉|南京|西安|重庆|天津|苏州|长沙|郑州|青岛|大连|宁波|厦门|福州|无锡|合肥|昆明|哈尔滨|济南|佛山|东莞|常州|温州|泉州|南通|嘉兴|绍兴|台州|惠州|珠海|中山|江门|湛江|扬州|镇江|泰州|宿迁|连云港|淮安|盐城|徐州|宿州|阜阳|亳州|六安|安庆|池州|宣城|黄山|芜湖|马鞍山|铜陵|安庆|池州|宣城|黄山|芜湖|马鞍山|铜陵)\b/g,
      PRODUCT: /\b(手机|电脑|电视|空调|冰箱|洗衣机|汽车|服装|食品|药品|书籍|家具|电器|化妆品|珠宝|手表|包包|鞋子|玩具|运动器材)\b/g,
      DATE: /\b(\d{4}年\d{1,2}月\d{1,2}日|\d{4}-\d{1,2}-\d{1,2}|今天|明天|昨天|本周|下周|上月|下月|今年|明年|去年)\b/g
    };
    
    for (const [type, pattern] of Object.entries(patterns)) {
      const matches = text.match(pattern) || [];
      matches.forEach(match => {
        entities.push({
          entity: match,
          type: type,
          confidence: parseFloat((Math.random() * 0.3 + 0.7).toFixed(2))
        });
      });
    }
    
    return {
      entities,
      entityCount: entities.length,
      entityTypes: [...new Set(entities.map(e => e.type))]
    };
  }

  /**
   * 关键词提取
   */
  private static async extractKeywords(text: string, language: string): Promise<any> {
    // 模拟关键词提取逻辑
    const stopWords = ['的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这', '那', '他', '她', '它'];
    
    const words = text.split(/\s+|[,.;!?，。；！？]/).filter(word => 
      word.length > 1 && !stopWords.includes(word)
    );
    
    const wordFreq: Record<string, number> = {};
    words.forEach(word => {
      wordFreq[word] = (wordFreq[word] || 0) + 1;
    });
    
    const keywords = Object.entries(wordFreq)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 10)
      .map(([word, freq]) => ({
        keyword: word,
        frequency: freq,
        score: parseFloat((freq / words.length * 100).toFixed(2))
      }));
    
    return {
      keywords,
      keywordCount: keywords.length,
      totalWords: words.length
    };
  }

  /**
   * 语言检测
   */
  private static async detectLanguage(text: string): Promise<string> {
    // 简单的语言检测逻辑
    const chineseChars = text.match(/[\u4e00-\u9fff]/g) || [];
    const englishWords = text.match(/\b[a-zA-Z]+\b/g) || [];
    
    const chineseRatio = chineseChars.length / Math.max(text.length, 1);
    const englishRatio = englishWords.length / Math.max(text.split(/\s+/).length, 1);
    
    if (chineseRatio > 0.3) return 'zh';
    if (englishRatio > 0.5) return 'en';
    return 'zh'; // 默认中文
  }

  /**
   * 计算文本哈希
   */
  private static async calculateTextHash(text: string): Promise<string> {
    const crypto = require('crypto');
    return crypto.createHash('md5').update(text).digest('hex');
  }

  /**
   * 获取处理历史
   */
  static async getProcessingHistory(tenantId: string, limit: number = 50): Promise<any[]> {
    return db(this.NLP_TABLE)
      .where({ tenant_id: tenantId })
      .orderBy('created_at', 'desc')
      .limit(limit);
  }

  /**
   * 批量处理文本
   */
  static async batchProcessTexts(params: {
    tenantId: string;
    texts: string[];
    language?: string;
    tasks: ('analysis' | 'sentiment' | 'entity' | 'keyword')[];
  }): Promise<{
    processed: number;
    failed: number;
    results: any[];
  }> {
    const results = [];
    let processed = 0;
    let failed = 0;

    for (const text of params.texts) {
      try {
        const result = await this.processText({
          tenantId: params.tenantId,
          text,
          language: params.language,
          tasks: params.tasks
        });
        results.push(result);
        processed++;
      } catch (error: any) {
        logger.error(`[NLP] Batch processing failed for text: ${error.message}`);
        failed++;
      }
    }

    return { processed, failed, results };
  }

  /**
   * 获取模型性能统计
   */
  static async getModelStats(tenantId: string): Promise<any> {
    const stats = await db(this.NLP_TABLE)
      .where({ tenant_id: tenantId })
      .select(
        db.raw('COUNT(*) as total_texts'),
        db.raw('AVG(processing_time) as avg_processing_time'),
        db.raw('MAX(processing_time) as max_processing_time'),
        db.raw('MIN(processing_time) as min_processing_time'),
        db.raw('AVG(text_length) as avg_text_length')
      )
      .first();

    return {
      totalTexts: stats.total_texts || 0,
      avgProcessingTime: parseFloat(stats.avg_processing_time || 0).toFixed(3),
      maxProcessingTime: parseFloat(stats.max_processing_time || 0).toFixed(3),
      minProcessingTime: parseFloat(stats.min_processing_time || 0).toFixed(3),
      avgTextLength: parseFloat(stats.avg_text_length || 0).toFixed(0)
    };
  }

  /**
   * 多语言支持检查
   */
  static async getSupportedLanguages(): Promise<string[]> {
    return ['zh', 'en', 'ja', 'ko', 'fr', 'de', 'es', 'ru'];
  }
}