package com.xdap.self_development.service.impl;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.definesys.mpaas.query.MpaasQuery;
import com.xdap.api.moudle.department.pojo.entity.XdapDepartments;
import com.xdap.api.moudle.department.pojo.entity.XdapDeptUsers;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.common.BusinessDatabase;
import com.xdap.self_development.controller.request.*;
import com.xdap.self_development.domain.dto.PageResultDTO;
import com.xdap.self_development.domain.enums.ParamPermissionEnum;
import com.xdap.self_development.domain.pojo.*;
import com.xdap.self_development.domain.view.MenuParamView;
import com.xdap.self_development.domain.view.RoleAndPreView;
import com.xdap.self_development.domain.view.RoleInfoView;
import com.xdap.self_development.domain.view.UserDeptItem;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.service.ModelRoleService;
import com.xdap.self_development.service.XdapDeptUsersService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.Collator;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 模型角色服务实现类
 *
 * @version 1.0
 * @since 2025
 */
@Slf4j
@Service
public class ModelRoleServiceImpl implements ModelRoleService {

    @Resource
    private BusinessDatabase businessDatabase;

    @Resource
    private XdapDeptUsersService xdapDeptUsersService;

    @Resource
    private ModelRoleService modelRoleService;

    /**
     * 添加角色
     * 根据请求参数添加新角色
     *
     * @param request 模型角色请求
     * @return void
     */
    @Override
    public void addRoles(ModelRolesRequest request) {
        List<ModelRolesPojo> modelRolesPojos = businessDatabase.getBusinessDatabase()
                .eq("is_enabled", 1)
                .eq("role_code", request.getRoleCode())
                .doQuery(ModelRolesPojo.class);
        if (ObjectUtils.isNotEmpty(modelRolesPojos)) {
            throw new CommonException("角色已存在");
        }
        ModelRolesPojo modelRolesPojo = new ModelRolesPojo();
        BeanUtils.copyProperties(request, modelRolesPojo);
        modelRolesPojo.setCreatedBy(request.getUserId());
        modelRolesPojo.setCreationDate(new Date());
        modelRolesPojo.setIsEnabled(1);
        businessDatabase.getBusinessDatabase()
                .doInsert(modelRolesPojo);
    }

    /**
     * 查询所有角色
     * 查询系统中的所有角色信息
     *
     * @return 角色POJO列表
     */
    @Override
    public List<ModelRolesPojo> selectRoles() {
        return businessDatabase.getBusinessDatabase()
                .eq("is_enabled", 1)
                .doQuery(ModelRolesPojo.class);
    }

    /**
     * 更新角色权限
     * 根据请求列表更新角色权限信息
     *
     * @param requests 角色权限关联请求列表
     * @return void
     */
    @Override
    @Transactional
    public void updatePerForRole(List<RolePerJoinRequest> requests) {

        //将老权限置为未启用
        List<String> roleids = requests.stream().map(x -> x.getRoleId()).distinct().collect(Collectors.toList());
        for (String roleId : roleids) {
            if (ObjectUtils.isNotEmpty(roleId)) {
                businessDatabase.getBusinessDatabase()
                        .update("is_enable", 0)
                        .eq("role_id", roleId)
                        .doUpdate(ModelRolePermissionPojo.class);
            }
        }
        //增加新权限
        for (RolePerJoinRequest request : requests) {
            String roleId = request.getRoleId();
            String permissionPath = request.getPermissionPath();

            Integer parameterPer = request.getParameterPer();
            if (ObjectUtils.isEmpty(permissionPath) || ObjectUtils.isEmpty(parameterPer) || ObjectUtils.isEmpty(roleId)) {
                log.warn("参数不完整无法写入");
                continue;
            }
            List<ModelMenuParameterPojo> modelMenuParameterPojos = businessDatabase.getBusinessDatabase()

                    .eq("permission_path", permissionPath)
                    .eq("parameter_per", parameterPer)
                    .doQuery(ModelMenuParameterPojo.class);

            //如果参数权限没有配置
            String id = String.valueOf(UUID.randomUUID());
            if (ObjectUtils.isEmpty(modelMenuParameterPojos)) {
                //查找参数 组装权限
                ModelMenuParameterPojo modelMenuParameterPojo = new ModelMenuParameterPojo();
                modelMenuParameterPojo.setPermissionPath(permissionPath);
                modelMenuParameterPojo.setParameterPer(parameterPer);
                modelMenuParameterPojo.setId(id);
                modelMenuParameterPojo.setCreatedBy(request.getUserId());
                modelMenuParameterPojo.setCreationDate(new Date());
                businessDatabase.getBusinessDatabase()
                        .doInsert(modelMenuParameterPojo);

            } else {
                id = modelMenuParameterPojos.get(0).getId();
            }

            //为角色分配权限
            ModelRolePermissionPojo pojo = new ModelRolePermissionPojo();
            pojo.setRoleId(roleId);
            pojo.setPerId(id);
            pojo.setCreationDate(new Date());
            pojo.setCreatedBy(request.getUserId());
            pojo.setIsEnable(1);
            businessDatabase.getBusinessDatabase()
                    .doInsert(pojo);
        }

    }

    /**
     * 更新角色
     * 根据角色信息和用户ID更新角色
     *
     * @param modelRolesPojo 模型角色POJO
     * @param userID         用户ID
     * @return void
     */
    @Override
    public void updateRole(ModelRolesPojo modelRolesPojo, String userID) {
        modelRolesPojo.setLastUpdatedBy(userID);
        modelRolesPojo.setLastUpdateDate(new Date());
        businessDatabase.getBusinessDatabase()
                .update("role_name", modelRolesPojo.getRoleName())
                .update("role_code", modelRolesPojo.getRoleCode())
                .update("role_description", modelRolesPojo.getRoleDescription())
                .rowid("id", modelRolesPojo.getId())
                .doUpdate(ModelRolesPojo.class);
    }

    /**
     * 根据用户查询权限
     * 根据用户或部门ID查询权限信息
     *
     * @param userOrDepID 用户或部门ID
     * @return 菜单参数视图列表
     */
    @Override
    public List<MenuParamView> selectPersByUser(String userOrDepID) {
        log.info("开始查询用户权限 - 用户ID: {}", userOrDepID);
        
        if (ObjectUtils.isEmpty(userOrDepID)) {
            throw new CommonException("用户或部门ID为空");
        }
        List<ModelDepUserRolePojo> userOrDeps = businessDatabase.getBusinessDatabase()
                .eq("user_or_dep", userOrDepID)
                .eq("is_enable", 1)
                .doQuery(ModelDepUserRolePojo.class);
        
        log.info("用户绑定的角色数量: {}", userOrDeps.size());
        
        List<MenuParamView> paramViews = new ArrayList<>();
        for (ModelDepUserRolePojo userOrDep : userOrDeps) {
            log.info("查询角色权限 - 角色ID: {}", userOrDep.getRoleId());
            List<MenuParamView> views = selectPersByRole(userOrDep.getRoleId());
            log.info("角色 {} 的权限数量: {}", userOrDep.getRoleId(), views.size());
            if (ObjectUtils.isNotEmpty(views)) {
                paramViews.addAll(views);
            }
        }
        
        log.info("用户总权限数量: {}", paramViews.size());
        return paramViews;
    }

    /**
     * 根据角色查询权限
     * 根据角色ID查询权限信息
     *
     * @param roleID 角色ID
     * @return 菜单参数视图列表
     */
    @Override
    public List<MenuParamView> selectPersByRole(String roleID) {
        log.info("查询角色权限 - 角色ID: {}", roleID);
        
        if (ObjectUtils.isEmpty(roleID)) {
            throw new CommonException("角色为空");
        }
        ModelRolesPojo modelRolesPojos = businessDatabase.getBusinessDatabase()
                .eq("is_enabled", 1)
                .eq("id", roleID)
                .doQueryFirst(ModelRolesPojo.class);
        
        if (ObjectUtils.isEmpty(modelRolesPojos)) {
            log.warn("角色不存在或未启用 - 角色ID: {}", roleID);
            return Collections.emptyList();
        }
        
        if ("super_admin".equals(modelRolesPojos.getRoleCode())) {
            log.info("角色是超级管理员 - 角色ID: {}", roleID);
            return Collections.singletonList(new MenuParamView(roleID, "", "", "", "", 1));
        }
        
        ArrayList<MenuParamView> menuParamViews = new ArrayList<>();
        List<ModelRolePermissionPojo> role = businessDatabase.getBusinessDatabase()
                .eq("role_id", roleID)
                .eq("is_enable", 1)
                .doQuery(ModelRolePermissionPojo.class);
        
        if (ObjectUtils.isEmpty(role)) {
            log.warn("角色没有配置权限 - 角色ID: {}", roleID);
            return Collections.emptyList();
        }
        
        log.info("角色配置的权限数量: {}", role.size());
        
        try {
            List<String> perids = role.stream().map(ModelRolePermissionPojo::getPerId).distinct().collect(Collectors.toList());
            List<ModelMenuParameterPojo> menuParameters = businessDatabase.getBusinessDatabase()
                    .in("id", perids)
                    .doQuery(ModelMenuParameterPojo.class);
            
            log.info("查询到的权限配置数量: {}", menuParameters.size());
            
            //获取权限
            for (ModelMenuParameterPojo menuParameter : menuParameters) {
                ParamPermissionEnum byCode = ParamPermissionEnum.getByCode(menuParameter.getParameterPer());
                if (byCode == null) {
                    log.warn("权限配置异常 - 权限ID: {}, 权限等级: {}, 跳过该权限", 
                            menuParameter.getId(), menuParameter.getParameterPer());
                    continue;
                }
                MenuParamView menuParamView = new MenuParamView();
                menuParamView.setId(menuParameter.getId());
                menuParamView.setPermissionPath(menuParameter.getPermissionPath());
                menuParamView.setParameterPer(byCode.getDesc());
                menuParamViews.add(menuParamView);
                
                log.debug("添加权限 - 路径: {}, 等级: {}", menuParameter.getPermissionPath(), byCode.getDesc());
            }
        } catch (Exception e) {
            log.error("查询角色权限异常: {}", e.getMessage(), e);
            return Collections.emptyList();
        }

        log.info("角色有效权限数量: {}", menuParamViews.size());
        return menuParamViews;
    }

    /**
     * 删除角色
     * 根据角色ID和用户ID删除角色
     *
     * @param roleID 角色ID
     * @param userID 用户ID
     */
    @Override
    @Transactional
    public void removeRoles(String roleID, String userID) {
        if (ObjectUtils.isEmpty(roleID)) {
            throw new CommonException("删除的角色为空");
        }
        businessDatabase.getBusinessDatabase()
                .update("is_enabled", 0)
                .update("last_updated_by", userID)
                .update("last_update_date", new Date())
                .eq("id", roleID)
                .doUpdate(ModelRolesPojo.class);
        businessDatabase.getBusinessDatabase()
                .update("is_enable", 0)
                .update("last_updated_by", userID)
                .update("last_update_date", new Date())
                .eq("role_id", roleID)
                .doUpdate(ModelRolePermissionPojo.class);

    }

    private static List<String> processPermissions(List<String> perms) {
        if (perms == null || perms.isEmpty()) {
            return new ArrayList<>();
        }

        class PathInfo {
            final String pathWithoutTrailingSlash;
            final boolean hasTrailingSlash;

            PathInfo(String originalPath) {
                this.hasTrailingSlash = originalPath.endsWith("/");
                this.pathWithoutTrailingSlash = hasTrailingSlash ? originalPath.substring(0, originalPath.length() - 1) : originalPath;
            }

            String getOriginalPath() {
                return pathWithoutTrailingSlash + (hasTrailingSlash ? "/" : "");
            }
        }

        List<PathInfo> pathInfos = perms.stream()
                .filter(Objects::nonNull)
                .map(PathInfo::new)
                .collect(Collectors.toList());

        Set<String> permSetWithoutTrailingSlash = pathInfos.stream()
                .map(info -> info.pathWithoutTrailingSlash)
                .collect(Collectors.toSet());

        List<PathInfo> filteredPathInfos = pathInfos.stream()
                .filter(info -> {
                    String currentPath = info.pathWithoutTrailingSlash;
                    int lastSlashIndex = currentPath.lastIndexOf('/');
                    if (lastSlashIndex > 0) {
                        String parentPath = currentPath.substring(0, lastSlashIndex);
                        return !permSetWithoutTrailingSlash.contains(parentPath);
                    }
                    return true;
                })
                .collect(Collectors.toList());

        Map<String, List<PathInfo>> groupedByParent = filteredPathInfos.stream()
                .filter(info -> info.pathWithoutTrailingSlash.indexOf('/') >= 0)
                .collect(Collectors.groupingBy(info -> {
                    String path = info.pathWithoutTrailingSlash;
                    int lastSlashIndex = path.lastIndexOf('/');
                    return path.substring(0, lastSlashIndex);
                }));

        List<String> topLevelPerms = filteredPathInfos.stream()
                .filter(info -> info.pathWithoutTrailingSlash.indexOf('/') < 0)
                .map(info -> {
                    String formattedPath = info.pathWithoutTrailingSlash.replace('/', '-');
                    return formattedPath + (info.hasTrailingSlash ? "/" : "");
                })
                .collect(Collectors.toList());

        List<String> result = new ArrayList<>();

        for (Map.Entry<String, List<PathInfo>> groupEntry : groupedByParent.entrySet()) {
            String parentPath = groupEntry.getKey();
            List<PathInfo> childInfos = groupEntry.getValue();

            boolean anyHasTrailingSlash = childInfos.stream().anyMatch(info -> info.hasTrailingSlash);

            List<String> leafNames = childInfos.stream()
                    .filter(info -> !info.hasTrailingSlash)
                    .map(info -> {
                        String path = info.pathWithoutTrailingSlash;
                        int lastSlashIndex = path.lastIndexOf('/');
                        return path.substring(lastSlashIndex + 1);
                    })
                    .collect(Collectors.toList());

            String formattedParentPath = parentPath.replace('/', '-');

            String finalPermString;
            if (anyHasTrailingSlash) {
                finalPermString = formattedParentPath + "/";
            } else {
                if (!leafNames.isEmpty()) {
                    String joinedLeafNames = String.join("、", leafNames);
                    finalPermString = formattedParentPath + "-" + joinedLeafNames;
                } else {
                    finalPermString = formattedParentPath + "/";
                }
            }
            result.add(finalPermString);
        }

        result.addAll(topLevelPerms);

        Collections.sort(result);

        return result;
    }

    private static RoleInfoView getRoleInfoView(Map.Entry<String, List<RoleInfoView>> entry) {
        List<RoleInfoView> views = entry.getValue();

        if (views == null || views.isEmpty()) {
            return null;
        }

        RoleInfoView firstView = views.get(0);

        List<String> allEditPerms = views.stream()
                .map(RoleInfoView::getEditPerms)
                .filter(p -> p != null && !p.isEmpty())
                .collect(Collectors.toList());

        List<String> allQueryPerms = views.stream()
                .map(RoleInfoView::getQueryPerms)
                .filter(p -> p != null && !p.isEmpty())
                .collect(Collectors.toList());

        List<String> processedEditPerms = processPermissions(allEditPerms);
        List<String> processedQueryPerms = processPermissions(allQueryPerms);

        String combinedEditPerms = String.join(",\n", processedEditPerms);
        String combinedQueryPerms = String.join(",\n", processedQueryPerms);

        firstView.setEditPerms(combinedEditPerms);
        firstView.setQueryPerms(combinedQueryPerms);

        return firstView;
    }

    /**
     * 用户角色绑定
     * 将用户或部门与角色进行绑定
     *
     * @param request 用户角色绑定请求
     */
    @Override
    @Transactional
    public void userRoleBinding(UserRoleBindingRequest request) {
        // 更新用户
        modelRoleService.updateUserRole(request, 0);
        // 更新部门
        modelRoleService.updateUserRole(request, 1);

    }

    /**
     * 根据角色查询用户或部门
     * 根据角色ID查询关联的用户或部门信息
     *
     * @param roleID 角色ID
     * @return 用户或部门信息映射
     */
    @Override
    public HashMap<String, List<String>> selectUserOrDeptByRole(String roleID) {
        if (ObjectUtils.isEmpty(roleID)) {
            return new HashMap<>();
        }
        List<ModelDepUserRolePojo> modelDepUserRolePojos = businessDatabase.getBusinessDatabase()
                .eq("role_id", roleID)
                .eq("is_enable", 1)
                .doQuery(ModelDepUserRolePojo.class);
        HashMap<String, List<String>> map = new HashMap<>();
        if (ObjectUtils.isNotEmpty(modelDepUserRolePojos)) {
            List<ModelDepUserRolePojo> deptList = modelDepUserRolePojos.stream().filter(x -> x.getIsDep() == 1).collect(Collectors.toList());
            List<ModelDepUserRolePojo> userList = modelDepUserRolePojos.stream().filter(x -> x.getIsDep() == 0).collect(Collectors.toList());
            ArrayList<String> stringsDept = new ArrayList<>();
            ArrayList<String> stringsUser = new ArrayList<>();
            for (ModelDepUserRolePojo userRolePojo : deptList) {
                String depId = userRolePojo.getUserOrDep();
                XdapDepartments xdapDepartments = xdapDeptUsersService.selectDeptByID(depId);
                if (ObjectUtils.isEmpty(xdapDepartments)) {
                    stringsDept.add("未知部门:" + depId);
                } else {
                    stringsDept.add(xdapDepartments.getName() + "-ID:" + depId);
                }
            }
            map.put("部门", stringsDept);
            for (ModelDepUserRolePojo userRolePojo : userList) {
                String userId = userRolePojo.getUserOrDep();
                XdapUsers xdapUsers = xdapDeptUsersService.selectUserByID(userId);
                if (ObjectUtils.isEmpty(xdapUsers)) {
                    stringsUser.add("未知人员:" + userId);
                } else {
                    stringsUser.add(xdapUsers.getUsername() + "-ID:" + userId);
                }
            }
            map.put("人员", stringsUser);
            return map;
        }
        return new HashMap<>();
    }

    @Override
    public boolean matchesAnyPermission(
            EngineParamDetailPojo pojo,
            Map<String, Map<String, Set<String>>> permissionIndex,
            String cat
    ) {
        String sys = pojo.getSubsystemName();
        String comp = Optional.ofNullable(pojo.getPartsName()).orElse("/");

        Map<String, Set<String>> sysMap = permissionIndex.get(cat);
        if (sysMap == null) {
            return false;
        }

        // 1. 检查是否有 cat/*/* （即 parts.length == 1）
        if (sysMap.containsKey("*")) {
            return true;
        }

        // 2. 检查是否有 cat/sys/* （即 parts.length == 2）
        Set<String> compSet = sysMap.get(sys);
        if (compSet != null) {
            if (compSet.contains("*")) {
                return true;
            }
            return compSet.contains(comp);
        }
        return false;
    }

    @Override
    public boolean matchesAnyPermission(EngineParamDetailPojo pojo, Map<String, Map<String, Set<String>>> permissionIndex, List<String> cats) {
        String sys = pojo.getSubsystemName();
        String comp = Optional.ofNullable(pojo.getPartsName()).orElse("/");

        for (String cat : cats) {
            Map<String, Set<String>> sysMap = permissionIndex.get(cat);
            if (sysMap == null) {
                continue;
            }

            if (sysMap.containsKey("*")) {
                return true;
            }

            Set<String> compSet = sysMap.get(sys);
            if (compSet != null) {
                if (compSet.contains("*")) {
                    return true;
                }
                if (compSet.contains(comp)) {
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    public boolean matchesAnyPermission(
            ParameterPojo pojo,
            Map<String, Map<String, Set<String>>> permissionIndex,
            List<String> cats
    ) {
        String sys = pojo.getSubsystemName();
        String comp = Optional.ofNullable(pojo.getPartsName()).orElse("/");

        for (String cat : cats) {
            Map<String, Set<String>> sysMap = permissionIndex.get(cat);
            if (sysMap == null) {
                continue;
            }

            if (sysMap.containsKey("*")) {
                return true;
            }

            Set<String> compSet = sysMap.get(sys);
            if (compSet != null) {
                if (compSet.contains("*")) {
                    return true;
                }
                if (compSet.contains(comp)) {
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    public Map<String, Map<String, Set<String>>> buildPermissionIndex(
            Set<String> permissions
    ) {
        Map<String, Map<String, Set<String>>> index = new HashMap<>();

        for (String perm : permissions) {
            String[] parts = perm.split("/", -1);
            String cat, sys, comp;

            if (parts.length == 1) {
                cat = parts[0];
                sys = "*"; // 表示通配
                comp = "*";
            } else if (parts.length == 2) {
                cat = parts[0];
                sys = parts[1];
                comp = "*";
            } else if (parts.length == 3) {
                cat = parts[0];
                sys = parts[1];
                comp = parts[2];
            } else if (parts.length == 4 && parts[3].isEmpty()) {
                // "cat/sys//" → comp 应视为 "/"
                cat = parts[0];
                sys = parts[1];
                comp = "/";
            } else {
                // 非法格式，跳过或记录日志
                continue;
            }

            index.computeIfAbsent(cat, k -> new HashMap<>())
                    .computeIfAbsent(sys, k -> new HashSet<>())
                    .add(comp);
        }
        return index;
    }

    @Override
    public void updateUserRole(UserRoleBindingRequest request, int isDept) {
        String roleId = request.getRoleId();
        // 获取目前已绑定的id
        List<String> userOrDepartRoleIds = new ArrayList<>();
        List<ModelDepUserRolePojo> userOrDepartRoles = businessDatabase.getBusinessDatabase()
                .eq("is_enable", 1)
                .eq("role_id", roleId)
                .eq("is_dep", isDept)
                .doQuery(ModelDepUserRolePojo.class);
        if (!userOrDepartRoles.isEmpty()) {
            userOrDepartRoleIds.addAll(userOrDepartRoles.stream().map(ModelDepUserRolePojo::getUserOrDep).collect(Collectors.toList()));
        }

        // 获取传入的用户id
        List<UserRoleBindingItem> userRolesReq = request.getUserOrDept().stream()
                .filter(item -> item.getIsDept() == isDept)
                .collect(Collectors.toList());

        // 找出需要需要禁用和新增的用户id
        List<String> userToAdd = new ArrayList<>();
        for (UserRoleBindingItem item : userRolesReq) {
            if (userOrDepartRoleIds.contains(item.getUserOrDeptId())) {
                userOrDepartRoleIds.remove(item.getUserOrDeptId());
            } else {
                userToAdd.add(item.getUserOrDeptId());
            }
        }

        // 更新用户
        if (!userOrDepartRoleIds.isEmpty()) {
            businessDatabase.getBusinessDatabase()
                    .in("user_or_dep", userOrDepartRoleIds)
                    .eq("is_dep", isDept)
                    .update("is_enable", 0)
                    .eq("role_id", roleId)
                    .doUpdate(ModelDepUserRolePojo.class);
        }

        // 新增用户
        if (!userToAdd.isEmpty()) {
            for (String userOrDeptId : userToAdd) {
                // 检查当前用户是否已经被禁用
                ModelDepUserRolePojo unableUser = businessDatabase.getBusinessDatabase()
                        .eq("user_or_dep", userOrDeptId)
                        .eq("is_enable", 0)
                        .eq("role_id", roleId)
                        .eq("is_dep", isDept)
                        .doQueryFirst(ModelDepUserRolePojo.class);
                if (unableUser == null) {
                    ModelDepUserRolePojo modelDepUserRolePojo = new ModelDepUserRolePojo();
                    modelDepUserRolePojo.setRoleId(roleId);
                    modelDepUserRolePojo.setUserOrDep(userOrDeptId);
                    modelDepUserRolePojo.setIsEnable(1);
                    modelDepUserRolePojo.setIsDep(isDept);
                    modelDepUserRolePojo.setCreationDate(new Date());
                    businessDatabase.getBusinessDatabase()
                            .doInsert(modelDepUserRolePojo);
                } else {
                    businessDatabase.getBusinessDatabase()
                            .eq("id", unableUser.getId())
                            .update("is_enable", 1)
                            .doUpdate(ModelDepUserRolePojo.class);
                }
            }
        }
    }

    @Override
    public void writePreAndRole(HttpServletResponse response) {
        String fileName = "系统权限导出_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        try {
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", 0);

            PreAndRolePageRequest request = new PreAndRolePageRequest();
            List<RoleInfoView> result = modelRoleService.getPerAndRole(request);

            EasyExcel.write(response.getOutputStream(), RoleInfoView.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .sheet("系统权限")
                    .doWrite(result);

        } catch (Exception e) {
            throw new CommonException("导出Excel失败: " + e.getMessage());
        }

    }

    @Override
    public PageResultDTO<RoleInfoView> getPreAndRoleByCondition(PreAndRolePageRequest request) {
        List<RoleInfoView> result = modelRoleService.getPerAndRole(request);
        PageResultDTO<RoleInfoView> page = new PageResultDTO<>();
        if (result.isEmpty()) {
            page.setTotalCount(0);
            page.setList(new ArrayList<>());
            return page;
        }

        int totalElements = result.size();
        int totalPages = (int) Math.ceil((double) totalElements / request.getPageSize());
        if (request.getPageNum() > totalPages) {
            request.setPageNum(totalPages);
        }
        int fromIndex = (request.getPageNum() - 1) * request.getPageSize();
        int toIndex = Math.min(fromIndex + request.getPageSize(), totalElements);

        List<RoleInfoView> finalResult = new ArrayList<>(result.subList(fromIndex, toIndex));
        page.setList(finalResult);
        page.setTotalCount(result.size());

        return page;
    }

    @Override
    public List<RoleInfoView> getPerAndRole(PreAndRolePageRequest request) {
        Set<String> deptOrUsers = new HashSet<>();
        List<UserDeptItem> userDeparts = new ArrayList<>();
        // 按用户名查询
        if (!request.getUsername().isEmpty()) {
            List<XdapUsers> xdapUsers = businessDatabase.getSystemDatabase()
                    .like("username", request.getUsername())
                    .doQuery(XdapUsers.class);
            if (!xdapUsers.isEmpty()) {
                deptOrUsers.addAll(
                        xdapUsers.stream().map(XdapUsers::getId).collect(Collectors.toList())
                );
                xdapUsers.forEach(user -> {
                    UserDeptItem item = new UserDeptItem();
                    item.setUsername(user.getUsername());
                    List<XdapDeptUsers> deptUsers = businessDatabase.getSystemDatabase()
                            .eq("user_id", user.getId())
                            .doQuery(XdapDeptUsers.class);
                    if (!deptUsers.isEmpty()) {
                        deptOrUsers.addAll(
                                deptUsers.stream().map(XdapDeptUsers::getDepartmentId).collect(Collectors.toList())
                        );
                        item.setDepartmentIds(deptUsers.stream().map(XdapDeptUsers::getDepartmentId).collect(Collectors.toList()));
                    }
                    userDeparts.add(item);
                });
            }
        }

        // 按部门名查询
        if (!request.getDepartment().isEmpty()) {
            List<XdapDepartments> xdapDepartments = businessDatabase.getSystemDatabase()
                    .like("name", request.getDepartment())
                    .doQuery(XdapDepartments.class);
            if (!xdapDepartments.isEmpty()) {
                deptOrUsers.addAll(
                        xdapDepartments.stream().map(XdapDepartments::getId).collect(Collectors.toSet())
                );
            }
        }

        // 查询所有用户的角色和权限
        List<RoleAndPreView> roleAndPreViews = new ArrayList<>();
        MpaasQuery query = businessDatabase.getBusinessDatabase()
                .viewQueryMode(true)
                .view("selectRoleAndPerInfo")
                .like("role_name", request.getRoleName());
        // 根据部门名和用户名查角色
        if (!deptOrUsers.isEmpty()) {
            query.in("userOrDep", deptOrUsers);
            roleAndPreViews.addAll(
                    query.doQuery(RoleAndPreView.class)
            );
        } else {
            if (request.getUsername().isEmpty() && request.getDepartment().isEmpty()) {
                roleAndPreViews.addAll(
                        query.doQuery(RoleAndPreView.class)
                );
            }
        }

        // 查询用户和部门并构建临时返回
        List<RoleInfoView> resultTemp = new ArrayList<>();
        roleAndPreViews.forEach(roleAndPreView -> {
            RoleInfoView view = new RoleInfoView();
            if (roleAndPreView.getIsDep() == 0) {
                XdapUsers user = businessDatabase.getSystemDatabase()
                        .eq("id", roleAndPreView.getUserOrDep())
                        .doQueryFirst(XdapUsers.class);
                if (user == null) {
                    view.setUsername("未知用户-" + roleAndPreView.getUserOrDep());
                } else {
                    view.setUsername(user.getUsername());
                    view.setUserNumber(user.getUserNumber());
                    view.setUserId(user.getId());
                }
            } else if (roleAndPreView.getIsDep() == 1) {
                XdapDepartments department = businessDatabase.getSystemDatabase()
                        .eq("id", roleAndPreView.getUserOrDep())
                        .doQueryFirst(XdapDepartments.class);
                if (department == null) {
                    view.setDepartment("未知部门-" + roleAndPreView.getUserOrDep());
                } else {
                    view.setDepartment(department.getName());
                    view.setDepartmentId(department.getId());
                    if (!userDeparts.isEmpty()) {
                        String usernames = userDeparts.stream()
                                .filter(userDepart -> userDepart.getDepartmentIds() != null)
                                .filter(userDepart -> userDepart.getDepartmentIds().contains(department.getId()))
                                .map(UserDeptItem::getUsername)
                                .collect(Collectors.joining("、"));
                        view.setUsername(usernames);
                    }
                }
            }

            view.setRoleId(roleAndPreView.getRoleId());
            view.setRoleName(roleAndPreView.getRoleName());
            view.setRoleDescription(roleAndPreView.getRoleDescription());

            if (roleAndPreView.getParameterPer() != null) {
                if (roleAndPreView.getParameterPer() == 1) {
                    view.setQueryPerms(roleAndPreView.getPermissionPath());
                } else if (roleAndPreView.getParameterPer() == 2) {
                    view.setEditPerms(roleAndPreView.getPermissionPath());
                }
            }

            resultTemp.add(view);
        });

        // 构建聚合返回
        List<RoleInfoView> result = new ArrayList<>();
        Map<String, List<RoleInfoView>> userGroup = resultTemp.stream()
                .filter(item ->
                        item.getUserId() != null && !item.getUserId().isEmpty())
                .collect(Collectors.groupingBy(item -> item.getRoleId() + "_" + item.getUserId()));

        Map<String, List<RoleInfoView>> deptGroup = resultTemp.stream()
                .filter(item ->
                        item.getDepartmentId() != null && !item.getDepartmentId().isEmpty())
                .collect(Collectors.groupingBy(item -> item.getRoleId() + "_" + item.getDepartmentId()));

        for (Map.Entry<String, List<RoleInfoView>> entry : userGroup.entrySet()) {
            RoleInfoView view = getRoleInfoView(entry);
            result.add(view);
        }

        for (Map.Entry<String, List<RoleInfoView>> entry : deptGroup.entrySet()) {
            RoleInfoView view = getRoleInfoView(entry);
            result.add(view);
        }

        if (result.isEmpty()) {
            return new ArrayList<>();
        }

        result.forEach(item -> {
            if (Objects.equals(item.getRoleName(), "超级管理员")) {
                item.setEditPerms("全部权限");
                item.setQueryPerms("全部权限");
            }
        });


        result.sort(Comparator.comparing(RoleInfoView::getRoleName, Collator.getInstance(Locale.CHINESE)));

        return result;
    }
}
