package jnpf.authority.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import jnpf.authority.mapper.*;
import jnpf.authority.service.FtbPermissionFunctionMenuService;
import jnpf.authority.service.FtbPermissionRoleAuthorizePersonService;
import jnpf.base.ActionResult;
import jnpf.base.ModuleApi;
import jnpf.base.entity.ModuleEntity;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.base.vo.PageListVO;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.authority.dto.authorize.FtbPermissionAuthorizeVO;
import jnpf.model.authority.dto.menu.FuntionMenuDTO;
import jnpf.model.authority.dto.person.FtbPermissionRoleBatchDeleteDTO;
import jnpf.model.authority.dto.person.FtbPermissionRolePersonAddDTO;
import jnpf.model.authority.dto.person.FtbPermissionRolePersonRelationDTO;
import jnpf.model.authority.dto.person.FunctionDTO;
import jnpf.model.authority.po.*;
import jnpf.model.authority.vo.menu.FtbPermissionMenuDirectoryVO;
import jnpf.model.authority.vo.person.FtbAuthorizedPersonnelVO;
import jnpf.model.authority.vo.person.FtbEmployeePermissionPersonnelVO;
import jnpf.model.authority.vo.person.FtbRoleListDropDownVO;
import jnpf.model.authority.vo.person.FunctionVO;
import jnpf.model.cultivate.CultivatePage;
import jnpf.permission.V2UserApi;
import jnpf.permission.vo.v2.user.UserBoundInfoVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.util.AuthUtil;
import jnpf.util.CustomTenantUtil;
import jnpf.util.UserProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 *
 *@Author: peng.hao
 *@create: 2025/3/5
 *
 */
@Service
public class FtbPermissionRoleAuthorizePersonServiceImpl extends ServiceImpl<FtbPermissionRoleAuthorizePersonMapper, FtbPermissionRoleAuthorizePerson> implements FtbPermissionRoleAuthorizePersonService{



    @Autowired
    V2UserApi v2UserApi;

    @Resource
    private FtbPermissionRoleMapper permissionRoleMapper;

    @Resource
    private FtbPermissionRolePersonUserRelationMapper ftbPermissionRolePersonUserRelationMapper;

    @Resource
    private FtbPermissionRoleAuthorizePostMapper ftbPermissionRoleAuthorizePostMapper;

    @Resource
    FtbPermissionFunctionMenuService  ftbPermissionFunctionMenuService;

    @Resource
    ModuleApi moduleApi;

    @Resource
    private CustomTenantUtil customTenantUtil;

    @Resource
    FtbPermissionRoleMenuRelationMapper ftbPermissionRoleMenuRelationMapper;

    @Override
    public PageListVO<FtbAuthorizedPersonnelVO> authorizedPersonnel(Page<FtbAuthorizedPersonnelVO> page, String roleId) {
        Page<FtbAuthorizedPersonnelVO> pageListVO = baseMapper.authorizedPersonnel(page,roleId);
        if (CollUtil.isEmpty(pageListVO.getRecords())) return CultivatePage.coverPageList(page);
        getPersonnelVOS(pageListVO.getRecords());
        return CultivatePage.coverPageList(pageListVO);
    }

    @NotNull
    private void getPersonnelVOS(List<FtbAuthorizedPersonnelVO> list) {
        List<String> userIds = list.stream().map(FtbAuthorizedPersonnelVO::getUserId).collect(Collectors.toList());
        ActionResult<List<UserBoundVO>> boundBatch = v2UserApi.getUserPrimaryBoundBatch(userIds, UserProvider.getUser().getTenantId());
        List<UserBoundVO> data = boundBatch.getData();
        Map<String, UserBoundVO> userIdMap = data.stream().collect(Collectors.toMap(UserBoundVO::getId, Function.identity(), (r1, r2) -> r1));
        list.forEach(v -> {
            if (userIdMap.containsKey(v.getUserId())) {
                UserBoundVO infoVO = userIdMap.get(v.getUserId());
                v.setOrgName(infoVO.getOrganizeName());
                v.setPostName(infoVO.getPositionName());
            }
        });
    }

    @Override
    public PageListVO<FtbEmployeePermissionPersonnelVO> employeePermission(Page<FtbEmployeePermissionPersonnelVO> page, String userName, List<String> userIds) {
        Page<FtbEmployeePermissionPersonnelVO> newPageList =  baseMapper.employeePermissionLPage(page,userName,null,userIds);
        List<FtbEmployeePermissionPersonnelVO> listRecords = newPageList.getRecords();
        supplementalData(listRecords);
        return CultivatePage.coverPageList(newPageList);
    }
    private void supplementalData(List<FtbEmployeePermissionPersonnelVO> list) {
        List<String> userIds = list.stream().map(FtbEmployeePermissionPersonnelVO::getUserId).collect(Collectors.toList());
        List<FtbEmployeePermissionPersonnelVO> records = baseMapper.employeePermission(userIds);
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserPrimaryBoundBatch(userIds, UserProvider.getUser().getTenantId());
        List<UserBoundVO> data = listActionResult.getData();
        if  (data == null) return;
        Map<String, UserBoundVO> userBoundVOMap = data.stream().collect(Collectors.toMap(UserBoundVO::getId, Function.identity()));
        List<String> positionIds = data.stream().filter(v-> StringUtils.isNotEmpty(v.getPositionId())).map(UserBoundVO::getPositionId).filter(Objects::nonNull).collect(Collectors.toList());
        Map<String, List<FtbPermissionRoleAuthorizePost>> postMaps = new HashMap<>();
        if (CollUtil.isNotEmpty(positionIds)) {
            LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> postQuery = Wrappers.lambdaQuery();
            postQuery.in(FtbPermissionRoleAuthorizePost::getPostId, positionIds);
            postQuery.eq(FtbPermissionRoleAuthorizePost::getEnableMark,0);
            List<FtbPermissionRoleAuthorizePost> authorizePosts = ftbPermissionRoleAuthorizePostMapper.selectList(postQuery);
            postMaps = authorizePosts.stream().collect(Collectors.groupingBy(FtbPermissionRoleAuthorizePost::getPostId));
        }
        Map<String, FtbEmployeePermissionPersonnelVO> personnelVOMap = records.stream().collect(Collectors.toMap(FtbEmployeePermissionPersonnelVO::getUserId, Function.identity(), (r1, r2) -> r1));
        LambdaQueryWrapper<FtbPermissionRole> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionRole::getEnableMark,0);
        List<FtbPermissionRole> rolesList = permissionRoleMapper.selectList(wrapper);
        Map<String, FtbPermissionRole> roleMap = rolesList.stream().collect(Collectors.toMap(FtbPermissionRole::getId, Function.identity(), (r1, r2) -> r1));
        Map<String, List<FtbPermissionRoleAuthorizePost>> finalPostMaps = postMaps;
        list.forEach(v->{
            List<String> roleIds = new ArrayList<>();
            if (userBoundVOMap.containsKey(v.getUserId())){
                UserBoundVO infoVO = userBoundVOMap.get(v.getUserId());
                v.setOrgName(infoVO.getOrganizeName());
                v.setPostId(infoVO.getPositionId());
                v.setPostName(infoVO.getPositionName());
            }
            if (finalPostMaps.containsKey(v.getPostId())){
                finalPostMaps.get(v.getPostId()).stream().map(FtbPermissionRoleAuthorizePost::getRoleId).forEach(roleIds::add);
            }
            if (personnelVOMap.containsKey(v.getUserId())){
                String[] split = personnelVOMap.get(v.getUserId()).getRoleIds().split(",");
                roleIds.addAll(List.of(split));
            }
            if (CollUtil.isNotEmpty(roleIds)){
                String roleIdsStr = roleIds.stream().distinct().collect(Collectors.joining(","));
                v.setRoleIds(roleIdsStr);
                List<String> roleNames = roleIds.stream().distinct().map(roleId -> {
                    if (!roleMap.containsKey(roleId)) return null;
                   return roleMap.get(roleId).getRoleName();
                }).filter(Objects::nonNull).collect(Collectors.toList());
                v.setRoleName(String.join(",", roleNames));
            }
        });
    }
    private void supplementalDataWithPost(List<FtbEmployeePermissionPersonnelVO> list) {
        List<String> userIds = list.stream().map(FtbEmployeePermissionPersonnelVO::getUserId).collect(Collectors.toList());
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserPrimaryBoundBatch(userIds, UserProvider.getUser().getTenantId());
        List<UserBoundVO> data = listActionResult.getData();
        if  (data == null) return;
        Map<String, UserBoundVO> userBoundVOMap = data.stream().collect(Collectors.toMap(UserBoundVO::getId, Function.identity()));
        List<String> positionIds = data.stream().filter(v-> StringUtils.isNotEmpty(v.getPositionId())).map(UserBoundVO::getPositionId).filter(Objects::nonNull).collect(Collectors.toList());
        Map<String, List<FtbPermissionRoleAuthorizePost>> postMaps = new HashMap<>();
        if (CollUtil.isNotEmpty(positionIds)) {
            LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> postQuery = Wrappers.lambdaQuery();
            postQuery.in(FtbPermissionRoleAuthorizePost::getPostId, positionIds);
            List<FtbPermissionRoleAuthorizePost> authorizePosts = ftbPermissionRoleAuthorizePostMapper.selectList(postQuery);
            postMaps = authorizePosts.stream().collect(Collectors.groupingBy(FtbPermissionRoleAuthorizePost::getPostId));
        }
        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));
        Map<String, List<FtbPermissionRoleAuthorizePost>> finalPostMaps = postMaps;
        list.forEach(v->{
            List<String> roleIds = new ArrayList<>();
            if (userBoundVOMap.containsKey(v.getUserId())){
                UserBoundVO infoVO = userBoundVOMap.get(v.getUserId());
                v.setOrgName(infoVO.getOrganizeName());
                v.setPostId(infoVO.getPositionId());
                v.setPostName(infoVO.getPositionName());
            }
            if (finalPostMaps.containsKey(v.getPostId())){
                finalPostMaps.get(v.getPostId()).stream().map(FtbPermissionRoleAuthorizePost::getRoleId).forEach(roleIds::add);
            }
            if (CollUtil.isNotEmpty(roleIds)){
                String roleIdsStr = roleIds.stream().distinct().collect(Collectors.joining(","));
                v.setRoleIds(roleIdsStr);
                List<String> roleNames = roleIds.stream().distinct().map(roleId -> roleMap.get(roleId).getRoleName()).collect(Collectors.toList());
                v.setRoleName(String.join(",", roleNames));
            }
        });
    }

    @Override
    public List<FtbRoleListDropDownVO> roleListDropDown(String userId) {
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getUserId, userId);
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getEnableMark,0);
        List<FtbPermissionRoleAuthorizePerson> people = baseMapper.selectList(wrapper);
        ActionResult<List<UserBoundVO>> primaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), UserProvider.getUser().getTenantId());
        List<String> roleIds = new ArrayList<>();
        if(primaryBoundBatch != null &&  primaryBoundBatch.getData() != null){
            List<UserBoundVO> data = primaryBoundBatch.getData();
            if (CollUtil.isNotEmpty(data) ){
                LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> queryWrapper = Wrappers.lambdaQuery();
                queryWrapper.eq(FtbPermissionRoleAuthorizePost::getPostId, data.get(0).getPositionId());
                queryWrapper.eq(FtbPermissionRoleAuthorizePost::getEnableMark, 0);
                List<FtbPermissionRoleAuthorizePost> roleAuthorizePosts = ftbPermissionRoleAuthorizePostMapper.selectList(queryWrapper);
                if (CollUtil.isNotEmpty(roleAuthorizePosts)) {
                    roleIds = roleAuthorizePosts.stream().map(FtbPermissionRoleAuthorizePost::getRoleId).collect(Collectors.toList());
                }
            }
        }
        List<FtbPermissionRole> roles = permissionRoleMapper.selectList(new LambdaQueryWrapper<FtbPermissionRole>().eq(FtbPermissionRole::getEnableMark,0));
        List<String> finalRoleIds = roleIds;
        return roles.stream().map(v->{
            FtbRoleListDropDownVO covert = FtbRoleListDropDownVO.covert(v);
            if (people.stream().anyMatch(p->p.getRoleId().equals(v.getId()))){
                covert.setIsOpen(true);
            }else if (CollUtil.isNotEmpty(finalRoleIds) && finalRoleIds.contains(v.getId())){
                covert.setIsOpen(true);
            }
            return covert;
        }).collect(Collectors.toList());
    }
    @Override
    public List<FtbRoleListDropDownVO> allRolesOfTheCurrentPerson(String userId, String tenantId) {
        customTenantUtil.checkOutTenant(tenantId);
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getUserId, userId);
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getEnableMark,0);
        List<FtbPermissionRoleAuthorizePerson> people = baseMapper.selectList(wrapper);
        List<String> roleIds = new ArrayList<>() ;
        if (CollUtil.isNotEmpty(people)) {
            roleIds.addAll(people.stream().map(FtbPermissionRoleAuthorizePerson::getRoleId).collect(Collectors.toList())) ;
        }
        ActionResult<UserBoundInfoVO> actionResult = v2UserApi.getUsersBound(userId, UserProvider.getUser().getTenantId());
        if(actionResult != null  && actionResult.getData() != null) {
            LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(FtbPermissionRoleAuthorizePost::getPostId, actionResult.getData().getPositionId());
            queryWrapper.eq(FtbPermissionRoleAuthorizePost::getEnableMark,0);
            List<FtbPermissionRoleAuthorizePost> authorizePosts = ftbPermissionRoleAuthorizePostMapper.selectList(queryWrapper);
            if  (CollUtil.isNotEmpty(authorizePosts)) {
                roleIds.addAll(authorizePosts.stream().map(FtbPermissionRoleAuthorizePost::getRoleId).collect(Collectors.toList()));
            }
        }
        if (CollUtil.isEmpty(roleIds)) return null;
        LambdaQueryWrapper<FtbPermissionRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FtbPermissionRole::getEnableMark,0);
        queryWrapper.in(SuperBaseEntity.SuperIBaseEntity::getId,roleIds);
        List<FtbPermissionRole> roles = permissionRoleMapper.selectList(queryWrapper);
        return roles.stream().map(v->{
            FtbRoleListDropDownVO covert = FtbRoleListDropDownVO.covert(v);
            if (roles.contains(v)){
                covert.setIsOpen(true);
            }
            return covert;
        }).collect(Collectors.toList());
    }

    @Override
    public void addPersonalPermission(FtbPermissionRolePersonRelationDTO rolePersonAddDTO) {
        String userId = rolePersonAddDTO.getUserId();
        // 先清空数据
        LambdaQueryWrapper<FtbPermissionRolePersonUserRelation> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionRolePersonUserRelation::getUserId, userId);
        int delete = ftbPermissionRolePersonUserRelationMapper.delete(queryWrapper);
        List<FunctionDTO> functionDTOList = rolePersonAddDTO.getFunctionDTOList();
        long count = functionDTOList.stream().filter(v -> v.getRoleEnabled() == 1).count();
        // 无修改
        if (count  == 0 && delete != 0) {
            AuthUtil.kickoutByUserId(userId);
            return;
        }
        List<FtbPermissionRolePersonUserRelation> userRelationsList = functionDTOList.stream().map(v -> {
            FtbPermissionRolePersonUserRelation userRelation = new FtbPermissionRolePersonUserRelation();
            userRelation.setUserId(userId);
            userRelation.setFunctionWebId(v.getFunctionWebId());
            userRelation.setFunctionAppId(v.getFunctionAppId());
            userRelation.setFunctionPcId(v.getFunctionPcId());
            userRelation.setScopePermission(v.getScopePermission());
            if(CollUtil.isNotEmpty(v.getSpecifyOrgIds())) userRelation.setSpecifyOrgIds(v.getSpecifyOrgIds().stream().map(Object::toString).collect(Collectors.joining(",")));
            userRelation.setRoleEnabled(v.getRoleEnabled());
            return userRelation;
        }).collect(Collectors.toList());
        Db.saveBatch(userRelationsList);
        AuthUtil.kickoutByUserId(userId);
    }

    @Override
    public List<FunctionVO> getPersonalPermission(String userId) {
        LambdaQueryWrapper<FtbPermissionRolePersonUserRelation> userRelationLambdaQueryWrapper = Wrappers.lambdaQuery();
        userRelationLambdaQueryWrapper.eq(FtbPermissionRolePersonUserRelation::getUserId, userId);
        userRelationLambdaQueryWrapper.eq(FtbPermissionRolePersonUserRelation::getEnableMark, 0);
        List<FtbPermissionRolePersonUserRelation> userRelations = ftbPermissionRolePersonUserRelationMapper.selectList(userRelationLambdaQueryWrapper);
        List<String> roleIds = new ArrayList<>();
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionRoleAuthorizePerson::getUserId, userId);
        queryWrapper.eq(FtbPermissionRoleAuthorizePerson::getEnableMark, 0);
        List<FtbPermissionRoleAuthorizePerson> roleAuthorizePeople = baseMapper.selectList(queryWrapper);
       if (CollUtil.isNotEmpty(roleAuthorizePeople)) {
            roleIds.addAll(roleAuthorizePeople.stream().map(FtbPermissionRoleAuthorizePerson::getRoleId).collect(Collectors.toList()));
        }
        // 查询岗位信息绑定角色
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), UserProvider.getUser().getTenantId());
        List<UserBoundVO> data = listActionResult.getData();
        if (data == null) throw new RuntimeException("获取用户信息失败");
        List<String> positionIds = data.stream().map(UserBoundVO::getPositionId).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(positionIds)) {
            LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> postQuery = Wrappers.lambdaQuery();
            postQuery.in(FtbPermissionRoleAuthorizePost::getPostId, positionIds);
            postQuery.eq(FtbPermissionRoleAuthorizePost::getEnableMark,0);
            List<FtbPermissionRoleAuthorizePost> authorizePosts = ftbPermissionRoleAuthorizePostMapper.selectList(postQuery);
            if (CollUtil.isNotEmpty(authorizePosts)) {
                roleIds.addAll(authorizePosts.stream().map(FtbPermissionRoleAuthorizePost::getRoleId).collect(Collectors.toList()));
            }
        }
        if (CollUtil.isEmpty(roleIds)) return null;
        // 多个角色信息出现重合情况
        List<List<FtbPermissionMenuDirectoryVO>> listList = roleIds.stream().map(v -> {
            List<FtbPermissionMenuDirectoryVO> directory = ftbPermissionFunctionMenuService.getAListOfMenuDirectory(v);
            return directory.stream().filter(FtbPermissionMenuDirectoryVO::getIsUse).collect(Collectors.toList());
        }).collect(Collectors.toList());
        // 多个模块进行平铺
        List<FtbPermissionMenuDirectoryVO> directory = listList.stream().flatMap(List::stream).distinct().collect(Collectors.toList());
        // 库回显
        Map<String, FunctionVO> functionVOMap = new HashMap<>();
        if (CollUtil.isNotEmpty(userRelations)) {
            List<FunctionVO> functionVOList = userRelations.stream().map(v -> {
                FunctionVO functionVO = new FunctionVO();
                functionVO.setFunctionWebId(v.getFunctionWebId());
                ModuleEntity moduleApiModuleByList = moduleApi.getModuleByList(v.getFunctionWebId());
                if (moduleApiModuleByList != null) {
                    functionVO.setModuleName(moduleApiModuleByList.getFullName());
                } else {
                    ModuleEntity moduleEntity = moduleApi.getModuleByList(v.getFunctionAppId());
                    if (moduleEntity != null) {
                        functionVO.setModuleName(moduleEntity.getFullName());
                    } else {
                        moduleEntity = moduleApi.getModuleByList(v.getFunctionPcId());
                        if (moduleEntity != null) {
                            functionVO.setModuleName(moduleEntity.getFullName());
                        }
                    }
                }
                functionVO.setFunctionPcId(v.getFunctionPcId());
                functionVO.setFunctionAppId(v.getFunctionAppId());
                functionVO.setScopePermission(v.getScopePermission());
                if (StringUtils.isNotEmpty(v.getSpecifyOrgIds()))
                    functionVO.setSpecifyOrgIds(List.of(v.getSpecifyOrgIds().split(",")));
                functionVO.setRoleEnabled(v.getRoleEnabled());
                return functionVO;
            }).collect(Collectors.toList());
            functionVOMap = functionVOList.stream().collect(Collectors.toMap(FunctionVO::getModuleName, v -> v, (a, b) -> a));
        }
        Map<String, FunctionVO> finalFunctionVOMap = functionVOMap;
        return directory.stream().map(v -> {
            FunctionVO functionVO = new FunctionVO();
            functionVO.setModuleName(v.getFullName());
            FunctionVO vo = finalFunctionVOMap.get(v.getFullName());
            if (finalFunctionVOMap.containsKey(v.getFullName())){
                if (CollUtil.isNotEmpty(vo.getSpecifyOrgIds())) functionVO.setSpecifyOrgIds(vo.getSpecifyOrgIds());
                functionVO.setScopePermission(vo.getScopePermission());
                functionVO.setRoleEnabled(vo.getRoleEnabled());
            }else {
                functionVO.setRoleEnabled(0);
            }
            FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO orElseWeb = getDirectoryInfoVO("Web", v);
            FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO orElseApp = getDirectoryInfoVO("App", v);
            FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO orElsePc = getDirectoryInfoVO("PC", v);
            if (orElseWeb != null) {
                functionVO.setFunctionWebId(orElseWeb.getId());
            }
            if (orElseApp != null) {
                functionVO.setFunctionAppId(orElseApp.getId());
            }
            if (orElsePc != null) {
                functionVO.setFunctionPcId(orElsePc.getId());
            }
            return functionVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<String> queryButtonPermission(FuntionMenuDTO funtion) throws LoginException {
        TenantDataSourceUtil.switchTenant(funtion.getTenantId());
        LambdaQueryWrapper<FtbPermissionFunctionMenu> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionFunctionMenu::getEnableMark,0);
        queryWrapper.in(FtbPermissionFunctionMenu::getOriginalCoding, funtion.getButtonEncoding());
        List<FtbPermissionFunctionMenu> list = ftbPermissionFunctionMenuService.list(queryWrapper);
        if (CollUtil.isEmpty(list)) return null;
        Page<FtbEmployeePermissionPersonnelVO> objectPage = new Page<>();
        objectPage.setSize(-1);
        PageListVO<FtbEmployeePermissionPersonnelVO> pageListVO = employeePermission(objectPage, null, funtion.getUserIds());
        List<FtbEmployeePermissionPersonnelVO> listRecords = pageListVO.getList();
        List<String> roleIds = listRecords.stream().map(v -> {
            if (StringUtils.isNotEmpty(v.getRoleIds())) {
                return v.getRoleIds().split(",");
            }
            return null;
        }).filter(Objects::nonNull).flatMap(Arrays::stream).collect(Collectors.toList());
        LambdaQueryWrapper<FtbPermissionRoleMenuRelation> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionRoleMenuRelation::getEnableMark,0);
        wrapper.in(FtbPermissionRoleMenuRelation::getRoleId, roleIds);
        wrapper.in(FtbPermissionRoleMenuRelation::getRoleMenuConfigId, list.stream().map(FtbPermissionFunctionMenu::getId).collect(Collectors.toList()));
        List<FtbPermissionRoleMenuRelation> personUserRelations = ftbPermissionRoleMenuRelationMapper.selectList(wrapper);
        if (CollUtil.isEmpty(personUserRelations)) return null;
        // 包含按钮
        List<String> roleids = personUserRelations.stream().map(FtbPermissionRoleMenuRelation::getRoleId).collect(Collectors.toList());
        Set<String> roleIdSet = new HashSet<>(roleids);
        List<String> userIds = listRecords.stream().filter(v -> {
            if (StringUtils.isNotEmpty(v.getRoleIds())) {
                String[] split = v.getRoleIds().split(",");
                return Arrays.stream(split).anyMatch(roleIdSet::contains);
            }
            return false;
        }).map(FtbEmployeePermissionPersonnelVO::getUserId).collect(Collectors.toList());
        return userIds;
    }

    @Nullable
    private static FtbPermissionMenuDirectoryVO.FtbPermissionMenuDirectoryInfoVO getDirectoryInfoVO(String str, FtbPermissionMenuDirectoryVO v) {
        return v.getChildren().stream().filter(c -> str.equals(c.getCategory())).findFirst().orElse(null);
    }

    @Override
    public void editEmployeePermission(List<String> roleIds, String userId) {
        Page<FtbEmployeePermissionPersonnelVO> page = new Page<>();
        page.setSize(-1);
        Page<FtbEmployeePermissionPersonnelVO> newPageList =  baseMapper.employeePermissionLPage(page,null,userId, null);
        List<FtbEmployeePermissionPersonnelVO> listRecords = newPageList.getRecords();
        supplementalDataWithPost(listRecords);
        FtbEmployeePermissionPersonnelVO personnelVO = listRecords.stream().filter(item -> userId.equals(item.getUserId())).findFirst().orElse(new FtbEmployeePermissionPersonnelVO());
        if (StringUtils.isNotEmpty(personnelVO.getRoleIds())) {
            List<String> stringList = List.of(personnelVO.getRoleIds().split(","));
            List<String> postRoleIds = stringList.stream().filter(v -> !roleIds.contains(v)).collect(Collectors.toList());
            // 如果岗位授权到了角色,不能解绑
            if (CollUtil.isNotEmpty(postRoleIds)) {
                LambdaQueryWrapper<FtbPermissionRoleAuthorizePost> postWrapper = Wrappers.lambdaQuery();
                postWrapper.in(FtbPermissionRoleAuthorizePost::getRoleId, postRoleIds);
                postWrapper.eq(FtbPermissionRoleAuthorizePost::getEnableMark,0);
                List<FtbPermissionRoleAuthorizePost> posts = ftbPermissionRoleAuthorizePostMapper.selectList(postWrapper);
                if (CollUtil.isNotEmpty(posts)) {
                    LambdaQueryWrapper<FtbPermissionRole> lambdaQuery = Wrappers.lambdaQuery();
                    lambdaQuery.in(SuperBaseEntity.SuperIBaseEntity::getId, postRoleIds);
                    lambdaQuery.eq(FtbPermissionRole::getEnableMark,0);
                    List<FtbPermissionRole> permissionRoles = permissionRoleMapper.selectList(lambdaQuery);
                    String collected = permissionRoles.stream().map(FtbPermissionRole::getRoleName).collect(Collectors.joining(","));
                    throw new RuntimeException(collected + "已授权到岗位，不可解绑！");
                }
            }
        }
        // 首先将管理员数据全部移除
        v2UserApi.userAdminEnable(userId, false);
        LambdaUpdateWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getUserId, userId);
        wrapper.set(FtbPermissionRoleAuthorizePerson::getEnableMark,1);
        baseMapper.update(new FtbPermissionRoleAuthorizePerson(),wrapper);
        if (CollUtil.isEmpty(roleIds)) {
            // 删除所有员工权限
            // 员工踢下线
            AuthUtil.kickoutByUserId(userId);
            return;
        }
        List<FtbPermissionRoleAuthorizePerson> collected = roleIds.stream().map(roleId -> {
            FtbPermissionRoleAuthorizePerson person = new FtbPermissionRoleAuthorizePerson();
            person.setUserId(userId);
            person.setRoleId(roleId);
            LambdaQueryWrapper<FtbPermissionRole> roleLambdaQueryWrapper = Wrappers.lambdaQuery();
            roleLambdaQueryWrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, roleId);
            roleLambdaQueryWrapper.eq(FtbPermissionRole::getEnableMark,0);
            FtbPermissionRole ftbPermissionRole = permissionRoleMapper.selectOne(roleLambdaQueryWrapper);
            Integer isSuperAdmin = ftbPermissionRole.getIsSuperAdmin();
            // 同步超级管理员到base_user表
            if (isSuperAdmin == 1){
                syncSuperAdmin(userId, true);
            }
            return person;
        }).collect(Collectors.toList());
        Db.saveBatch(collected);
        // 员工踢下线
        collected.stream().map(FtbPermissionRoleAuthorizePerson::getUserId).forEach(AuthUtil::kickoutByUserId);
    }

    @Override
    public void add(FtbPermissionRolePersonAddDTO rolePersonAddDTO) {
        String roleId = rolePersonAddDTO.getRoleId();
        LambdaQueryWrapper<FtbPermissionRole> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, roleId);
        FtbPermissionRole ftbPermissionRole = permissionRoleMapper.selectOne(wrapper);
        Integer isSuperAdmin = ftbPermissionRole.getIsSuperAdmin();
        // 查询生效的数据
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPermissionRoleAuthorizePerson::getRoleId, roleId);
        queryWrapper.eq(FtbPermissionRoleAuthorizePerson::getEnableMark,0);
        queryWrapper.ne(FtbPermissionRoleAuthorizePerson::getUserId,"349057407209541");
        // 清空所有绑定关系
        List<FtbPermissionRoleAuthorizePerson> people = baseMapper.selectList(queryWrapper);
        List<String> userIds = rolePersonAddDTO.getUserIds();
        List<String> collect = people.stream().map(FtbPermissionRoleAuthorizePerson::getUserId).collect(Collectors.toList());
        // 空提交删除之前所有绑定的用户
        if (CollUtil.isEmpty(userIds) && CollUtil.isNotEmpty(people)){
            if (isSuperAdmin == 1) collect.forEach(v->syncSuperAdmin(v, false));
            // 删除所有员工权限
            baseMapper.deleteBatchIds(people.stream().map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList()));
            // 员工踢下线
            collect.forEach(AuthUtil::kickoutByUserId);
            return;
        }
        if (CollUtil.isNotEmpty(people)) {
            // 排除之前以绑定的员工
            List<String> newUserIds = userIds.stream().filter(item -> !collect.contains(item)).collect(Collectors.toList());
            List<String> finalUserIds = userIds;
            List<String> deleteUserIds = collect.stream().filter(v->!finalUserIds.contains(v)).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(deleteUserIds)) {
                // 员工踢下线
                deleteUserIds.forEach(AuthUtil::kickoutByUserId);
                if (isSuperAdmin == 1) deleteUserIds.forEach(v->syncSuperAdmin(v, false));
                // 关闭以前的超管
                baseMapper.deleteBatchIds(people.stream().filter(v->deleteUserIds.contains(v.getUserId())).map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList()));
            }
            userIds = newUserIds;
        }
        if (CollUtil.isEmpty(userIds)) return;
        // 同步超级管理员到base_user表
        if (isSuperAdmin == 1){
            for (String userId : userIds) {
                syncSuperAdmin(userId, true);
            }
        }
        List<FtbPermissionRoleAuthorizePerson> collected = userIds.stream().map(userId -> {
            FtbPermissionRoleAuthorizePerson person = new FtbPermissionRoleAuthorizePerson();
            person.setUserId(userId);
            person.setRoleId(roleId);
            return person;
        }).collect(Collectors.toList());
        Db.saveBatch(collected);
        // 员工踢下线
        userIds.forEach(AuthUtil::kickoutByUserId);

    }

    @Override
    public void batchDelete(FtbPermissionRoleBatchDeleteDTO rolePersonDeleteDTO) {
        List<FtbPermissionRoleAuthorizePerson> people = baseMapper.selectBatchIds(rolePersonDeleteDTO.getPrimaryKeyIds());
        for (FtbPermissionRoleAuthorizePerson person : people) {
            String roleId = person.getRoleId();
            LambdaQueryWrapper<FtbPermissionRole> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, roleId);
            FtbPermissionRole ftbPermissionRole = permissionRoleMapper.selectOne(wrapper);
            Integer isSuperAdmin = ftbPermissionRole.getIsSuperAdmin();
            // 同步超级管理员到base_user表
            if (isSuperAdmin == 1){
                // 移除超级管理员信息
                syncSuperAdmin(person.getUserId(), false);
            }
        }
        Db.removeByIds(rolePersonDeleteDTO.getPrimaryKeyIds(),FtbPermissionRoleAuthorizePerson.class);
        // 员工踢下线
        people.stream().map(FtbPermissionRoleAuthorizePerson::getUserId).forEach(AuthUtil::kickoutByUserId);
    }

    private void syncSuperAdmin(String person, boolean enabled) {
        ActionResult<Boolean> actionResult = v2UserApi.userAdminEnable(person, enabled);
        if (actionResult == null || actionResult.getCode() != 200) {
            throw new RuntimeException("同步超级管理员状态失败!请重试!");
        }
    }

    @Override
    public List<String> getRoleIdsByUserId(FtbPermissionAuthorizeVO vo) {
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getRoleId,vo.getAuthorizationId());
        wrapper.eq(FtbPermissionRoleAuthorizePerson::getEnableMark,0);
        List<FtbPermissionRoleAuthorizePerson> people = baseMapper.selectList(wrapper);
        List<String> hasBandUserIds = people.stream().map(FtbPermissionRoleAuthorizePerson::getUserId).distinct().collect(Collectors.toList());
        List<String> userIds = vo.getIds();
        if (CollUtil.isNotEmpty(hasBandUserIds)){
            return userIds.stream().filter(v->!hasBandUserIds.contains(v)).collect(Collectors.toList());
        }
        return userIds;
    }

    @Override
    public void deleteEmployeeAllPermission(List<String> userIds) {
        // 首先将管理员数据全部移除
        v2UserApi.userAdminEnableBatch(userIds, false);
        LambdaQueryWrapper<FtbPermissionRoleAuthorizePerson> wrapper = Wrappers.lambdaQuery();
        wrapper.in(FtbPermissionRoleAuthorizePerson::getUserId,userIds);
        baseMapper.delete(wrapper);
        userIds.forEach(AuthUtil::kickoutByUserId);
    }


}
