package com.fastbee.project.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.fastbee.common.constant.DepartmentAdministrationLevelConstant;
import com.fastbee.common.constant.ProjectLevelConstant;
import com.fastbee.common.core.domain.entity.SysDept;
import com.fastbee.common.core.domain.entity.SysMenu;
import com.fastbee.common.core.domain.entity.SysRole;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.holder.ProjectHolder;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.json.JsonStrUtil;
import com.fastbee.iot.model.RegisterUserInput;
import com.fastbee.iot.model.RegisterUserOutput;
import com.fastbee.iot.service.IToolService;
import com.fastbee.project.domain.Project;
import com.fastbee.project.domain.vo.ProjectLoginBaseInfo;
import com.fastbee.project.mapper.ProjectMapper;
import com.fastbee.project.service.IProjectService;
import com.fastbee.system.domain.SysDistrict;
import com.fastbee.system.mapper.SysDeptMapper;
import com.fastbee.system.mapper.SysDistrictMapper;
import com.fastbee.system.mapper.SysUserMapper;
import com.fastbee.system.service.ISysDeptService;
import com.fastbee.system.service.ISysMenuService;
import com.fastbee.system.service.ISysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目Service业务层处理
 * @author kerwincui
 * &#064;date  2024-09-26
 */
@Service
public class ProjectServiceImpl implements IProjectService
{

        private final ProjectMapper projectMapper;
        private final SysDeptMapper sysDeptMapper;
        private final SysUserMapper sysUserMapper;

        private final SysDistrictMapper sysDistrictMapper;

        private final ISysMenuService sysMenuService;

        private final ISysRoleService sysRoleService;

        private final ISysDeptService deptService;
        private final IToolService toolService;

        public ProjectServiceImpl(ProjectMapper projectMapper, SysDeptMapper sysDeptMapper, SysUserMapper sysUserMapper, SysDistrictMapper sysDistrictMapper, ISysMenuService sysMenuService, ISysRoleService sysRoleService, ISysDeptService deptService, IToolService toolService) {
                this.projectMapper = projectMapper;
                this.sysDeptMapper = sysDeptMapper;
                this.sysUserMapper = sysUserMapper;
                this.sysDistrictMapper = sysDistrictMapper;
                this.sysMenuService = sysMenuService;
                this.sysRoleService = sysRoleService;
                this.deptService = deptService;
                this.toolService = toolService;
        }


        /**
         * 根据主键查询项目
         *
         * @param projectId 项目主键
         * @return 项目
         */
        @Override
        public Project selectProjectByProjectId(Long projectId)
        {       //查询项目信息
                List<Project> projectList = new LambdaQueryChainWrapper<>(projectMapper)
                        .select(Project::getProjectName, Project::getSysShowName, Project::getCentralCoordinates, Project::getScope,
                                Project::getAdministrativeAreaCode, Project::getLevel, Project::getDeptId, Project::getDeptName,
                                Project::getVideoIntroduction, Project::getImage, Project::getLogo, Project::getRemark)
                        .eq(Project::getId, projectId)
                        .eq(Project::getDelFlag,0)
                        .list();
                //查询项目管理员信息
                List<SysUser> list = new LambdaQueryChainWrapper<>(sysUserMapper)
                        .select(SysUser::getUserId, SysUser::getUserName, SysUser::getPhonenumber)
                        .eq(SysUser::getDeptId, projectList.get(0).getDeptId())
                        .list();

                if(projectList.isEmpty()){
                        throw new ServiceException("项目不存在!");
                }
                if(list.isEmpty()){
                        throw new ServiceException("项目机构管理员不存在!");
                }
                Project project = projectList.get(0);
                project.setUserName(list.get(0).getUserName());
                project.setPhoneNumber(list.get(0).getPhonenumber());

                return project;
        }

        /**
         * 查询项目列表
         */
        @Override
        public List<Project> selectProjectList(Project project)
        {
                return  new LambdaQueryChainWrapper<>(projectMapper)
                        .select(Project::getId, Project::getProjectName, Project::getScope,
                                Project::getDeptId,
                                Project::getLogo, Project::getImage, Project::getLevel, Project::getDeptName,
                                Project::getCreateTime,
                                Project::getAdministrativeAreaCode,Project::getAdministrativeArea, Project::getProvinceCode,Project::getCityCode,Project::getCountyCode)
                        .eq(Project::getDelFlag,0)
                        .like(StringUtils.isNotBlank(project.getSearchValue()),Project::getProjectName, project.getSearchValue())
                        .list();
        }

        /**
         * 新增项目
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public int insertProject(Project project)
        {
                //TODO 参数校验
                //获取当前时间
                Date nowDate = DateUtils.getNowDate();
                //处理项目行政区划
                parseAdministrativeDivisionInfo(project);
                //给项目分配一个机构--------------------------------------------------------
                SysDept newSysDept = new SysDept();
                //设置上级机构id
                newSysDept.setParentId(100L);
                //设置祖级列表
                newSysDept.setAncestors("0,100");
                //设置创建时间
                newSysDept.setCreateTime(nowDate);
                //设置默认机构名称
                newSysDept.setDeptName(project.getProjectName());
                //设置默认机构类型
                newSysDept.setDeptType(3);
                //设置机构领导
                newSysDept.setLeader("hanzhen");
                //设置默认的机构行政级别
                newSysDept.setAdministrativeLevel(3);
                //设置机构所属项目id


                //设置机构型行政区域信息
                newSysDept.setAdministrativeAreaCode(Objects.nonNull(project.getAdministrativeAreaCode())?project.getAdministrativeAreaCode():null);
                newSysDept.setAdministrativeArea(Objects.nonNull(project.getAdministrativeArea())?project.getAdministrativeArea():null);
                newSysDept.setProvinceCode(Objects.nonNull(project.getProvinceCode())?project.getProvinceCode():null);
                newSysDept.setCityCode(Objects.nonNull(project.getCityCode())?project.getCityCode():null);
                newSysDept.setCountyCode(Objects.nonNull(project.getCountyCode())?project.getCountyCode():null);
                newSysDept.setTownCode(Objects.nonNull(project.getTownCode())?project.getTownCode():null);
                newSysDept.setVillageCode(Objects.nonNull(project.getVillageCode())?project.getVillageCode():null);

                if(sysDeptMapper.insertDept(newSysDept)<1){
                        throw new ServiceException("创建默认机构失败！");
                }
                // 新增机构关联系统账号
                        // 添加管理员角色，给基本权限
                        SysDept sysDept = deptService.selectDeptById(100L);
                        List<SysMenu> sysMenuList = sysMenuService.selectMenuList(new SysMenu(), sysDept.getDeptUserId());
                        Long[] menuIdList = sysMenuList.stream().map(SysMenu::getMenuId)
                                .filter(menuId-> menuId!=3469L&&menuId!=3L&&menuId!=2L &&menuId!=3468L&&menuId!=102L)
                                .toArray(Long[]::new);
                        SysRole sysRole = new SysRole();
                        sysRole.setRoleName("管理员");
                        sysRole.setRoleKey("manager");
                        sysRole.setRoleSort(1);
                        sysRole.setStatus("0");
                        sysRole.setDeptId(newSysDept.getDeptId());
                        sysRole.setMenuIds(menuIdList);
                        sysRoleService.insertRole(sysRole);

                        // 注册机构管理员用户
                        RegisterUserInput registerUserInput = new RegisterUserInput();
                        registerUserInput.setUsername(project.getUserName());
                        registerUserInput.setPassword(project.getPassword());
                        registerUserInput.setPhonenumber(project.getPhoneNumber());
                        registerUserInput.setDeptId(newSysDept.getDeptId());
                        registerUserInput.setRoleIds(new Long[]{sysRole.getRoleId()});
                        RegisterUserOutput registerUserOutput = toolService.registerNoCaptcha(registerUserInput);
                        if (com.fastbee.common.utils.StringUtils.isNotEmpty(registerUserOutput.getMsg())) {
                                deptService.deleteDeptById(newSysDept.getDeptId());
                                sysRoleService.deleteRoleById(sysRole.getRoleId());
                                throw new ServiceException(registerUserOutput.getMsg());
                        }
                        // 更新机构管理员角色绑定信息
                        deptService.updateDeptUserId(newSysDept.getDeptId(), registerUserOutput.getSysUserId());

                project.setDeptId(newSysDept.getDeptId());
                project.setDeptName(project.getProjectName());
                project.setCreateTime(DateUtils.getNowDate());
                if(projectMapper.insertProject(project)<1){
                        throw new ServiceException("项目创建失败！");
                }
                boolean updatedSysDept = new LambdaUpdateChainWrapper<>(sysDeptMapper)
                        .set(SysDept::getProjectId, project.getId())
                        .eq(SysDept::getDeptId, newSysDept.getDeptId())
                        .update();
                if(!updatedSysDept){
                        throw new ServiceException("机构与项目关联失败！");
                }
                return 1;
        }

        /**
         * 解析项目行政区划信息
         * @param project 项目
         */
        private void parseAdministrativeDivisionInfo(Project project) {
                //项目行政区域处理
                //拆解项目行政区域代码信息
                if(StringUtils.isBlank(project.getAdministrativeAreaCode())){
                        throw new ServiceException("项目行政区域代码不能为空！");
                }
                //判断行政区域代码json格式
                if(!JsonStrUtil.isJsonArray(project.getAdministrativeAreaCode())){
                        throw new ServiceException("项目行政区域代码多选列表非json数组！");
                }
                //项目省代码列表
                List<String> provincialCodeList =new ArrayList<>();
                //项目市代码列表
                List<String> cityCodeList =new ArrayList<>();
                //项目县代码列表
                List<String> countyCodeList =new ArrayList<>();
                //项目镇代码列表
                List<String> townCodeList =new ArrayList<>();
                //项目村代码列表
                List<String> villageCodeList =new ArrayList<>();
                JSONArray administrativeAreaList = JSONUtil.parseArray(project.getAdministrativeAreaCode());
                administrativeAreaList.forEach(item->{
                        if(!JsonStrUtil.isJsonArray(item.toString())){
                                throw new ServiceException("项目行政区域代码多选列表的元素非json数组！");
                        }
                        //单个行政区划代码列表
                        JSONArray administrativeArea = JSONUtil.parseArray(item);
                        //拆解出每个行政区划代码里面的镇或村
//                         if(administrativeArea.size()!=5){
//                                 throw new ServiceException("项目行政区域代码多选列表的元素长度必须为5，到达村级别！");
//                         }
                         //保存项目省代码列表
                         provincialCodeList.add(administrativeArea.get(0).toString());
                         //保存项目市代码列表
                         cityCodeList.add(administrativeArea.get(1).toString());
                         //保存项目县代码列表
                         countyCodeList.add(administrativeArea.get(2).toString());

                         if(administrativeArea.size()>=4){
                                 //保存项目镇代码列表
                                 townCodeList.add(administrativeArea.get(3).toString());
                         }
                         if(administrativeArea.size()>=5){
                                 //保存项目村代码列表
                                 villageCodeList.add(administrativeArea.get(4).toString());
                         }

                });

                //设置项目省、市、县、镇、村行政区划代码列表
                project.setProvinceCode(JSONUtil.toJsonStr(provincialCodeList));
                project.setCityCode(JSONUtil.toJsonStr(cityCodeList));
                project.setCountyCode(JSONUtil.toJsonStr(countyCodeList));
                project.setTownCode(JSONUtil.toJsonStr(townCodeList));
                project.setVillageCode(JSONUtil.toJsonStr(villageCodeList));
        }



        /**
         * 修改项目
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public int updateProject(Project project)
        {
                //判断选择的机构下是否已经绑定项目
                Project one = new LambdaQueryChainWrapper<>(projectMapper)
                        .select(Project::getId, Project::getProjectName,Project::getDeptId)
                        .eq(Project::getDeptId, project.getDeptId())
//                        .ne(Project::getId,project.getId())
                        .one();
                if(Objects.isNull(one)){
                        throw new ServiceException("项目不存在！");
                }
                if(!one.getDeptId().equals(project.getDeptId())){
                        throw new ServiceException("非法修改项目机构！");
                }
                project.setUpdateTime(DateUtils.getNowDate());
                //处理项目行政区划
                parseAdministrativeDivisionInfo(project);
                //同步更新项目所属最顶级部门行政区划数据
                boolean updateDept = new LambdaUpdateChainWrapper<>(sysDeptMapper)
                        .set(SysDept::getAdministrativeAreaCode, project.getAdministrativeAreaCode())
                        .set(SysDept::getProvinceCode, project.getProvinceCode())
                        .set(SysDept::getCityCode, project.getCityCode())
                        .set(SysDept::getCountyCode, project.getCountyCode())
                        .set(SysDept::getTownCode, project.getTownCode())
                        .set(SysDept::getVillageCode, project.getVillageCode())
                        .eq(SysDept::getDeptId, project.getDeptId())
                        .update();
                if(!updateDept){
                        throw new ServiceException("同步更新项目所属最顶级部门行政区划数据失败！");
                }
                int updateProject = projectMapper.updateProject(project);
                if(updateProject <1 ){
                        throw new ServiceException("修改项目失败！");
                }
                return 1;
        }

        /**
         * 删除项目
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public int deleteProjectByProjectIds(Long projectId)
        {       //逻辑删除项目信息
                boolean updateProject = new LambdaUpdateChainWrapper<>(projectMapper)
                        .set(Project::getDelFlag, "2")
                        .eq(Project::getId, projectId)
                        .update();
                //查询项目下的机构
                List<SysDept> projectDeptList = new LambdaQueryChainWrapper<>(sysDeptMapper)
                        .select(SysDept::getDeptId)
                        .eq(SysDept::getProjectId, projectId)
                        .eq(SysDept::getDelFlag, "0")
                        .list();
                //逻辑删除项目机构信息
                boolean updateDept = new LambdaUpdateChainWrapper<>(sysDeptMapper)
                        .set(SysDept::getDelFlag, "2")
                        .eq(SysDept::getProjectId, projectId)
                        .update();
                //逻辑删除项目用户信息
                boolean updateUser=false;
                LambdaUpdateChainWrapper<SysUser> sysUserLambdaUpdateChainWrapper = new LambdaUpdateChainWrapper<>(sysUserMapper);
                sysUserLambdaUpdateChainWrapper
                        .set(SysUser::getDelFlag, "2");
                if(!projectDeptList.isEmpty()){
                        updateUser = sysUserLambdaUpdateChainWrapper.in(SysUser::getDeptId, projectDeptList.stream().map(SysDept::getDeptId).collect(Collectors.toList()))
                                .update();

                }

                return updateDept&&updateProject&&updateUser?1:0;
        }


        /**
         * 获取项目的一些基本信息
         * 获取管理员所管理的项目id以及子项目id列表，行政区划等
         */
        @Override
        public ProjectLoginBaseInfo selectProjectByUserId(Long userId) {
                //TODO 优化为连表查
                //查询用户所属机构
                SysUser sysUser = new LambdaQueryChainWrapper<>(sysUserMapper)
                        .select(SysUser::getUserId, SysUser::getDeptId)
                        .eq(SysUser::getUserId, userId)
                        .one();
                //查询机构
                SysDept sysDept = new LambdaQueryChainWrapper<>(sysDeptMapper)
                        .select(SysDept::getProvinceCode, SysDept::getCityCode, SysDept::getCountyCode,
                                SysDept::getTownCode, SysDept::getVillageCode,SysDept::getAdministrativeLevel,SysDept::getProjectId)
                        .eq(SysDept::getDeptId, sysUser.getDeptId())
                        .one();
                if(Objects.isNull(sysDept)) {
                        return null;
                }
                //查询该管理员所管理的项目id以及子项目id列表
                Project project = new LambdaQueryChainWrapper<>(projectMapper)
                        .select(Project::getId, Project::getProjectName,Project::getLevel,Project::getDeptId
                                ,Project::getCityCode,Project::getCountyCode)
                        .eq(Project::getId, sysDept.getProjectId())
                        .one();
                if(Objects.isNull(project)){
                        return null;
                }


                ProjectLoginBaseInfo projectLoginBaseInfo = new ProjectLoginBaseInfo();
                //查询项目对应行政区划的地图轮廓数据,根据部门的账号的行政等级字段来判断是县、镇、村。
                List<SysDistrict> sysDistrictList = getSysDistrictByDeptAdministrativeLevel(sysDept,projectLoginBaseInfo);
                //设置项目id列表
                projectLoginBaseInfo.setProjectIds(Collections.singletonList(project.getId()).toString());
                //设置项目id
                projectLoginBaseInfo.setProjectId(project.getId());
                //设置项目名称
                projectLoginBaseInfo.setProjectName(project.getProjectName());

                //根据项目级别获取对应的行政区划编码
                if(project.getLevel().equals("市级")){
                        projectLoginBaseInfo.setProjectLevel(ProjectLevelConstant.LEVEL_CITY);
                        projectLoginBaseInfo.setProjectAreaCode(JSONUtil.parseArray(project.getCityCode()).get(0).toString());
                }
                if(project.getLevel().equals("县/区级")){
                        projectLoginBaseInfo.setProjectLevel(ProjectLevelConstant.LEVEL_COUNTY);
                        projectLoginBaseInfo.setProjectAreaCode(JSONUtil.parseArray(project.getCountyCode()).get(0).toString());
                }
                //设置项目部门行政级别
                projectLoginBaseInfo.setDeptAreaLevel(String.valueOf(sysDept.getAdministrativeLevel()));


                if(!sysDistrictList.isEmpty()){
                        //项目的行政区划在地图上的轮廓json数据
                        projectLoginBaseInfo.setMapOutline(sysDistrictList.get(0).getMapOutline());
                        //项目的行政区划在地图上的轮廓json文件url
                        projectLoginBaseInfo.setMapOutlineUrl(sysDistrictList.get(0).getMapOutlineUrl());
                        //项目的行政区划中心点经纬度
                        projectLoginBaseInfo.setLongitude(sysDistrictList.get(0).getLng());
                        projectLoginBaseInfo.setLatitude(sysDistrictList.get(0).getLat());
                }
                return projectLoginBaseInfo;
        }

        /**
         * 根据部门账号的行政等级字段来判断是县、镇、村。并查询对应行政区划信息
         * @param sysDept 部门账号
         * @return 行政区划信息
         */
        private List<SysDistrict> getSysDistrictByDeptAdministrativeLevel(SysDept sysDept,ProjectLoginBaseInfo projectLoginBaseInfo) {
                LambdaQueryChainWrapper<SysDistrict> sysDistrictLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(sysDistrictMapper)
                        .select(SysDistrict::getMapOutline, SysDistrict::getMapOutlineUrl, SysDistrict::getLng, SysDistrict::getLat);
                if(Objects.equals(sysDept.getAdministrativeLevel(), DepartmentAdministrationLevelConstant.COUNTY)){
                        sysDistrictLambdaQueryChainWrapper.eq(SysDistrict::getAdcode, JSONUtil.parseArray(sysDept.getCountyCode()).get(0));
                        projectLoginBaseInfo.setDeptAreaCode(JSONUtil.parseArray(sysDept.getCountyCode()).get(0).toString());
                }
                else if(Objects.equals(sysDept.getAdministrativeLevel(), DepartmentAdministrationLevelConstant.TOWN)){
                        sysDistrictLambdaQueryChainWrapper.eq(SysDistrict::getAdcode, JSONUtil.parseArray(sysDept.getTownCode()).get(0));
                        projectLoginBaseInfo.setDeptAreaCode(JSONUtil.parseArray(sysDept.getTownCode()).get(0).toString());
                }
                else if(Objects.equals(sysDept.getAdministrativeLevel(), DepartmentAdministrationLevelConstant.VILLAGE)){
                        sysDistrictLambdaQueryChainWrapper.eq(SysDistrict::getAdcode, JSONUtil.parseArray(sysDept.getVillageCode()).get(0));
                        projectLoginBaseInfo.setDeptAreaCode(JSONUtil.parseArray(sysDept.getVillageCode()).get(0).toString());
                }
            return sysDistrictLambdaQueryChainWrapper
                        .list();
        }



        /**
         * 查询管理员可管理项目下拉框列表
         */
        @Override
        public List<Project> selectAdminProjectList() {
                //判断管理员级别
                List<Project> projectList=new ArrayList<>();
                //超级管理员
                if(Objects.isNull(ProjectHolder.getProjectInfo().getProjectIdList())){
                        //查询所有一级项目列表
                        projectList = new LambdaQueryChainWrapper<>(projectMapper)
                                .select(Project::getId, Project::getProjectName)
                                .isNull(Project::getParentId)
                                .list();
                }
                //市级/县级项目
                else if(Objects.nonNull(ProjectHolder.getProjectInfo().getProjectIdList())){
                        //查询所有子一级项目列表
                        projectList = new LambdaQueryChainWrapper<>(projectMapper)
                                .select(Project::getId, Project::getProjectName)
                                .in(!ProjectHolder.getProjectInfo().getProjectIdList().isEmpty(),Project::getParentId,
                                        ProjectHolder.getProjectInfo().getProjectIdList())
                                .list();
                }
                return projectList;
        }

        /**
         * 查询项目管理机构管理的最高行政区划级别下的全部行政区划的树状列表
         */
        @Override
        public List<SysDistrict> getProjectAreaTreeAll(Long deptId, Integer startLevel) {
                //处理超级管理员情况
                if(deptId==100){
                        return null;
                }
                //参数校验
                if(startLevel>5||startLevel<1){
                        throw new ServiceException("超出行政级别查询范围(1~5级)!");
                }
                //查询项目管理部门的行政区划信息
                SysDept sysDept = new LambdaQueryChainWrapper<>(sysDeptMapper)
                        .select(SysDept::getDeptId,SysDept::getProvinceCode, SysDept::getCityCode, SysDept::getCountyCode,
                                SysDept::getTownCode, SysDept::getVillageCode,SysDept::getAdministrativeLevel)
                        .eq(SysDept::getDeptId, deptId)
                        .one();
                if (Objects.isNull(sysDept)) {
                        throw new ServiceException("未查询到项目管理机构信息!");
                }
                //查询省、市、县行政区划信息
                LambdaQueryChainWrapper<SysDistrict> aboveSysDistrictLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(sysDistrictMapper).select(SysDistrict::getId,SysDistrict::getAdcode,SysDistrict::getLevel,SysDistrict::getName,SysDistrict::getFullName,SysDistrict::getParentId);
                LambdaQueryChainWrapper<SysDistrict> belowSysDistrictLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(sysDistrictMapper).select(SysDistrict::getId, SysDistrict::getAdcode, SysDistrict::getLevel, SysDistrict::getName,SysDistrict::getFullName, SysDistrict::getParentId);

                List<Object> queryInAdcodeList = new ArrayList<>();
                List<Integer> queryInLevelList = new ArrayList<>();
                //县级管理机构
                if(Objects.equals(sysDept.getAdministrativeLevel(), DepartmentAdministrationLevelConstant.COUNTY)){
                        //添加省代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getProvinceCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getProvinceCode()).get(0));
                        }
                        //添加市代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getCityCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getCityCode()).get(0));
                        }

                        //添加县代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getCountyCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getCountyCode()).get(0));
                        }

                        //县级查镇、村级别行政区划
                        queryInLevelList.add(DepartmentAdministrationLevelConstant.TOWN);
                        queryInLevelList.add(DepartmentAdministrationLevelConstant.VILLAGE);

                }
                //镇级管理机构
                else if(Objects.equals(sysDept.getAdministrativeLevel(), DepartmentAdministrationLevelConstant.TOWN)){
                        //添加省代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getProvinceCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getProvinceCode()).get(0));
                        }
                        //添加市代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getCityCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getCityCode()).get(0));
                        }
                        //添加县代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getCountyCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getCountyCode()).get(0));
                        }
                        //添加镇代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getTownCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getTownCode()).get(0));
                        }

                        //镇级查村级别行政区划
                        queryInLevelList.add(DepartmentAdministrationLevelConstant.VILLAGE);

                }
                //村级管理机构
                else if(Objects.equals(sysDept.getAdministrativeLevel(), DepartmentAdministrationLevelConstant.VILLAGE)){
                        //添加省代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getProvinceCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getProvinceCode()).get(0));
                        }
                        //添加市代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getCityCode()))
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getCityCode()).get(0));
                        //添加县代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getCountyCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getCountyCode()).get(0));
                        }
                        //添加镇代码
                        if(JsonStrUtil.nonEmptyArray(sysDept.getTownCode())){
                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getTownCode()).get(0));
                        }
                        //添加村代码
//                        if(JsonStrUtil.nonEmptyArray(sysDept.getVillageCode())){
//                                queryInAdcodeList.add(JSONUtil.parseArray(sysDept.getVillageCode()).get(0));
//                        }
                        //村级查户级别行政区划
                        queryInLevelList.add(DepartmentAdministrationLevelConstant.VILLAGE);

                }
                //先根据项目机构行政管理级别查上层的行政区划信息
                List<SysDistrict> aboveSysDistrictList =new ArrayList<>();
                if(!queryInAdcodeList.isEmpty()){
                        aboveSysDistrictList= aboveSysDistrictLambdaQueryChainWrapper
                                .in(SysDistrict::getAdcode, queryInAdcodeList)
                                .list();
                }
                //根据行政区划级别查询下级行政区划信息
                List<SysDistrict> belowSysDistrictList = belowSysDistrictLambdaQueryChainWrapper
                        .in(!queryInLevelList.isEmpty(),SysDistrict::getLevel, queryInLevelList)
                        .list();
                //合并
               List<SysDistrict> allSysDistrictList= new ArrayList<>();
               allSysDistrictList.addAll(aboveSysDistrictList);
               allSysDistrictList.addAll(belowSysDistrictList);
                List<SysDistrict> sysDistricts = buildTree(allSysDistrictList);
                //过滤一下不需要的数据
                return Collections.singletonList(sysDistricts.get(0));
        }



        /**
         * 查询项目管理机构的当前管理的行政区划树状列表
         * @param deptId 机构id
         * @param startLevel 行政区划其实展示级别
         * @param isDeptHold 是否只展示机构所管辖的行政区划
         */
        @Override
        public List<SysDistrict> getProjectAreaTree(Long deptId,Integer startLevel,Integer isDeptHold) {
                startLevel= Objects.isNull(startLevel)?1:startLevel;
                //处理超级管理员情况
//                if(deptId==100){
//                        return null;
//                }
                if(startLevel>5||startLevel<1){
                        throw new ServiceException("超出行政级别查询范围(1~5级)!");
                }
                //查询项目管理部门的行政区划信息
                SysDept sysDept = new LambdaQueryChainWrapper<>(sysDeptMapper)
                        .select(SysDept::getDeptId,SysDept::getProvinceCode, SysDept::getCityCode, SysDept::getCountyCode,
                                SysDept::getTownCode, SysDept::getVillageCode)
                        .eq(SysDept::getDeptId, deptId)
                        .one();
                if (Objects.isNull(sysDept)) {
                        return null;
                }
                //校验项目的省、市、县、镇、村行政区划列表数据完整性
                checkAreaCodeNonBlank(sysDept);

                List<Object> administrativeCodeList = getProjectDeptAreaCodeList(sysDept,startLevel);
                //查询项目所属县下面的所有镇、村行政区划列表
                List<SysDistrict> projectDistrictList;
                LambdaQueryChainWrapper<SysDistrict> sysDistrictLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(sysDistrictMapper)
                        .select(SysDistrict::getId, SysDistrict::getParentId, SysDistrict::getName, SysDistrict::getAdcode,
                                SysDistrict::getLevel, SysDistrict::getFullName, SysDistrict::getName
                                , SysDistrict::getLng, SysDistrict::getLat,SysDistrict::getMapOutline,SysDistrict::getMapOutlineUrl);

                projectDistrictList = sysDistrictLambdaQueryChainWrapper
                       .in(!administrativeCodeList.isEmpty(),SysDistrict::getAdcode,administrativeCodeList)
                        .list();

                //构建树状结构
            return buildTree(projectDistrictList);
        }


        /**
         * 获取项目所管辖行政区划代码列表
         * 业务规则:一个项目最大管辖行政区划为县/区级，下的若干镇和村
         *              即一个项目只能选择一个县/区，下的若干镇和村
         * @param sysDept 项目信息
         * @param startLevel 行政区划开始展示级别,对于河南省开封市尉氏县的项目，一般startLevel=3,会返回----尉氏县、县下的镇、镇下的村的行政区划代码
         *                    对于河南省开封市尉氏县的项目，若startLevel=2,会返回----开封市、尉氏县、县下的镇、镇下的村的行政区划代码
         *                    对于河南省开封市尉氏县的项目，若startLevel=1,会返回----河南省、开封市、尉氏县、县下的镇、镇下的村的行政区划代码
         *                    对于河南省开封市尉氏县的项目，若startLevel=4,会返回----县下的镇、镇下的村的行政区划代码
         *                    对于河南省开封市尉氏县的项目，若startLevel=5,会返回----镇下的村的行政区划代码
         */
        private  List<Object> getProjectDeptAreaCodeList(SysDept sysDept,Integer startLevel) {

                //项目的行政区划里面只能有一个省、市、县，也就是说项目为县级别建设
                JSONArray provinceCodeList = JSONUtil.parseArray(sysDept.getProvinceCode());
                //判断集合中的元素值都相等则说明省未多选
                if (!provinceCodeList.stream().allMatch(provinceCode -> provinceCode.equals(provinceCodeList.get(0)))) {
                        throw new ServiceException("项目省级行政区划只能包含一个省！");
                }
                //省去重
                List<Object> distinctProvinceCodeList = provinceCodeList.stream().distinct().collect(Collectors.toList());
                //判断市是否多选
                JSONArray cityCodeList = JSONUtil.parseArray(sysDept.getCityCode());
                //判断集合中的元素值都相等则说明市未多选
                if (!cityCodeList.stream().allMatch(cityCode -> cityCode.equals(cityCodeList.get(0)))) {
                        throw new ServiceException("项目市级行政区划只能包含一个市！");
                }
                //市去重
                List<Object> distinctCityCodeList = cityCodeList.stream().distinct().collect(Collectors.toList());
                //判断县是否多选
                JSONArray countyCodeList = JSONUtil.parseArray(sysDept.getCountyCode());
                //判断集合中的元素值都相等则说明县未多选
                if (!countyCodeList.stream().allMatch(countyCode -> countyCode.equals(countyCodeList.get(0)))) {
                        throw new ServiceException("项目县级行政区划只能包含一个县！");
                }
                //县去重
                List<Object>  distinctcCountyCodeList= countyCodeList.stream().distinct().collect(Collectors.toList());
                //判断镇是否多选
                JSONArray townCodeList = JSONUtil.parseArray(sysDept.getTownCode());
                //判断集合中的元素值都相等则说明镇未多选
                List<Object> distinctTownCodeList;

                distinctTownCodeList = townCodeList.stream().distinct().collect(Collectors.toList());
                JSONArray villageCodeList = JSONUtil.parseArray(sysDept.getVillageCode());

                //合并省、市、县、镇、村行政区划代码集合
                List<Object> administrativeCodeList = new ArrayList<>();
                //根据startLevel的值来合并省、市、县、镇、村行政区划代码集合
                int[] startLevels = {1, 2, 3, 4, 5};
                List<List<Object>> distinctCodeLists = Arrays.asList(distinctProvinceCodeList, distinctCityCodeList, distinctcCountyCodeList, distinctTownCodeList, villageCodeList);
                for (int i = 0; i < startLevels.length; i++) {
                        if (startLevel <= startLevels[i]) {
                                for (int j = i; j < distinctCodeLists.size(); j++) {
                                        administrativeCodeList.addAll(distinctCodeLists.get(j));
                                }
                                break;
                        }
                }
                return administrativeCodeList;
        }

        private void checkAreaCodeNonBlank(SysDept sysDept) {
                if(sysDept.getDeptId().toString().equals("100")){
                        return ;
                }
                if (StringUtils.isBlank(sysDept.getProvinceCode())){
                        throw new ServiceException("项目省级行政区划信息缺失！");
                }
                if (StringUtils.isBlank(sysDept.getCityCode())){
                        throw new ServiceException("项目市级行政区划信息缺失！");
                }
                if (StringUtils.isBlank(sysDept.getCountyCode())){
                        throw new ServiceException("项目县级行政区划信息缺失！");
                }
                if (StringUtils.isBlank(sysDept.getTownCode())){
                        throw new ServiceException("项目镇级行政区划信息缺失！");
                }
                if (StringUtils.isBlank(sysDept.getVillageCode())){
                        throw new ServiceException("项目村级行政区划信息缺失！");
                }
        }

        private List<SysDistrict> buildTree(List<SysDistrict> SysDistricts) {
                //给所有行政区划建立键值对
                Map<Long, SysDistrict> map = new HashMap<>();
                List<SysDistrict> roots = new ArrayList<>();
                for (SysDistrict sysDistrict : SysDistricts) {
                        map.put(sysDistrict.getAdcode(), sysDistrict);
                }
                return getDistricts(SysDistricts, map, roots);
        }

        private List<SysDistrict> getDistricts(List<SysDistrict> SysDistricts, Map<Long, SysDistrict> map, List<SysDistrict> roots) {
                for (SysDistrict sysDistrict : SysDistricts) {
                        Long parentId = sysDistrict.getParentId();
                        if (parentId == null || !map.containsKey(parentId)) {
                                roots.add(sysDistrict);
                        } else {
                                SysDistrict parent = map.get(parentId);
                                if (parent.getChildren() == null) {
                                        parent.setChildren(new ArrayList<>());
                                }
                                parent.getChildren().add(sysDistrict);
                        }
                }
                return roots;
        }

}

