const { User, Role, Permission, RolePermission } = require('../models');

/**
 * 权限服务类 - 提供动态权限检查和管理功能
 */
class PermissionService {
  /**
   * 检查用户是否具有指定权限
   * @param {number} userId - 用户ID
   * @param {string} permissionCode - 权限代码
   * @returns {Promise<boolean>} 是否具有权限
   */
  static async checkUserPermission(userId, permissionCode) {
    try {
      const user = await User.findByPk(userId, {
        include: [{
          model: Role,
          as: 'role',
          include: [{
            model: Permission,
            as: 'permissions',
            where: { code: permissionCode },
            required: false
          }]
        }]
      });

      if (!user || !user.role) {
        return false;
      }

      return user.role.permissions && user.role.permissions.length > 0;
    } catch (error) {
      console.error('检查用户权限失败:', error);
      return false;
    }
  }

  /**
   * 检查用户是否具有多个权限中的任意一个
   * @param {number} userId - 用户ID
   * @param {string[]} permissionCodes - 权限代码数组
   * @returns {Promise<boolean>} 是否具有任意一个权限
   */
  static async checkUserAnyPermission(userId, permissionCodes) {
    try {
      const user = await User.findByPk(userId, {
        include: [{
          model: Role,
          as: 'role',
          include: [{
            model: Permission,
            as: 'permissions',
            where: { code: permissionCodes },
            required: false
          }]
        }]
      });

      if (!user || !user.role) {
        return false;
      }

      return user.role.permissions && user.role.permissions.length > 0;
    } catch (error) {
      console.error('检查用户权限失败:', error);
      return false;
    }
  }

  /**
   * 检查用户是否具有所有指定权限
   * @param {number} userId - 用户ID
   * @param {string[]} permissionCodes - 权限代码数组
   * @returns {Promise<boolean>} 是否具有所有权限
   */
  static async checkUserAllPermissions(userId, permissionCodes) {
    try {
      const user = await User.findByPk(userId, {
        include: [{
          model: Role,
          as: 'role',
          include: [{
            model: Permission,
            as: 'permissions',
            where: { code: permissionCodes },
            required: false
          }]
        }]
      });

      if (!user || !user.role) {
        return false;
      }

      const userPermissions = user.role.permissions || [];
      return permissionCodes.every(code => 
        userPermissions.some(permission => permission.code === code)
      );
    } catch (error) {
      console.error('检查用户权限失败:', error);
      return false;
    }
  }

  /**
   * 获取用户的所有权限
   * @param {number} userId - 用户ID
   * @returns {Promise<string[]>} 用户权限代码数组
   */
  static async getUserPermissions(userId) {
    try {
      const user = await User.findByPk(userId, {
        include: [{
          model: Role,
          as: 'role',
          include: [{
            model: Permission,
            as: 'permissions'
          }]
        }]
      });

      if (!user || !user.role || !user.role.permissions) {
        return [];
      }

      return user.role.permissions.map(permission => permission.code);
    } catch (error) {
      console.error('获取用户权限失败:', error);
      return [];
    }
  }

  /**
   * 获取角色的所有权限
   * @param {number} roleId - 角色ID
   * @returns {Promise<Permission[]>} 权限对象数组
   */
  static async getRolePermissions(roleId) {
    try {
      const role = await Role.findByPk(roleId, {
        include: [{
          model: Permission,
          as: 'permissions'
        }]
      });

      return role ? role.permissions || [] : [];
    } catch (error) {
      console.error('获取角色权限失败:', error);
      return [];
    }
  }

  /**
   * 检查权限是否存在
   * @param {string} permissionCode - 权限代码
   * @returns {Promise<boolean>} 权限是否存在
   */
  static async permissionExists(permissionCode) {
    try {
      const permission = await Permission.findOne({
        where: { code: permissionCode }
      });
      return !!permission;
    } catch (error) {
      console.error('检查权限存在性失败:', error);
      return false;
    }
  }

  /**
   * 获取权限树结构
   * @returns {Promise<Object[]>} 权限树
   */
  static async getPermissionTree() {
    try {
      const permissions = await Permission.findAll({
        order: [['module', 'ASC'], ['type', 'ASC'], ['code', 'ASC']]
      });

      // 按模块分组
      const modules = {};
      permissions.forEach(permission => {
        if (!modules[permission.module]) {
          modules[permission.module] = {
            module: permission.module,
            permissions: []
          };
        }
        modules[permission.module].permissions.push(permission);
      });

      return Object.values(modules);
    } catch (error) {
      console.error('获取权限树失败:', error);
      return [];
    }
  }

  /**
   * 批量检查用户权限
   * @param {number} userId - 用户ID
   * @param {string[]} permissionCodes - 权限代码数组
   * @returns {Promise<Object>} 权限检查结果对象
   */
  static async batchCheckUserPermissions(userId, permissionCodes) {
    try {
      const userPermissions = await this.getUserPermissions(userId);
      const result = {};

      permissionCodes.forEach(code => {
        result[code] = userPermissions.includes(code);
      });

      return result;
    } catch (error) {
      console.error('批量检查用户权限失败:', error);
      return {};
    }
  }

  /**
   * 获取用户可访问的菜单
   * @param {number} userId - 用户ID
   * @returns {Promise<Object[]>} 可访问的菜单数组
   */
  static async getUserAccessibleMenus(userId) {
    try {
      const userPermissions = await this.getUserPermissions(userId);
      
      // 这里可以根据权限过滤菜单
      // 示例：假设菜单与权限有对应关系
      const allMenus = [
        { id: 1, name: '用户管理', permission: 'user:view', path: '/users' },
        { id: 2, name: '角色管理', permission: 'role:view', path: '/roles' },
        { id: 3, name: '权限管理', permission: 'permission:view', path: '/permissions' },
        { id: 4, name: '保单管理', permission: 'policy:view', path: '/policies' },
        { id: 5, name: '理赔管理', permission: 'claim:view', path: '/claims' },
        { id: 6, name: '系统设置', permission: 'system:view', path: '/system' }
      ];

      return allMenus.filter(menu => 
        userPermissions.includes(menu.permission)
      );
    } catch (error) {
      console.error('获取用户可访问菜单失败:', error);
      return [];
    }
  }
}

module.exports = PermissionService;