/**
 * 权限验证中间件
 * @file permission.js
 * @description 基于权限的访问控制中间件
 */
const { User, Role, Permission } = require('../models');
const { hasPermission } = require('../config/permissions');

/**
 * 权限验证中间件
 * @param {string|Array} requiredPermissions 需要的权限
 * @returns {Function} 中间件函数
 */
const requirePermission = (requiredPermissions) => {
  return async (req, res, next) => {
    try {
      // 检查用户是否已认证
      if (!req.user || !req.user.id) {
        return res.status(401).json({
          success: false,
          message: '未授权访问'
        });
      }

      // 获取用户信息（包含角色和权限）
      const user = await User.findByPk(req.user.id, {
        include: [{
          model: Role,
          as: 'role',
          attributes: ['id', 'name'],
          include: [{
            model: Permission,
            as: 'permissions',
            through: { attributes: [] },
            attributes: ['permission_key']
          }]
        }]
      });

      if (!user) {
        return res.status(404).json({
          success: false,
          message: '用户不存在'
        });
      }

      // 检查用户状态
      if (user.status !== 'active') {
        return res.status(403).json({
          success: false,
          message: '账户已被禁用'
        });
      }

      // 获取用户权限（从数据库）
      const userPermissions = user.role && user.role.permissions 
        ? user.role.permissions.map(p => p.permission_key)
        : [];

      // 检查权限
      const hasRequiredPermission = hasPermission(userPermissions, requiredPermissions);

      if (!hasRequiredPermission) {
        return res.status(403).json({
          success: false,
          message: '权限不足',
          requiredPermissions: Array.isArray(requiredPermissions) ? requiredPermissions : [requiredPermissions],
          userPermissions: userPermissions
        });
      }

      // 将用户信息添加到请求对象
      req.currentUser = {
        id: user.id,
        username: user.username,
        email: user.email,
        role: user.role,
        permissions: userPermissions
      };

      next();
    } catch (error) {
      console.error('权限验证错误:', error);
      res.status(500).json({
        success: false,
        message: '权限验证失败'
      });
    }
  };
};

/**
 * 角色验证中间件
 * @param {string|Array} requiredRoles 需要的角色
 * @returns {Function} 中间件函数
 */
const requireRole = (requiredRoles) => {
  return async (req, res, next) => {
    try {
      // 检查用户是否已认证
      if (!req.user || !req.user.id) {
        return res.status(401).json({
          success: false,
          message: '未授权访问'
        });
      }

      // 获取用户信息（包含角色）
      const user = await User.findByPk(req.user.id, {
        include: [{
          model: Role,
          as: 'role',
          attributes: ['id', 'name']
        }]
      });

      if (!user || !user.role) {
        return res.status(403).json({
          success: false,
          message: '用户角色不存在'
        });
      }

      // 检查角色
      const roles = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
      const hasRequiredRole = roles.includes(user.role.name);

      if (!hasRequiredRole) {
        return res.status(403).json({
          success: false,
          message: '角色权限不足',
          requiredRoles: roles,
          userRole: user.role.name
        });
      }

      // 将用户信息添加到请求对象
      req.currentUser = {
        id: user.id,
        username: user.username,
        email: user.email,
        role: user.role,
        permissions: getRolePermissions(user.role.name)
      };

      next();
    } catch (error) {
      console.error('角色验证错误:', error);
      res.status(500).json({
        success: false,
        message: '角色验证失败'
      });
    }
  };
};

/**
 * 管理员权限中间件
 * @returns {Function} 中间件函数
 */
const requireAdmin = () => {
  return requireRole('admin');
};

/**
 * 养殖场管理员权限中间件
 * @returns {Function} 中间件函数
 */
const requireFarmManager = () => {
  return requireRole(['admin', 'farm_manager']);
};

/**
 * 监管人员权限中间件
 * @returns {Function} 中间件函数
 */
const requireInspector = () => {
  return requireRole(['admin', 'farm_manager', 'inspector']);
};

/**
 * 获取用户权限信息中间件
 * @returns {Function} 中间件函数
 */
const getUserPermissions = async (req, res, next) => {
  try {
    if (!req.user || !req.user.id) {
      return next();
    }

    // 获取用户信息（包含角色）
    const user = await User.findByPk(req.user.id, {
      include: [{
        model: Role,
        as: 'role',
        attributes: ['id', 'name']
      }]
    });

    if (user && user.role) {
      req.currentUser = {
        id: user.id,
        username: user.username,
        email: user.email,
        role: user.role,
        permissions: getRolePermissions(user.role.name)
      };
    }

    next();
  } catch (error) {
    console.error('获取用户权限信息错误:', error);
    next();
  }
};

module.exports = {
  requirePermission,
  requireRole,
  requireAdmin,
  requireFarmManager,
  requireInspector,
  getUserPermissions,
};
