/**
 * 自动操作日志中间件
 * @file autoOperationLogger.js
 * @description 自动记录所有API操作日志的中间件
 */
const { OperationLog } = require('../models');

/**
 * 自动操作日志中间件
 * 自动记录所有经过认证的API操作
 */
const autoOperationLogger = async (req, res, next) => {
  const startTime = Date.now();
  const originalSend = res.send;
  let responseBody = null;

  // 拦截响应数据
  res.send = function(data) {
    responseBody = data;
    return originalSend.call(this, data);
  };

  // 在响应完成后记录日志
  res.on('finish', async () => {
    try {
      // 只记录经过认证的操作
      if (!req.user) {
        console.log(`[操作日志] 跳过记录 - 无用户信息: ${req.method} ${req.originalUrl}`);
        return;
      }

      const executionTime = Date.now() - startTime;
      const operationType = getOperationType(req.method, req.originalUrl);
      
      if (!operationType) {
        console.log(`[操作日志] 跳过记录 - 不支持的操作类型: ${req.method} ${req.originalUrl}`);
        return; // 不记录的操作类型
      }

      console.log(`[操作日志] 开始记录: ${req.user.username} ${operationType} ${req.method} ${req.originalUrl}`);

      // 获取模块名称
      const moduleName = getModuleName(req.originalUrl);
      
      // 获取表名
      const tableName = getTableName(req.originalUrl);
      
      // 获取记录ID
      const recordId = getRecordId(req);
      
      // 生成操作描述
      const operationDesc = generateOperationDesc(req, responseBody);
      
      // 获取操作前后数据
      const { oldData, newData } = await getOperationData(req, res, operationType);

      // 获取IP地址
      const ipAddress = getClientIP(req);

      // 记录操作日志
      await OperationLog.recordOperation({
        userId: req.user.id,
        username: req.user.username,
        userRole: req.user.role || 'unknown',
        operationType,
        moduleName,
        tableName,
        recordId,
        operationDesc,
        oldData,
        newData,
        ipAddress,
        userAgent: req.get('User-Agent'),
        requestUrl: req.originalUrl,
        requestMethod: req.method,
        responseStatus: res.statusCode,
        executionTime,
        errorMessage: res.statusCode >= 400 ? (responseBody?.message || '操作失败') : null
      });

      console.log(`[操作日志] ${req.user.username} ${operationType} ${moduleName} - ${operationDesc}`);
    } catch (error) {
      console.error('记录操作日志失败:', error);
      // 不抛出错误，避免影响主业务
    }
  });

  next();
};

/**
 * 根据HTTP方法和URL获取操作类型
 */
const getOperationType = (method, url) => {
  const methodUpper = method.toUpperCase();
  
  // 特殊URL处理
  if (url.includes('/auth/login')) {
    return 'LOGIN';
  }
  if (url.includes('/auth/logout')) {
    return 'LOGOUT';
  }
  if (url.includes('/export')) {
    return 'EXPORT';
  }
  if (url.includes('/import')) {
    return 'IMPORT';
  }
  if (url.includes('/batch-delete')) {
    return 'BATCH_DELETE';
  }
  if (url.includes('/batch-update')) {
    return 'BATCH_UPDATE';
  }
  
  // 标准HTTP方法映射
  switch (methodUpper) {
    case 'POST':
      return 'CREATE';
    case 'PUT':
    case 'PATCH':
      return 'UPDATE';
    case 'DELETE':
      return 'DELETE';
    case 'GET':
      // GET请求记录所有操作
      return 'READ';
    default:
      return null;
  }
};

/**
 * 根据URL获取模块名称
 */
const getModuleName = (url) => {
  const pathSegments = url.split('/').filter(segment => segment);
  
  if (pathSegments.length < 2) {
    return '未知模块';
  }
  
  const moduleMap = {
    'users': '用户管理',
    'farms': '农场管理',
    'animals': '动物管理',
    'devices': '设备管理',
    'alerts': '告警管理',
    'products': '产品管理',
    'orders': '订单管理',
    'auth': '认证管理',
    'stats': '统计分析',
    'map': '地图服务',
    'operation-logs': '操作日志',
    'roles': '角色管理',
    'permissions': '权限管理',
    'menus': '菜单管理',
    'cattle-batches': '牛只批次管理',
    'cattle-pens': '牛舍管理',
    'cattle-transfer-records': '牛只转移记录',
    'cattle-exit-records': '牛只出栏记录',
    'electronic-fences': '电子围栏',
    'electronic-fence-points': '围栏点位',
    'pens': '圈舍管理'
  };
  
  const moduleKey = pathSegments[1];
  return moduleMap[moduleKey] || moduleKey || '未知模块';
};

/**
 * 根据URL获取表名
 */
const getTableName = (url) => {
  const pathSegments = url.split('/').filter(segment => segment);
  
  if (pathSegments.length < 2) {
    return 'unknown';
  }
  
  const tableMap = {
    'users': 'users',
    'farms': 'farms',
    'animals': 'animals',
    'devices': 'devices',
    'alerts': 'alerts',
    'products': 'products',
    'orders': 'orders',
    'cattle-batches': 'cattle_batches',
    'cattle-pens': 'cattle_pens',
    'cattle-transfer-records': 'cattle_transfer_records',
    'cattle-exit-records': 'cattle_exit_records',
    'electronic-fences': 'electronic_fences',
    'electronic-fence-points': 'electronic_fence_points',
    'pens': 'pens',
    'roles': 'roles',
    'permissions': 'permissions',
    'menus': 'menu_permissions'
  };
  
  const tableKey = pathSegments[1];
  return tableMap[tableKey] || tableKey || 'unknown';
};

/**
 * 获取记录ID
 */
const getRecordId = (req) => {
  // 从URL参数中获取ID
  const id = req.params.id || req.params.farmId || req.params.animalId || 
             req.params.deviceId || req.params.alertId || req.params.productId || 
             req.params.orderId || req.params.batchId || req.params.penId;
  
  return id ? parseInt(id) : null;
};

/**
 * 生成操作描述
 */
const generateOperationDesc = (req, responseBody) => {
  const method = req.method.toUpperCase();
  const url = req.originalUrl;
  const moduleName = getModuleName(url);
  
  // 根据操作类型生成描述
  switch (method) {
    case 'POST':
      if (url.includes('/auth/login')) {
        return '用户登录';
      }
      if (url.includes('/auth/logout')) {
        return '用户登出';
      }
      if (url.includes('/export')) {
        return `导出${moduleName}数据`;
      }
      if (url.includes('/import')) {
        return `导入${moduleName}数据`;
      }
      if (url.includes('/batch-delete')) {
        return `批量删除${moduleName}数据`;
      }
      if (url.includes('/batch-update')) {
        return `批量更新${moduleName}数据`;
      }
      return `新增${moduleName}记录`;
      
    case 'PUT':
    case 'PATCH':
      return `更新${moduleName}记录`;
      
    case 'DELETE':
      if (url.includes('/batch-delete')) {
        return `批量删除${moduleName}数据`;
      }
      return `删除${moduleName}记录`;
      
    case 'GET':
      if (url.includes('/stats') || url.includes('/analytics')) {
        return `查看${moduleName}统计`;
      }
      if (url.includes('/reports')) {
        return `查看${moduleName}报表`;
      }
      // 如果是获取单个记录详情，可能是用于编辑
      if (url.match(/\/\d+$/)) {
        return `获取${moduleName}详情`;
      }
      return `查看${moduleName}数据`;
      
    default:
      return `${method}操作${moduleName}`;
  }
};

/**
 * 获取操作前后数据
 */
const getOperationData = async (req, res, operationType) => {
  let oldData = null;
  let newData = null;
  
  try {
    // 对于更新和删除操作，尝试获取操作前的数据
    if (operationType === 'UPDATE' || operationType === 'DELETE') {
      // 这里可以根据需要实现获取旧数据的逻辑
      // 由于需要查询数据库，暂时返回null
      oldData = null;
    }
    
    // 对于新增和更新操作，获取操作后的数据
    if (operationType === 'CREATE' || operationType === 'UPDATE') {
      // 从响应体中获取新数据
      if (res.responseBody && res.responseBody.data) {
        newData = res.responseBody.data;
      }
    }
  } catch (error) {
    console.error('获取操作数据失败:', error);
  }
  
  return { oldData, newData };
};

/**
 * 获取客户端IP地址
 */
const getClientIP = (req) => {
  return req.ip || 
    req.connection.remoteAddress || 
    req.socket.remoteAddress ||
    (req.connection.socket ? req.connection.socket.remoteAddress : null) ||
    req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
    'unknown';
};

module.exports = {
  autoOperationLogger
};
