/**
 * 数据库连接监控工具
 * @file db-monitor.js
 * @description 实时监控数据库连接状态
 */
const { sequelize } = require('./database-pool');
const { QueryTypes } = require('sequelize');
const EventEmitter = require('events');

// 创建事件发射器
const dbEvents = new EventEmitter();

/**
 * 检查数据库连接状态
 * @returns {Promise<Object>} 连接状态信息
 */
async function checkConnectionStatus() {
  try {
    // 测试连接
    await sequelize.authenticate();
    
    // 获取连接信息
    const processlist = await sequelize.query(
      'SHOW PROCESSLIST',
      { type: QueryTypes.SELECT }
    );
    
    // 获取连接统计信息
    const connectionStats = await sequelize.query(
      'SELECT * FROM performance_schema.host_cache',
      { type: QueryTypes.SELECT }
    ).catch(() => []);
    
    // 获取等待事件
    const waitEvents = await sequelize.query(
      'SELECT * FROM performance_schema.events_waits_current LIMIT 10',
      { type: QueryTypes.SELECT }
    ).catch(() => []);
    
    // 返回状态信息
    const status = {
      connected: true,
      connections: processlist.length,
      connectionStats: connectionStats,
      waitEvents: waitEvents,
      timestamp: new Date()
    };
    
    // 触发状态更新事件
    dbEvents.emit('status_update', status);
    
    return status;
  } catch (error) {
    // 连接失败
    const errorStatus = {
      connected: false,
      error: error.message,
      timestamp: new Date()
    };
    
    // 触发错误事件
    dbEvents.emit('connection_error', errorStatus);
    
    return errorStatus;
  }
}

/**
 * 获取连接池状态
 * @returns {Promise<Object>} 连接池状态
 */
async function getPoolStatus() {
  try {
    const pool = sequelize.connectionManager.pool;
    
    if (!pool) {
      return { error: '连接池未初始化' };
    }
    
    const status = {
      total: pool.size,
      available: pool.available,
      borrowed: pool.borrowed,
      pending: pool.pending,
      max: pool.max,
      min: pool.min,
      idle: pool.idleTimeoutMillis,
      acquire: pool.acquireTimeoutMillis
    };
    
    // 触发连接池状态更新事件
    dbEvents.emit('pool_status_update', status);
    
    return status;
  } catch (error) {
    console.error('获取连接池状态失败:', error);
    return { error: error.message };
  }
}

/**
 * 识别慢查询
 * @param {number} threshold 慢查询阈值（毫秒）
 * @returns {Promise<Array>} 慢查询列表
 */
async function identifySlowQueries(threshold = 1000) {
  try {
    const slowQueries = await sequelize.query(
      'SELECT * FROM information_schema.PROCESSLIST WHERE TIME > ?',
      {
        replacements: [threshold / 1000], // 转换为秒
        type: QueryTypes.SELECT
      }
    );
    
    if (slowQueries.length > 0) {
      // 触发慢查询事件
      dbEvents.emit('slow_queries_detected', slowQueries);
    }
    
    return slowQueries;
  } catch (error) {
    console.error('识别慢查询失败:', error);
    return [];
  }
}

/**
 * 记录数据库错误
 * @param {Error} error 错误对象
 */
function logDatabaseError(error) {
  const errorLog = {
    message: error.message,
    stack: error.stack,
    timestamp: new Date()
  };
  
  // 触发错误日志事件
  dbEvents.emit('error_logged', errorLog);
  
  console.error('数据库错误:', error);
}

/**
 * 启动定期监控
 * @param {number} interval 监控间隔（毫秒）
 * @returns {Object} 监控器对象
 */
function startMonitoring(interval = 60000) {
  // 创建监控器
  const monitor = {
    interval: null,
    isRunning: false,
    lastStatus: null,
    start: function() {
      if (this.isRunning) return;
      
      this.isRunning = true;
      this.interval = setInterval(async () => {
        try {
          // 检查连接状态
          this.lastStatus = await checkConnectionStatus();
          
          // 检查连接池状态
          await getPoolStatus();
          
          // 检查慢查询
          await identifySlowQueries();
        } catch (error) {
          logDatabaseError(error);
        }
      }, interval);
      
      dbEvents.emit('monitoring_started', { interval });
      return this;
    },
    stop: function() {
      if (!this.isRunning) return;
      
      clearInterval(this.interval);
      this.interval = null;
      this.isRunning = false;
      
      dbEvents.emit('monitoring_stopped');
      return this;
    },
    getStatus: function() {
      return {
        isRunning: this.isRunning,
        interval: interval,
        lastStatus: this.lastStatus,
        timestamp: new Date()
      };
    }
  };
  
  return monitor;
}

/**
 * 监听数据库事件
 * @param {string} event 事件名称
 * @param {Function} listener 监听器函数
 */
function onDatabaseEvent(event, listener) {
  dbEvents.on(event, listener);
}

module.exports = {
  checkConnectionStatus,
  getPoolStatus,
  identifySlowQueries,
  logDatabaseError,
  startMonitoring,
  onDatabaseEvent,
  dbEvents
};