package jnpf.authority.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.authority.mapper.*;
import jnpf.authority.service.FtbPermissionRoleService;
import jnpf.base.ActionResult;
import jnpf.base.ModuleApi;
import jnpf.base.SystemApi;
import jnpf.base.entity.ModuleEntity;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.base.entity.SystemEntity;
import jnpf.base.vo.PageListVO;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.authority.po.*;
import jnpf.model.authority.vo.person.FtbEmployeePermissionPersonnelVO;
import jnpf.model.authority.vo.person.FtbUserPermissionVO;
import jnpf.model.authority.vo.role.FtbPermissionRoleIdentificationVO;
import jnpf.permission.V2OrganizeApi;
import jnpf.permission.V2PositionApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.dto.v2.user.QueryPageUserDTO;
import jnpf.permission.dto.v2.user.QueryUserBatchDTO;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.permission.vo.v2.user.UserPageListVO;
import jnpf.util.RedisUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

;

/**
 * 权限内部调用
 *
 * @author wangchunxiang
 * @date 2025/04/10
 */
@Component
@Slf4j
public class PermissionsUtils {

    @Resource
    private V2UserApi v2UserApi;
    @Resource
    private V2PositionApi v2PositionApi;
    @Resource
    private V2OrganizeApi v2OrganizeApi;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private SystemApi systemApi;

    @Resource
    private ModuleApi moduleApi;
    @Resource
    private FtbPermissionRoleAuthorizePersonMapper ftbPermissionRoleAuthorizePersonMapper;
    @Resource
    private FtbPermissionRoleAuthorizePostMapper ftbPermissionRoleAuthorizePostMapper;
    @Resource
    private FtbPermissionRoleMapper permissionRoleMapper;
    @Resource
    private FtbPermissionFunctionMenuMapper ftbPermissionFunctionMenuMapper;
    @Resource
    private FtbPermissionRoleMenuRelationMapper ftbPermissionRoleMenuRelationMapper;
    @Resource
    private FtbPermissionRoleMenuMapper ftbPermissionRoleMenuMapper;
    @Resource
    private FtbPermissionRoleService ftbPermissionRoleService;
    // 用户权限缓存key
    // 前缀，用于区分不同的缓存数据
    private static final String PREFIX = "user:permission:";

    private static final Map<String, String> cache = new ConcurrentHashMap<>();

    /**
     * 根据用户ID生成Redis键
     *
     * @param userId 用户ID
     * @return Redis键
     */
    public static String getUserPermissionKey(String userId) {
        return PREFIX + "user:" + userId;
    }

    /**
     * 获取当前登录用户所具有的数据权限用户Id，（超级管理员调动方自行判断）
     *
     * @param userId           用户ID
     * @param permissionModule 权限模块汉字
     * @param category         类别，传WEB或者APP
     * @return {@link List }<{@link String }>
     */
    public List<String> obtainPersonnelUserIdDataPermissions(String userId, String permissionModule, String category) {
        String hashValue = obtainTheScopeOfUserPermissions(userId, permissionModule, category);
        return processScope(hashValue, userId, null);
    }

    /**
     * 获取指定用户所具有的数据权限用户Id，（超级管理员调动方自行判断）
     *
     * @param userId   用户ID
     * @param moduleId 权限模块id
     * @return {@link List }<{@link String }>
     */
    public List<String> obtainPersonnelUserIdDataPermissions(String userId, String moduleId) {
        Map<String, String> queryUserScopeOfPermissions = ftbPermissionRoleService.queryUserScopeOfPermission(userId);
        String hashValue = queryUserScopeOfPermissions.get(moduleId);
        // 无此模块权限，人员返回空数组
        if (StrUtil.isBlank(hashValue)) {
            return new ArrayList<>();
        }
        return processScope(hashValue, userId, null);
    }

    /**
     * 获取用户权限适用范围
     *
     * @param userId           用户 ID
     * @param moduleId 权限模块id
     * @return {@link PermissionsApplicableEnums } 返回#分割的数组，如果是指定组织，则#后面跟着组织id，权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
     */
    public PermissionsApplicableObject obtainTheScopeOfUserPermissionsEnums(String userId, String moduleId, String tenantId) {
        Map<String, String> queryUserScopeOfPermissions = ftbPermissionRoleService.queryUserScopeOfPermission(userId,tenantId);
        String hashValue = queryUserScopeOfPermissions.get(moduleId);
        return getPermissionsApplicableObject(hashValue);
    }
    /**
     * 获取用户权限适用范围
     *
     * @param userId           用户 ID
     * @param moduleId 权限模块id
     * @return {@link PermissionsApplicableEnums } 返回#分割的数组，如果是指定组织，则#后面跟着组织id，权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
     */
    public Map<String, PermissionsApplicableObject> obtainTheScopeOfUserPermissionsEnums(List<String> userIds, String moduleId, String tenantId) {
        Map<String, Map<String, String>> userScopeOfPermission = ftbPermissionRoleService.queryUserScopeOfPermission(userIds, tenantId);
        log.info("userScopeOfPermission:{},moduleId:{},tenantId:{}", userScopeOfPermission,moduleId,tenantId);
        Map<String, PermissionsApplicableObject> hashMap = new HashMap<>();
        userIds.forEach(userId -> {
            if (userScopeOfPermission.containsKey(userId)) {
                String hashValue = userScopeOfPermission.get(userId).get(moduleId);
                hashMap.put(userId,getPermissionsApplicableObject( hashValue)) ;
            }
        });
        return hashMap;
    }

    /**
     * 获取用户权限适用范围
     *
     * @param userId 用户 ID
     * @return {@link PermissionsApplicableEnums } 返回#分割的数组，如果是指定组织，则#后面跟着组织id，权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
     */
    public PermissionsApplicableObject obtainTheScopeOfUserPermissionsEnums(String userId) {
        String requestModule = getRequestModule();
        String hashValue = getValidatedHashValue(userId, requestModule);
        return getPermissionsApplicableObject(hashValue);
    }

    private PermissionsApplicableObject getPermissionsApplicableObject(String hashValue) {
        PermissionsApplicableObject permissionsApplicableObject = new PermissionsApplicableObject();
        // 无此模块权限，人员返回空数组
        if (StrUtil.isBlank(hashValue)) {
            return permissionsApplicableObject;
        }
        String[] splits = hashValue.split("#");
        PermissionsApplicableEnums permissionsApplicableEnums = PermissionsApplicableEnums.fromValue(splits[0]);
        permissionsApplicableObject.setPermissionsApplicableEnums(permissionsApplicableEnums);
        if (PermissionsApplicableEnums.SCOPE_SPECIFIC_ORGANIZATION.equals(permissionsApplicableEnums)) {
            permissionsApplicableObject.setOrgIds(List.of(splits[1].split(",")));
        }
        return permissionsApplicableObject;
    }

    /**
     * 获取用户权限适用范围
     *
     * @param userId           用户 ID
     * @param permissionModule 权限模块
     * @param category         类别
     * @return {@link String } 返回#分割的数组，如果是指定组织，则#后面跟着组织id，权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
     */
    public String obtainTheScopeOfUserPermissions(String userId, String permissionModule, String category) {
        String cacheKey = permissionModule + "#" + category;
        String module;
        if (cache.get(cacheKey) != null) {
            module = cache.get(cacheKey);
        } else {
            module = getModule(permissionModule, category);
            cache.put(cacheKey, module);
        }
        // 提取模块Id
        return getValidatedHashValue(userId, module);
    }

    /**
     * 获取当前登录用户所具有的数据权限组织Id，（超级管理员调动方自行判断）
     *
     * @param userId           用户ID
     * @param permissionModule 权限模块汉字
     * @param category         类别，传WEB或者APP
     * @return {@link List }<{@link String }>
     */
    public List<String> obtainPersonnelOrganizationIdDataPermissions(String userId, String permissionModule, String category) {
        String hashValue = obtainTheScopeOfUserPermissions(userId, permissionModule, category);
        return processScopeOrgIds(hashValue, userId);
    }

    /**
     * 获取当前登录用户所具有的数据权限组织Id，（超级管理员调动方自行判断）
     *
     * @param userId 用户ID
     * @return {@link List }<{@link String }>
     */
    public List<String> obtainPersonnelOrganizationIdDataPermissions(String userId) {
        // 提取模块获取方法
        String module = getRequestModule();
        // 提取hash值验证
        String hashValue = getValidatedHashValue(userId, module);
        return processScopeOrgIds(hashValue, userId);
    }

    /**
     * 当前登录员工已有的按钮及页面权限标识集合
     */
    public FtbPermissionRoleIdentificationVO permissionIdentificationCollection() {
        return ftbPermissionRoleService.permissionIdentificationCollection();
    }


    private String getModule(String permissionModule, String category) {
        String module;
        String tenantId = UserProvider.getUser().getTenantId();
        SystemEntity systemVO = systemApi.getSystemVO();
        String systemId = systemVO.getId();
//        String tenantId = UserProvider.getUser().getTenantId();
        List<ModuleEntity> data = moduleApi.getListWithoutSystemId(systemId, category, permissionModule, tenantId);
        // 获取顶级目录菜单
        ModuleEntity entities = data.stream()
                .filter(item -> item.getType() != null && item.getEnabledMark() != null && 1 == item.getEnabledMark()  && "-1".equals(item.getParentId()))
                .findFirst().orElse(null);
        if (entities == null) {
            throw new RuntimeException("暂未找到模块ID");
        }
        module = entities.getId();
        return module;
    }
    private List<String> getModuleWithTenantId(List<String> permissionModule, String category,String tenantId) {
        ActionResult<List<SystemEntity>> listByTenantId = systemApi.getListByTenantId(tenantId);
        if (listByTenantId == null) {
            throw new RuntimeException("系统管理服务获取数据失败!");
        }
        List<SystemEntity> list = listByTenantId.getData();
        SystemEntity systemEntity = list.stream().filter(item -> !"mainSystem".equals(item.getEnCode())).findFirst().orElse(null);
        if (systemEntity == null) {
            throw new RuntimeException("暂未找到模块ID");
        }
        String systemId = systemEntity.getId();
        return permissionModule.stream().map(v->{
            List<ModuleEntity> data = moduleApi.getListWithoutSystemId(systemId, category, v, tenantId);
            // 获取顶级目录菜单
            ModuleEntity entities = data.stream()
                    .filter(item -> item.getType() != null && item.getEnabledMark() != null && 1 == item.getEnabledMark()  && "-1".equals(item.getParentId()))
                    .findFirst().orElse(null);
            if (entities == null) {
                throw new RuntimeException("暂未找到模块ID");
            }
            return entities.getId();
        }).collect(Collectors.toList());
    }



    /**
     * 根据用户id,查询具有改用户权限的人员
     *
     * @param userId            需要查询的人员
     * @param buttonPermissions 按钮权限
     * @param category          web / app
     * @param currOrg
     * @param moduleId
     * @return 具备该权限的人员列表
     */
    public List<String> getUserPersonnelOrganizationIdDataPermissions(String userId, List<String> buttonPermissions, String category, List<String> module, String tenantId, String currOrg, String moduleId) {
        try {
            TenantDataSourceUtil.switchTenant(tenantId);
        } catch (LoginException e) {
            throw new RuntimeException(e);
        }
        List<UserBoundVO> data = selectedOrganizationAndPositionEmployees(tenantId);
        if (CollUtil.isEmpty(data)) return null;
        List<String> userIds = data.stream().map(UserBoundVO::getId).collect(Collectors.toList());
        List<String> adminUserIds = data.stream().filter(UserBoundVO::getIsAdministrator).map(UserBoundVO::getId).collect(Collectors.toList());
        // 过滤超管
        userIds = userIds.stream().filter(v->!adminUserIds.contains(v)).collect(Collectors.toList());
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.in(CollUtil.isNotEmpty(userIds), FtbPermissionRoleAuthorizePerson::getUserId, userIds);
        List<FtbPermissionRoleAuthorizePerson> people = ftbPermissionRoleAuthorizePersonMapper.selectList(wrapper);
        if (CollUtil.isEmpty(people)) return null;
        // 列表中所有人员和角色信息集合
        List<FtbEmployeePermissionPersonnelVO> personnelVOS = getEmpPersonnelVOS(data, people);
        LambdaQueryWrapper<FtbPermissionFunctionMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(FtbPermissionFunctionMenu::getOriginalCoding, buttonPermissions);
        List<FtbPermissionFunctionMenu> functionMenus = ftbPermissionFunctionMenuMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(functionMenus)) return null;
        // 查询具有权限的角色ids
        LambdaQueryWrapper<FtbPermissionRoleMenuRelation> lambdaed = Wrappers.lambdaQuery();
        lambdaed.in(FtbPermissionRoleMenuRelation::getRoleMenuConfigId, functionMenus.stream().map(FtbPermissionFunctionMenu::getId).collect(Collectors.toList()));
        List<FtbPermissionRoleMenuRelation> relations = ftbPermissionRoleMenuRelationMapper.selectList(lambdaed);
        if (CollUtil.isEmpty(relations)) return null;
        // 具有权限的角色ids
        List<String> idsOfTheRoleWithPermissions = relations.stream().map(FtbPermissionRoleMenuRelation::getRoleId).collect(Collectors.toList());
        LambdaQueryWrapper<FtbPermissionRoleMenu> query = Wrappers.lambdaQuery();
        query.in(FtbPermissionRoleMenu::getFunctionWebId, getModuleWithTenantId(module, category ,tenantId));
        // 人事数据角色权限list
        query.eq(FtbPermissionRoleMenu::getEnableMark, 0);
        List<FtbPermissionRoleMenu> roleMenus = ftbPermissionRoleMenuMapper.selectList(query);
        if (CollUtil.isEmpty(roleMenus)) return null;
        // Map<String, FtbPermissionRoleMenu> roleMenuMap = roleMenus.stream().collect(Collectors.toMap(FtbPermissionRoleMenu::getRoleId, Function.identity(), (key1, key2) -> key1));
        List<FtbEmployeePermissionPersonnelVO> peopleWithThesePermissions = personnelVOS.stream().filter(v -> {
            if (StringUtils.isEmpty(v.getRoleIds())) {
                return false;
            }
            String roleIds = v.getRoleIds();
            String[] split = roleIds.split(",");
            List<String> stringList = Arrays.stream(split).filter(idsOfTheRoleWithPermissions::contains).collect(Collectors.toList());
            if (CollUtil.isEmpty(stringList)) {
                return false;
            }
            return true;
        }).collect(Collectors.toList());
        List<String> peouUserIds = peopleWithThesePermissions.stream().map(FtbEmployeePermissionPersonnelVO::getUserId).collect(Collectors.toList());
        Map<String, String> userPermssion  =new HashMap<>();;
        peouUserIds.parallelStream().forEach(v -> {
            try {
                TenantDataSourceUtil.switchTenant(tenantId);
            } catch (LoginException e) {
                throw new RuntimeException(e);
            }
            Map<String, String> queryUserScopeOfPermissions = ftbPermissionRoleService.queryUserScopeOfPermission(v,tenantId);
            String hashValue = queryUserScopeOfPermissions.get(moduleId);
            if ("null".equals(hashValue) || hashValue == null) return;
            userPermssion.put(v, hashValue);
        });
        List<String> collect = peopleWithThesePermissions.stream().filter(item -> {
            if (!userPermssion.containsKey(item.getUserId())) return false;
            String haves = userPermssion.get(item.getUserId());
            try {
                List<String> processScope = processScopeOrgIds(haves, item.getUserId(), moduleId, tenantId);
                if (processScope == null) return true;
                if (CollUtil.isEmpty(processScope)) return false;
                return processScope.contains(currOrg);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }).map(FtbEmployeePermissionPersonnelVO::getUserId).collect(Collectors.toList());

//        // 过滤出具有权限的人
//        List<String> collect = peopleWithThesePermissions.stream().filter(item -> {
//            if (StringUtils.isEmpty(item.getRoleIds())) {
//                return false;
//            }
//            String roleIds = item.getRoleIds();
//            String[] split = roleIds.split(",");
//            List<FtbUserPermissionVO> userPermissionVOS = Arrays.stream(split).map(roleKey -> {
//                FtbPermissionRoleMenu roleMenu = roleMenuMap.get(roleKey);
//                if (roleMenu == null) {
//                    return null;
//                }
//                String haves = roleMenu.getScopePermission() + "#" + "--------";
//                try {
//
//                    List<String> processScope = processScopeOrgIds(haves, item.getUserId(),moduleId,tenantId);
//                    FtbUserPermissionVO permissionVO = new FtbUserPermissionVO();
//                    permissionVO.setUserId(item.getUserId());
//                    permissionVO.setPermissionIds(processScope);
//                    return permissionVO;
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    return null;
//                }
//            }).filter(Objects::nonNull).collect(Collectors.toList());
//            long count = userPermissionVOS.stream().filter(v -> {
//                        // 超级管理员
//                        if (v.getPermissionIds() == null) return true;
//                        // 无权限
//                        if (CollUtil.isEmpty(v.getPermissionIds())) return false;
//                        return v.getPermissionIds().contains(currOrg);
//                    }
//            ).count();
//            return count != 0;
//        }).map(FtbEmployeePermissionPersonnelVO::getUserId).distinct().collect(Collectors.toList());
        log.info("获取人员权限：{}", collect);
        adminUserIds.addAll(collect);
        return adminUserIds;
    }

    /**
     * 查询具有某个按钮功能的用户权限的人员
     *
     * @param buttonPermissions 按钮权限编码
     * @return 具备该权限的人员列表（用户Id）
     */
    public List<String> getUserPersonnelOrganizationIdDataPermissions(String buttonPermissions, String tenantId) {
        try {
            TenantDataSourceUtil.switchTenant(tenantId);
        } catch (LoginException e) {
            throw new RuntimeException(e);
        }
        // 判断勾选了按钮的权限
        LambdaQueryWrapper<FtbPermissionFunctionMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(FtbPermissionFunctionMenu::getOriginalCoding, buttonPermissions);
        queryWrapper.eq(FtbPermissionFunctionMenu::getEnableMark,0);
        List<FtbPermissionFunctionMenu> functionMenus = ftbPermissionFunctionMenuMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(functionMenus)) {
            return null;
        }
        // 查询具有权限的角色ids，岗位授权
        LambdaQueryWrapper<FtbPermissionRoleMenuRelation> lambdaed = Wrappers.lambdaQuery();
        lambdaed.in(FtbPermissionRoleMenuRelation::getRoleMenuConfigId, functionMenus.stream().map(FtbPermissionFunctionMenu::getId).collect(Collectors.toList()));
        lambdaed.eq(FtbPermissionRoleMenuRelation::getEnableMark,0);
        List<FtbPermissionRoleMenuRelation> relations = ftbPermissionRoleMenuRelationMapper.selectList(lambdaed);
        if (CollUtil.isEmpty(relations)) {
            return null;
        }
        List<String> roleIds = relations.stream().map(FtbPermissionRoleMenuRelation::getRoleId).collect(Collectors.toList());
        List<FtbPermissionRole> roles = permissionRoleMapper.selectBatchIds(roleIds);
        roleIds = roles.stream().filter(a->a.getEnableMark() == 0).map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList());
        if (CollUtil.isEmpty(roleIds)) {
            return null;
        }
        // 人员授权
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.in(FtbPermissionRoleAuthorizePerson::getRoleId,roleIds);
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getEnableMark,0);
        List<FtbPermissionRoleAuthorizePerson> people = ftbPermissionRoleAuthorizePersonMapper.selectList(wrapper);
        List<String> userIds = people.stream().map(FtbPermissionRoleAuthorizePerson::getUserId).collect(Collectors.toList());
        // 岗位授权
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> postWrapper = Wrappers.lambdaQuery();
        postWrapper.in(FtbPermissionRoleAuthorizePost::getRoleId,roleIds);
        postWrapper.eq(FtbPermissionRoleAuthorizePost::getEnableMark,0);
        List<FtbPermissionRoleAuthorizePost> posts = ftbPermissionRoleAuthorizePostMapper.selectList(postWrapper);
        List<String> postIds = posts.stream().map(FtbPermissionRoleAuthorizePost::getPostId).collect(Collectors.toList());
        // 获取岗位下绑定了那些人
        if (CollUtil.isNotEmpty(postIds)) {
            QueryUserBatchDTO dto = new QueryUserBatchDTO();
            dto.setPositionIds(postIds);
            dto.setTenantId(tenantId);
            ActionResult<List<UserBoundVO>> userInfoBatch = v2UserApi.getUserInfoBatch(dto);
            if (userInfoBatch.getCode() == 200 && CollUtil.isNotEmpty(userInfoBatch.getData())) {
                List<String> postionUserIds = userInfoBatch.getData().stream().map(UserBoundVO::getId).collect(Collectors.toList());
                userIds.addAll(postionUserIds);
            }
        }
        return userIds;
    }

    /**
     * 所选组织和岗位员工
     */
    private List<UserBoundVO> selectedOrganizationAndPositionEmployees(String tenantId) {
        QueryPageUserDTO queryPageUserDTO = new QueryPageUserDTO();
        queryPageUserDTO.setIsPage(false);
        queryPageUserDTO.setTenantId(tenantId);
        ActionResult<PageListVO<UserBoundVO>> pageListVOActionResult = v2UserApi.pagePost(queryPageUserDTO);
        if (pageListVOActionResult.getCode() == 200 && Objects.nonNull(pageListVOActionResult.getData())) {
            List<UserBoundVO> list = pageListVOActionResult.getData().getList();
            return list;
        }
        return null;
    }
    /**
     * 查询当前用户的操作权限集合
     *
     * @param userId           用户id
     * @param permissionModule 操作权限集合
     * @param category         web / app
     * @param module           {@link  PermissionsEnums}
     * @return 可具有的操作权限, 没有范围空
     */
    public List<String> queryCollectionOfUserButtonPermissions(String userId, List<String> permissionModule, String category, String module) {
        ActionResult<List<UserBoundVO>> byLikeName = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), null);
        if (byLikeName == null || CollUtil.isEmpty(byLikeName.getData())) {
            return null;
        }
        UserBoundVO userBoundVO = byLikeName.getData().stream().findFirst().orElse(null);
        if (userBoundVO == null) return null;
        // 人员id
        String positionId = userBoundVO.getPositionId();
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getUserId, userId);
        List<FtbPermissionRoleAuthorizePerson> people = ftbPermissionRoleAuthorizePersonMapper.selectList(wrapper);
        List<String> roleIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(people))
            roleIds = people.stream().map(FtbPermissionRoleAuthorizePerson::getRoleId).collect(Collectors.toList());
        // 授权的岗位
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionRoleAuthorizePost::getPostId, positionId);
        FtbPermissionRoleAuthorizePost post = ftbPermissionRoleAuthorizePostMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNotEmpty(post)) {
            roleIds.add(post.getRoleId());
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
        }
        if (CollUtil.isEmpty(roleIds)) return null;
        LambdaQueryWrapper<FtbPermissionRoleMenu> query = Wrappers.lambdaQuery();
        query.eq(FtbPermissionRoleMenu::getFunctionWebId, getModule(module, category));
        query.eq(FtbPermissionRoleMenu::getRoleId, roleIds);
        // 人事数据角色权限list
        query.eq(FtbPermissionRoleMenu::getEnableMark, 0);
        List<FtbPermissionRoleMenu> roleMenus = ftbPermissionRoleMenuMapper.selectList(query);
        if (CollUtil.isEmpty(roleMenus)) return null;

        LambdaQueryWrapper<FtbPermissionFunctionMenu> buttonPermissionsQueryWrapper = Wrappers.lambdaQuery();
        buttonPermissionsQueryWrapper.in(FtbPermissionFunctionMenu::getFunName, permissionModule);
        List<FtbPermissionFunctionMenu> functionMenus = ftbPermissionFunctionMenuMapper.selectList(buttonPermissionsQueryWrapper);
        if (CollUtil.isEmpty(functionMenus)) return null;
        Map<String, FtbPermissionFunctionMenu> functionMenuMap = functionMenus.stream().collect(Collectors.toMap(FtbPermissionFunctionMenu::getId, Function.identity()));
        // 查询具有权限的角色ids
        LambdaQueryWrapper<FtbPermissionRoleMenuRelation> lambdaed = Wrappers.lambdaQuery();
        lambdaed.in(FtbPermissionRoleMenuRelation::getRoleMenuConfigId, functionMenus.stream().map(FtbPermissionFunctionMenu::getId).collect(Collectors.toList()));
        List<FtbPermissionRoleMenuRelation> relations = ftbPermissionRoleMenuRelationMapper.selectList(lambdaed);
        if (CollUtil.isEmpty(relations)) return null;
        List<String> finalRoleIds = roleIds;
        return relations.stream().filter(v -> finalRoleIds.contains(v.getRoleId())).map(v -> functionMenuMap.get(v.getRoleMenuId()).getFunName()).collect(Collectors.toList());
    }

    @NotNull
    private List<FtbEmployeePermissionPersonnelVO> getEmpPersonnelVOS(List<UserBoundVO> orgUserIds, List<FtbPermissionRoleAuthorizePerson> people) {
        Map<String, List<FtbPermissionRoleAuthorizePerson>> listMap = people.stream().collect(Collectors.groupingBy(FtbPermissionRoleAuthorizePerson::getUserId));
        LambdaQueryWrapper<FtbPermissionRole> wrapper = Wrappers.lambdaQuery();
        List<FtbPermissionRole> rolesList = permissionRoleMapper.selectList(wrapper);
        Map<String, FtbPermissionRole> roleMap = rolesList.stream().collect(Collectors.toMap(FtbPermissionRole::getId, Function.identity(), (r1, r2) -> r1));

        LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionRoleAuthorizePost::getEnableMark,0);
        List<FtbPermissionRoleAuthorizePost> authorizePosts = ftbPermissionRoleAuthorizePostMapper.selectList(queryWrapper);
        Map<String, List<FtbPermissionRoleAuthorizePost>> postIdMap = new HashMap<>();
        if(CollUtil.isNotEmpty(authorizePosts)){
            postIdMap = authorizePosts.stream().collect(Collectors.groupingBy(FtbPermissionRoleAuthorizePost::getPostId));
        }
        Map<String, List<FtbPermissionRoleAuthorizePost>> finalPostIdMap = postIdMap;
        return orgUserIds.stream().map(k -> {
            if (k == null || k.getId() == null) {
                return null;
            }
            String userId = k.getId();
            FtbEmployeePermissionPersonnelVO personnelVO = new FtbEmployeePermissionPersonnelVO();
            personnelVO.setUserId(userId);
            personnelVO.setOrgName(k.getOrganizeName());
            personnelVO.setPostId(k.getPositionId());
            personnelVO.setPostName(k.getPositionName());
            personnelVO.setUserName(k.getName());

            List<String> roleIds = new ArrayList<>();
            if (listMap.containsKey(userId)){
                roleIds.addAll(listMap.get(userId).stream()
                        .map(FtbPermissionRoleAuthorizePerson::getRoleId)
                        .collect(Collectors.toList()));
            }

            if (k.getPositionId() != null && finalPostIdMap.containsKey(k.getPositionId())) {
                List<String> postRoleIds = finalPostIdMap.get(k.getPositionId()).stream()
                        .map(FtbPermissionRoleAuthorizePost::getRoleId)
                        .collect(Collectors.toList());
                Set<String> uniqueRoleIds = new HashSet<>(roleIds);
                uniqueRoleIds.addAll(postRoleIds);
                roleIds = new ArrayList<>(uniqueRoleIds);
            }
            personnelVO.setRoleIds(String.join(",", roleIds));
            personnelVO.setRoleName(roleIds.stream()
                    .map(roleId -> {
                        FtbPermissionRole ftbPermissionRole = roleMap.get(roleId);
                        return ftbPermissionRole == null ? null : ftbPermissionRole.getRoleName();
                    })
                    .filter(Objects::nonNull)
                    .collect(Collectors.joining(",")));
            return personnelVO;
        }).filter(Objects::nonNull).collect(Collectors.toList());

    }

    /**
     * @param userId
     * @param module
     * @return
     */

    private String getValidatedHashValue(String userId, String module) {
        String hashValue = redisUtil.getHashValues(getUserPermissionKey(userId), module);
        if (StrUtil.isBlank(hashValue)) {
            // 改为日志打印，由上层处理
            log.error("当前用户暂未设置此模块数据权限适用范围，module值为：{},用户Id为：{}",module,userId);
            return null;
        }
        return hashValue;
    }

    private List<String> processScope(String hashValue, String userId, List<UserWorkStatusEnums> userWorkStatusEnumsList, String... tenantIds) {
        String tenantId = tenantIds.length > 0 ? tenantIds[0] : UserProvider.getUser().getTenantId();
        String[] parts = hashValue.split("#");
        String scope = parts[0];
        // 权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
        switch (scope) {
            case "0":
                return null;
            case "1":
                return getUserOrganizeUsers(userId, true, tenantId, userWorkStatusEnumsList);
            case "2":
                return getUserOrganizeUsers(userId, false, tenantId, userWorkStatusEnumsList);
            case "3":
                return getUnderlingUsers(userId,tenantId);
            case "4":
                return getSpecifiedOrganizeUsers(parts, tenantId, userWorkStatusEnumsList);
            default:
                throw new IllegalArgumentException("未知的权限范围类型: " + scope);
        }
    }
    private List<String> processScopeOrgIds(String hashValue, String userId,String moduleId, String... tenantIds) {
        String tenantId = tenantIds.length > 0 ? tenantIds[0] : UserProvider.getUser().getTenantId();
        String[] parts = hashValue.split("#");
        String scope = parts[0];
        if(scope == null || "null".equals(scope)) return new ArrayList<>();
        // 权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
        switch (scope) {
            case "0":
                return null;
            case "1":
                return getUserOrganizeIds(userId, true,tenantId);
            case "2":
                return getUserOrganizeIds(userId, false,tenantId);
            case "3":
                // throw new RuntimeException("仅下属组织员工暂不支持");
                return new ArrayList<>();
            case "4":
                return getSpecifiedOrganizeOrgIds(parts);
            default:
                throw new IllegalArgumentException("未知的权限范围类型: " + scope);
        }
    }

    private List<String> processScopeOrgIds(String hashValue, String userId) {
        String[] parts = hashValue.split("#");
        String scope = parts[0];
        // 权限适用范围,0全部1所在组织和下级组织员工,2所在组织员工,3仅下属,4指定组织
        switch (scope) {
            case "0":
                return null;
            case "1":
                return getUserOrganizeIds(userId, true);
            case "2":
                return getUserOrganizeIds(userId, false);
            case "3":
                // throw new RuntimeException("仅下属组织员工暂不支持");
                // 仅下属权限时，同步返回组织名称，已发邮件
                return getUserOrganizeIds(userId, false);
            case "4":
                return getSpecifiedOrganizeOrgIds(parts);
            default:
                throw new IllegalArgumentException("未知的权限范围类型: " + scope);
        }
    }

    // 公共结果处理方法
    private List<String> processApiResult(ActionResult<List<UserPageListVO>> result) {
        if (result.getCode() != 200 || Objects.isNull(result.getData())) {
            throw new RuntimeException("获取用户数据失败，状态码: " + result.getCode());
        }
        return result.getData().stream()
                .map(UserPageListVO::getId)
                .collect(Collectors.toList());
    }

    private List<String> processApiResultOrg(ActionResult<List<OrganizeGeneralDetailVO>> result) {
        if (result.getCode() != 200 || Objects.isNull(result.getData())) {
            throw new RuntimeException("获取用户数据失败，状态码: " + result.getCode());
        }
        return result.getData().stream()
                .map(OrganizeGeneralDetailVO::getId)
                .collect(Collectors.toList());
    }

    // 具体类型处理方法
    private List<String> getUserOrganizeUsers(String userId, boolean includeSubOrg, String tenantId, List<UserWorkStatusEnums> userWorkStatusEnumsList) {
        return processApiResult(v2UserApi.listTargetUserOrganize(userId, includeSubOrg, tenantId, userWorkStatusEnumsList, null));
    }

    private List<String> getUserOrganizeIds(String userId, boolean includeSubOrg) {
        return processApiResultOrg(v2OrganizeApi.organizesByUserBound(userId, includeSubOrg));
    }
    private List<String> getUserOrganizeIds(String userId, boolean includeSubOrg,String tenantId) {
        return processApiResultOrg(v2OrganizeApi.organizesByUserBoundSwitchDb(userId, includeSubOrg,tenantId));
    }

    private List<String> getUnderlingUsers(String userId, String tenantId) {
        return processApiResult(v2UserApi.listUnderlingTargetUser(userId, tenantId));
    }

    private List<String> getSpecifiedOrganizeUsers(String[] parts, String tenantId, List<UserWorkStatusEnums> userWorkStatusEnumsList) {
        if (parts.length < 2 || StrUtil.isBlank(parts[1])) {
            throw new RuntimeException("未配置指定组织范围");
        }
        return processApiResult(v2UserApi.listTargetOrganizes(Arrays.asList(parts[1].split(",")), tenantId, userWorkStatusEnumsList));
    }

    private List<String> getSpecifiedOrganizeOrgIds(String[] parts) {
        if (parts.length < 2 || StrUtil.isBlank(parts[1])) {
            throw new RuntimeException("未配置指定组织范围");
        }
        return Arrays.asList(parts[1].split(","));
    }

    public String getRequestModule() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) throw new IllegalStateException("No active request context");
        HttpServletRequest request = attributes.getRequest();
        if (ObjectUtil.isEmpty(request.getHeader("module"))) throw new RuntimeException("请求头参数缺少module!");
        return request.getHeader("module");
    }

    /**
     * 人事管理入职模块人员权限专属
     */
    public List<String> getPersonnelUserIdDataPermissions(String userId, List<UserWorkStatusEnums> userWorkStatusEnumsList) {
        String requestModule = getRequestModule();
        String hashValue = getValidatedHashValue(userId, requestModule);
        return processScope(hashValue, userId, userWorkStatusEnumsList);
    }


}
