const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');

const OperationLog = sequelize.define('OperationLog', {
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    primaryKey: true
  },
  user_id: {
    type: DataTypes.INTEGER,
    allowNull: false,
    references: {
      model: 'users',
      key: 'id'
    },
    comment: '操作用户ID'
  },
  operation_type: {
    type: DataTypes.ENUM(
      'login',           // 登录
      'logout',          // 登出
      'create',          // 创建
      'update',          // 更新
      'delete',          // 删除
      'view',            // 查看
      'export',          // 导出
      'import',          // 导入
      'approve',         // 审批
      'reject',          // 拒绝
      'system_config',   // 系统配置
      'user_manage',     // 用户管理
      'role_manage',     // 角色管理
      'other'            // 其他
    ),
    allowNull: false,
    comment: '操作类型'
  },
  operation_module: {
    type: DataTypes.STRING(50),
    allowNull: false,
    comment: '操作模块（如：用户管理、设备管理、预警管理等）'
  },
  operation_content: {
    type: DataTypes.TEXT,
    allowNull: false,
    comment: '操作内容描述'
  },
  operation_target: {
    type: DataTypes.STRING(100),
    allowNull: true,
    comment: '操作目标（如：用户ID、设备ID等）'
  },
  request_method: {
    type: DataTypes.ENUM('GET', 'POST', 'PUT', 'DELETE', 'PATCH'),
    allowNull: true,
    comment: 'HTTP请求方法'
  },
  request_url: {
    type: DataTypes.STRING(500),
    allowNull: true,
    comment: '请求URL'
  },
  request_params: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '请求参数（JSON格式）',
    get() {
      const value = this.getDataValue('request_params');
      return value ? JSON.parse(value) : null;
    },
    set(value) {
      this.setDataValue('request_params', value ? JSON.stringify(value) : null);
    }
  },
  response_status: {
    type: DataTypes.INTEGER,
    allowNull: true,
    comment: '响应状态码'
  },
  ip_address: {
    type: DataTypes.STRING(45),
    allowNull: true,
    comment: 'IP地址（支持IPv6）'
  },
  user_agent: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '用户代理信息'
  },
  execution_time: {
    type: DataTypes.INTEGER,
    allowNull: true,
    comment: '执行时间（毫秒）'
  },
  status: {
    type: DataTypes.ENUM('success', 'failed', 'error'),
    defaultValue: 'success',
    comment: '操作状态'
  },
  error_message: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '错误信息'
  }
}, {
  tableName: 'operation_logs',
  timestamps: true,
  underscored: true,
  indexes: [
    { fields: ['user_id'] },
    { fields: ['operation_type'] },
    { fields: ['operation_module'] },
    { fields: ['created_at'] },
    { fields: ['status'] },
    { fields: ['ip_address'] }
  ]
});

// 定义关联关系
OperationLog.associate = function(models) {
  // 操作日志属于用户
  OperationLog.belongsTo(models.User, {
    foreignKey: 'user_id',
    as: 'user',
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE'
  });
};

// 静态方法：记录操作日志
OperationLog.logOperation = async function(logData) {
  try {
    const log = await this.create({
      user_id: logData.userId,
      operation_type: logData.operationType,
      operation_module: logData.operationModule,
      operation_content: logData.operationContent,
      operation_target: logData.operationTarget,
      request_method: logData.requestMethod,
      request_url: logData.requestUrl,
      request_params: logData.requestParams,
      response_status: logData.responseStatus,
      ip_address: logData.ipAddress,
      user_agent: logData.userAgent,
      execution_time: logData.executionTime,
      status: logData.status || 'success',
      error_message: logData.errorMessage
    });
    return log;
  } catch (error) {
    console.error('记录操作日志失败:', error);
    throw error;
  }
};

// 静态方法：获取操作日志列表
OperationLog.getLogsList = async function(options = {}) {
  const {
    page = 1,
    limit = 20,
    userId,
    operationType,
    operationModule,
    status,
    startDate,
    endDate,
    keyword
  } = options;

  const where = {};
  
  // 构建查询条件
  if (userId) where.user_id = userId;
  if (operationType) where.operation_type = operationType;
  if (operationModule) where.operation_module = operationModule;
  if (status) where.status = status;
  
  // 时间范围查询
  if (startDate || endDate) {
    where.created_at = {};
    if (startDate) where.created_at[sequelize.Op.gte] = new Date(startDate);
    if (endDate) where.created_at[sequelize.Op.lte] = new Date(endDate);
  }
  
  // 关键词搜索
  if (keyword) {
    where[sequelize.Op.or] = [
      { operation_content: { [sequelize.Op.like]: `%${keyword}%` } },
      { operation_target: { [sequelize.Op.like]: `%${keyword}%` } }
    ];
  }

  const offset = (page - 1) * limit;

  const result = await this.findAndCountAll({
    where,
    include: [{
      model: sequelize.models.User,
      as: 'user',
      attributes: ['id', 'username', 'real_name']
    }],
    order: [['created_at', 'DESC']],
    limit: parseInt(limit),
    offset: parseInt(offset)
  });

  return {
    logs: result.rows,
    total: result.count,
    page: parseInt(page),
    limit: parseInt(limit),
    totalPages: Math.ceil(result.count / limit)
  };
};

// 静态方法：获取操作统计
OperationLog.getOperationStats = async function(options = {}) {
  const { startDate, endDate, userId } = options;
  
  const where = {};
  if (userId) where.user_id = userId;
  
  if (startDate || endDate) {
    where.created_at = {};
    if (startDate) where.created_at[sequelize.Op.gte] = new Date(startDate);
    if (endDate) where.created_at[sequelize.Op.lte] = new Date(endDate);
  }

  // 按操作类型统计
  const typeStats = await this.findAll({
    where,
    attributes: [
      'operation_type',
      [sequelize.fn('COUNT', sequelize.col('id')), 'count']
    ],
    group: ['operation_type'],
    raw: true
  });

  // 按操作模块统计
  const moduleStats = await this.findAll({
    where,
    attributes: [
      'operation_module',
      [sequelize.fn('COUNT', sequelize.col('id')), 'count']
    ],
    group: ['operation_module'],
    raw: true
  });

  // 按状态统计
  const statusStats = await this.findAll({
    where,
    attributes: [
      'status',
      [sequelize.fn('COUNT', sequelize.col('id')), 'count']
    ],
    group: ['status'],
    raw: true
  });

  return {
    typeStats,
    moduleStats,
    statusStats
  };
};

module.exports = OperationLog;

