const { OperationLog } = require('../models');

/**
 * 操作日志记录中间件
 * 自动记录用户的操作行为
 */
class OperationLogger {
  /**
   * 记录操作日志的中间件
   */
  static logOperation(options = {}) {
    return async (req, res, next) => {
      const startTime = Date.now();
      
      // 保存原始的res.json方法
      const originalJson = res.json;
      
      // 重写res.json方法以捕获响应数据
      res.json = function(data) {
        const endTime = Date.now();
        const executionTime = endTime - startTime;
        
        // 异步记录操作日志，不阻塞响应
        setImmediate(async () => {
          try {
            await OperationLogger.recordLog(req, res, data, executionTime, options);
          } catch (error) {
            console.error('记录操作日志失败:', error);
          }
        });
        
        // 调用原始的json方法
        return originalJson.call(this, data);
      };
      
      next();
    };
  }

  /**
   * 记录操作日志
   */
  static async recordLog(req, res, responseData, executionTime, options) {
    try {
      // 如果用户未登录，不记录日志
      if (!req.user || !req.user.id) {
        return;
      }

      // 获取操作类型
      const operationType = OperationLogger.getOperationType(req.method, req.url, options);
      
      // 获取操作模块
      const operationModule = OperationLogger.getOperationModule(req.url, options);
      
      // 获取操作内容
      const operationContent = OperationLogger.getOperationContent(req, operationType, operationModule, options);
      
      // 获取操作目标
      const operationTarget = OperationLogger.getOperationTarget(req, responseData, options);
      
      // 获取操作状态
      const status = OperationLogger.getOperationStatus(res.statusCode, responseData);
      
      // 获取错误信息
      const errorMessage = OperationLogger.getErrorMessage(responseData, status);

      // 记录操作日志
      await OperationLog.logOperation({
        user_id: req.user.id,
        operation_type: operationType,
        operation_module: operationModule,
        operation_content: operationContent,
        operation_target: operationTarget,
        request_method: req.method,
        request_url: req.originalUrl || req.url,
        request_params: {
          query: req.query,
          body: OperationLogger.sanitizeRequestBody(req.body),
          params: req.params
        },
        response_status: res.statusCode,
        response_data: OperationLogger.sanitizeResponseData(responseData),
        ip_address: OperationLogger.getClientIP(req),
        user_agent: req.get('User-Agent') || '',
        execution_time: executionTime,
        status: status,
        error_message: errorMessage
      });
    } catch (error) {
      console.error('记录操作日志时发生错误:', error);
    }
  }

  /**
   * 获取操作类型
   */
  static getOperationType(method, url, options) {
    if (options.operation_type) {
      return options.operation_type;
    }

    // 根据URL和HTTP方法推断操作类型
    if (url.includes('/login')) return 'login';
    if (url.includes('/logout')) return 'logout';
    if (url.includes('/export')) return 'export';
    if (url.includes('/import')) return 'import';
    if (url.includes('/approve')) return 'approve';
    if (url.includes('/reject')) return 'reject';
    
    switch (method.toUpperCase()) {
      case 'GET':
        return 'view';
      case 'POST':
        return 'create';
      case 'PUT':
      case 'PATCH':
        return 'update';
      case 'DELETE':
        return 'delete';
      default:
        return 'other';
    }
  }

  /**
   * 获取操作模块
   */
  static getOperationModule(url, options) {
    if (options.operation_module) {
      return options.operation_module;
    }

    // 从URL中提取模块名
    const pathSegments = url.split('/').filter(segment => segment && segment !== 'api');
    if (pathSegments.length > 0) {
      return pathSegments[0].replace(/-/g, '_');
    }
    
    return 'unknown';
  }

  /**
   * 获取操作内容
   */
  static getOperationContent(req, operationType, operationModule, options) {
    if (options.operation_content) {
      return options.operation_content;
    }

    const actionMap = {
      'login': '用户登录',
      'logout': '用户退出',
      'view': '查看',
      'create': '创建',
      'update': '更新',
      'delete': '删除',
      'export': '导出',
      'import': '导入',
      'approve': '审批通过',
      'reject': '审批拒绝'
    };

    const moduleMap = {
      'users': '用户',
      'roles': '角色',
      'insurance': '保险',
      'policies': '保单',
      'claims': '理赔',
      'system': '系统',
      'operation_logs': '操作日志',
      'devices': '设备',
      'device_alerts': '设备告警'
    };

    const action = actionMap[operationType] || operationType;
    const module = moduleMap[operationModule] || operationModule;

    return `${action}${module}`;
  }

  /**
   * 获取操作目标
   */
  static getOperationTarget(req, responseData, options) {
    if (options.operation_target) {
      return options.operation_target;
    }

    // 尝试从请求参数中获取ID
    if (req.params.id) {
      return `ID: ${req.params.id}`;
    }

    // 尝试从响应数据中获取信息
    if (responseData && responseData.data) {
      if (responseData.data.id) {
        return `ID: ${responseData.data.id}`;
      }
      if (responseData.data.name) {
        return `名称: ${responseData.data.name}`;
      }
      if (responseData.data.username) {
        return `用户: ${responseData.data.username}`;
      }
    }

    return '';
  }

  /**
   * 获取操作状态
   */
  static getOperationStatus(statusCode, responseData) {
    if (statusCode >= 200 && statusCode < 300) {
      return 'success';
    } else if (statusCode >= 400 && statusCode < 500) {
      return 'failed';
    } else {
      return 'error';
    }
  }

  /**
   * 获取错误信息
   */
  static getErrorMessage(responseData, status) {
    if (status === 'success') {
      return null;
    }

    if (responseData && responseData.message) {
      return responseData.message;
    }

    if (responseData && responseData.error) {
      return responseData.error;
    }

    return null;
  }

  /**
   * 清理请求体数据（移除敏感信息）
   */
  static sanitizeRequestBody(body) {
    if (!body || typeof body !== 'object') {
      return body;
    }

    const sanitized = { ...body };
    const sensitiveFields = ['password', 'token', 'secret', 'key', 'auth'];
    
    sensitiveFields.forEach(field => {
      if (sanitized[field]) {
        sanitized[field] = '***';
      }
    });

    return sanitized;
  }

  /**
   * 清理响应数据（移除敏感信息）
   */
  static sanitizeResponseData(data) {
    if (!data || typeof data !== 'object') {
      return data;
    }

    // 只保留基本的响应信息，不保存完整的响应数据
    return {
      status: data.status,
      message: data.message,
      code: data.code
    };
  }

  /**
   * 获取客户端IP地址
   */
  static getClientIP(req) {
    return req.ip || 
           req.connection.remoteAddress || 
           req.socket.remoteAddress ||
           (req.connection.socket ? req.connection.socket.remoteAddress : null) ||
           '127.0.0.1';
  }

  /**
   * 创建特定操作的日志记录器
   */
  static createLogger(operationType, operationModule, operationContent) {
    return OperationLogger.logOperation({
      operation_type: operationType,
      operation_module: operationModule,
      operation_content: operationContent
    });
  }
}

module.exports = OperationLogger;