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

/**
 * [BIZ_INF_102] 慢查询自动 EXPLAIN 建议 (SlowQueryAdvisor)
 * @description 核心逻辑：拦截数据库执行时长超过阈值的慢查询。
 * 自动对该 SQL 执行 EXPLAIN 并提取索引使用、全表扫描等风险点。
 * 输出结构化的优化建议（Markdown 格式），并联动语义日志中心进行归档。
 */
export class SlowQueryAdvisor {
  private static readonly SLOW_QUERY_THRESHOLD_MS = 1000; // 慢查询阈值：1秒

  /**
   * 初始化慢查询监听
   */
  static init() {
    const queries: Map<string, number> = new Map();

    db.on('query', (query) => {
      queries.set(query.__knexUid, Date.now());
    });

    db.on('query-response', (response, query) => {
      const startTime = queries.get(query.__knexUid);
      if (startTime) {
        const duration = Date.now() - startTime;
        if (duration >= this.SLOW_QUERY_THRESHOLD_MS) {
          this.analyzeSlowQuery(query.sql, query.bindings, duration);
        }
        queries.delete(query.__knexUid);
      }
    });

    logger.info(`[SlowQueryAdvisor] Monitoring enabled (Threshold: ${this.SLOW_QUERY_THRESHOLD_MS}ms)`);
  }

  /**
   * 分析慢查询并生成 EXPLAIN 报告
   */
  private static async analyzeSlowQuery(sql: string, bindings: any[], duration: number) {
    try {
      // 1. 执行 EXPLAIN
      const explainResult = await db.raw(`EXPLAIN ${sql}`, bindings);
      const rows = explainResult[0];

      // 2. 生成 Markdown 报告
      let report = `### 🐢 Slow Query Detected (${duration}ms)\n\n`;
      report += `**SQL:** \`${sql}\`\n\n`;
      report += `**Bindings:** \`${JSON.stringify(bindings)}\`\n\n`;
      report += `| Table | Type | Possible Keys | Key | Key Len | Rows | Extra |\n`;
      report += `| --- | --- | --- | --- | --- | --- | --- |\n`;

      let riskPoints: string[] = [];

      for (const row of rows) {
        report += `| ${row.table} | ${row.type} | ${row.possible_keys || 'NULL'} | ${row.key || 'NULL'} | ${row.key_len} | ${row.rows} | ${row.Extra} |\n`;
        
        // 识别风险点
        if (row.type === 'ALL') riskPoints.push(`⚠️ 表 \`${row.table}\` 正在执行全表扫描 (Type: ALL)`);
        if (!row.key && row.possible_keys) riskPoints.push(`💡 表 \`${row.table}\` 有可用索引但未使用，请核查 SQL 编写`);
        if (row.Extra && row.Extra.includes('Using filesort')) riskPoints.push(`❌ 表 \`${row.table}\` 触发了文件排序 (Using filesort)`);
        if (row.Extra && row.Extra.includes('Using temporary')) riskPoints.push(`❌ 表 \`${row.table}\` 触发了临时表 (Using temporary)`);
      }

      if (riskPoints.length > 0) {
        report += `\n**Optimization Advice:**\n`;
        riskPoints.forEach(p => report += `- ${p}\n`);
      } else {
        report += `\n**Status:** 索引使用正常，可能是由于数据量过大或网络延迟引起。\n`;
      }

      // 3. 记录到语义日志中心
      await SemanticLogService.logSemantic(report, 'WARN', 'DB_ADVISOR');
      logger.warn(`[SlowQueryAdvisor] Report generated for query: ${sql.substring(0, 50)}...`);

    } catch (err: any) {
      logger.error(`[SlowQueryAdvisor] Analysis failed: ${err.message}`);
    }
  }
}
