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

/**
 * [BIZ_KER_123] 数据库死锁自动检测与解除建议 (Deadlock)
 * @description 核心逻辑：扫描数据库引擎状态，识别当前存在的死锁或长事务阻塞。
 * 提取阻塞的事务日志、涉及的表及 SQL 语句。
 * 输出结构化的解除建议，帮助开发者优化事务传播行为。
 * 遵循 Autocomplete-First (V31.5) 规范。
 */
export class DeadlockAdvisor {
  private static readonly SCAN_INTERVAL_MS = 300000; // 每 5 分钟扫描一次

  /**
   * 初始化死锁监听
   */
  static async init() {
    logger.info(`[DeadlockAdvisor] Initializing database deadlock monitor...`);
    this.runScan();
    setInterval(() => this.runScan(), this.SCAN_INTERVAL_MS);
  }

  /**
   * 执行死锁与阻塞扫描
   * @private
   */
  private static async runScan() {
    try {
      // 1. 获取 InnoDB 引擎状态 (MySQL 专用)
      const engineStatus = await db.raw('SHOW ENGINE INNODB STATUS');
      const statusText = engineStatus[0][0].Status;

      // 2. 分析是否存在 LATEST DETECTED DEADLOCK
      if (statusText.includes('LATEST DETECTED DEADLOCK')) {
        await this.processDeadlock(statusText);
      }

      // 3. 检查长事务阻塞 (Wait Locks)
      const blockingQueries = await db.raw(`
        SELECT 
          r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query,
          b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query
        FROM information_schema.innodb_lock_waits w
        INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
        INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id
      `);

      if (blockingQueries[0].length > 0) {
        await this.processBlocking(blockingQueries[0]);
      }

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

  /**
   * 处理死锁日志
   * @private
   */
  private static async processDeadlock(statusText: string) {
    // 提取死锁部分文本
    const deadlockLog = statusText.split('LATEST DETECTED DEADLOCK')[1].split('------------')[0];
    const report = `### 🧱 Database Deadlock Detected!\n\n` +
                   `**Engine Log Fragment:**\n\`\`\`\n${deadlockLog.trim().substring(0, 1000)}\n\`\`\`\n\n` +
                   `**Recommendation:** 请检查涉及表的更新顺序，确保所有事务按相同顺序请求锁。建议缩短事务范围并增加索引以减少行锁。`;
    
    await SemanticLogService.logSemantic(report, 'ERROR', 'DB_ADVISOR');
    logger.error(`[DeadlockAdvisor] Deadlock detected and reported to semantic log.`);
  }

  /**
   * 处理阻塞查询
   * @private
   */
  private static async processBlocking(blockingList: any[]) {
    let report = `### ⏳ Database Transaction Blocking Detected!\n\n`;
    blockingList.forEach((b: any) => {
      report += `- **Waiting Query:** \`${b.waiting_query}\` (Thread: ${b.waiting_thread})\n`;
      report += `- **Blocking Query:** \`${b.blocking_query}\` (Thread: ${b.blocking_thread})\n\n`;
    });
    report += `**Recommendation:** 识别到长事务持锁时间过长，请检查是否在事务中执行了外部 API 调用或耗时逻辑。`;

    await SemanticLogService.logSemantic(report, 'WARN', 'DB_ADVISOR');
    logger.warn(`[DeadlockAdvisor] ${blockingList.length} blocking transactions detected.`);
  }
}
