/**
 * 操作日志模型
 * @file OperationLog.js
 * @description 记录系统用户的操作日志，包括新增、编辑、删除操作
 */
const { DataTypes } = require('sequelize');
const BaseModel = require('./BaseModel');

class OperationLog extends BaseModel {
  static init(sequelize) {
    return super.init({
      id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        comment: '主键ID'
      },
      user_id: {
        type: DataTypes.INTEGER,
        allowNull: false,
        comment: '操作用户ID'
      },
      username: {
        type: DataTypes.STRING(50),
        allowNull: false,
        comment: '操作用户名'
      },
      user_role: {
        type: DataTypes.STRING(50),
        allowNull: false,
        comment: '操作用户角色'
      },
      operation_type: {
        type: DataTypes.ENUM('CREATE', 'UPDATE', 'DELETE', 'READ', 'LOGIN', 'LOGOUT', 'EXPORT', 'IMPORT', 'BATCH_DELETE', 'BATCH_UPDATE'),
        allowNull: false,
        comment: '操作类型：CREATE-新增，UPDATE-编辑，DELETE-删除，READ-查看，LOGIN-登录，LOGOUT-登出，EXPORT-导出，IMPORT-导入，BATCH_DELETE-批量删除，BATCH_UPDATE-批量更新'
      },
      module_name: {
        type: DataTypes.STRING(100),
        allowNull: false,
        comment: '操作模块名称'
      },
      table_name: {
        type: DataTypes.STRING(100),
        allowNull: false,
        comment: '操作的数据表名'
      },
      record_id: {
        type: DataTypes.INTEGER,
        allowNull: true,
        comment: '操作的记录ID'
      },
      operation_desc: {
        type: DataTypes.TEXT,
        allowNull: false,
        comment: '操作描述'
      },
      old_data: {
        type: DataTypes.JSON,
        allowNull: true,
        comment: '操作前的数据（编辑和删除时记录）'
      },
      new_data: {
        type: DataTypes.JSON,
        allowNull: true,
        comment: '操作后的数据（新增和编辑时记录）'
      },
      ip_address: {
        type: DataTypes.STRING(45),
        allowNull: true,
        comment: '操作IP地址'
      },
      user_agent: {
        type: DataTypes.TEXT,
        allowNull: true,
        comment: '用户代理信息'
      },
      request_url: {
        type: DataTypes.STRING(500),
        allowNull: true,
        comment: '请求URL'
      },
      request_method: {
        type: DataTypes.STRING(10),
        allowNull: true,
        comment: '请求方法'
      },
      response_status: {
        type: DataTypes.INTEGER,
        allowNull: true,
        comment: '响应状态码'
      },
      execution_time: {
        type: DataTypes.INTEGER,
        allowNull: true,
        comment: '执行时间（毫秒）'
      },
      error_message: {
        type: DataTypes.TEXT,
        allowNull: true,
        comment: '错误信息（如果有）'
      },
      created_at: {
        type: DataTypes.DATE,
        allowNull: false,
        defaultValue: DataTypes.NOW,
        comment: '创建时间'
      }
    }, {
      sequelize,
      tableName: 'operation_logs',
      comment: '操作日志表',
      indexes: [
        {
          name: 'idx_user_id',
          fields: ['user_id']
        },
        {
          name: 'idx_operation_type',
          fields: ['operation_type']
        },
        {
          name: 'idx_module_name',
          fields: ['module_name']
        },
        {
          name: 'idx_table_name',
          fields: ['table_name']
        },
        {
          name: 'idx_created_at',
          fields: ['created_at']
        },
        {
          name: 'idx_user_operation',
          fields: ['user_id', 'operation_type']
        },
        {
          name: 'idx_module_operation',
          fields: ['module_name', 'operation_type']
        }
      ]
    });
  }

  /**
   * 记录操作日志
   * @param {Object} logData 日志数据
   * @returns {Promise<OperationLog>} 创建的日志记录
   */
  static async recordOperation(logData) {
    try {
      const {
        userId,
        username,
        userRole,
        operationType,
        moduleName,
        tableName,
        recordId,
        operationDesc,
        oldData,
        newData,
        ipAddress,
        userAgent,
        requestUrl,
        requestMethod,
        responseStatus,
        executionTime,
        errorMessage
      } = logData;

      return await this.create({
        user_id: userId,
        username: username,
        user_role: userRole,
        operation_type: operationType,
        module_name: moduleName,
        table_name: tableName,
        record_id: recordId,
        operation_desc: operationDesc,
        old_data: oldData,
        new_data: newData,
        ip_address: ipAddress,
        user_agent: userAgent,
        request_url: requestUrl,
        request_method: requestMethod,
        response_status: responseStatus,
        execution_time: executionTime,
        error_message: errorMessage
      });
    } catch (error) {
      console.error('记录操作日志失败:', error);
      throw error;
    }
  }

  /**
   * 获取用户操作统计
   * @param {number} userId 用户ID
   * @param {string} startDate 开始日期
   * @param {string} endDate 结束日期
   * @returns {Promise<Object>} 统计结果
   */
  static async getUserOperationStats(userId, startDate, endDate) {
    try {
      const whereClause = {
        user_id: userId
      };

      if (startDate && endDate) {
        whereClause.created_at = {
          [this.sequelize.Sequelize.Op.between]: [startDate, endDate]
        };
      }

      const stats = await this.findAll({
        where: whereClause,
        attributes: [
          'operation_type',
          [this.sequelize.fn('COUNT', this.sequelize.col('id')), 'count']
        ],
        group: ['operation_type'],
        raw: true
      });

      return stats.reduce((acc, stat) => {
        acc[stat.operation_type] = parseInt(stat.count);
        return acc;
      }, {});
    } catch (error) {
      console.error('获取用户操作统计失败:', error);
      throw error;
    }
  }

  /**
   * 获取模块操作统计
   * @param {string} moduleName 模块名称
   * @param {string} startDate 开始日期
   * @param {string} endDate 结束日期
   * @returns {Promise<Object>} 统计结果
   */
  static async getModuleOperationStats(moduleName, startDate, endDate) {
    try {
      const whereClause = {
        module_name: moduleName
      };

      if (startDate && endDate) {
        whereClause.created_at = {
          [this.sequelize.Sequelize.Op.between]: [startDate, endDate]
        };
      }

      const stats = await this.findAll({
        where: whereClause,
        attributes: [
          'operation_type',
          [this.sequelize.fn('COUNT', this.sequelize.col('id')), 'count']
        ],
        group: ['operation_type'],
        raw: true
      });

      return stats.reduce((acc, stat) => {
        acc[stat.operation_type] = parseInt(stat.count);
        return acc;
      }, {});
    } catch (error) {
      console.error('获取模块操作统计失败:', error);
      throw error;
    }
  }

  /**
   * 清理过期日志
   * @param {number} daysToKeep 保留天数
   * @returns {Promise<number>} 删除的记录数
   */
  static async cleanExpiredLogs(daysToKeep = 90) {
    try {
      const cutoffDate = new Date();
      cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);

      const deletedCount = await this.destroy({
        where: {
          created_at: {
            [this.sequelize.Sequelize.Op.lt]: cutoffDate
          }
        }
      });

      console.log(`清理了 ${deletedCount} 条过期操作日志`);
      return deletedCount;
    } catch (error) {
      console.error('清理过期日志失败:', error);
      throw error;
    }
  }
}

module.exports = OperationLog;
