package com.fastbee.ggroup.service.impl;


import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.fastbee.common.core.domain.entity.SysDept;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.holder.ProjectHolder;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.json.JsonUtils;
import com.fastbee.ggroup.domain.GGroups;
import com.fastbee.ggroup.domain.GSiteGroups;
import com.fastbee.ggroup.domain.GSites;
import com.fastbee.ggroup.domain.vo.GGroupSiteVo;
import com.fastbee.ggroup.mapper.GGroupsMapper;
import com.fastbee.ggroup.mapper.GSiteGroupsMapper;
import com.fastbee.ggroup.service.IGGroupsService;
import com.fastbee.system.mapper.SysDeptMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

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


/**
 * 组Service业务层处理
 * 
 * @author kerwincui
 * &#064;date  2024-09-27
 */
@Service
public class GGroupsServiceImpl implements IGGroupsService
{

    private final GGroupsMapper gGroupsMapper;

    private final GSiteGroupsMapper gSiteGroupsMapper;

    private final SysDeptMapper sysDeptMapper;

    public GGroupsServiceImpl(GGroupsMapper gGroupsMapper, GSiteGroupsMapper gSiteGroupsMapper, SysDeptMapper sysDeptMapper) {
        this.gGroupsMapper = gGroupsMapper;
        this.gSiteGroupsMapper = gSiteGroupsMapper;
        this.sysDeptMapper = sysDeptMapper;
    }


    /**
     * 根据id查询组详情
     *
     * @param id 组主键
     * @return 组
     */
    @Override
    public GGroups selectGGroupsById(Long id)
    {
        return gGroupsMapper.selectGGroupsById(id);
    }


    /**
     * 查询组树状列表(不带叶子节点)后台站点管理
     * 
     * @param gGroups 组
     * @return 组
     */
    @Override
    public List<GGroups> selectGGroupsList(GGroups gGroups)
    {
        List<GGroups> list = new LambdaQueryChainWrapper<>(gGroupsMapper).select(GGroups::getId, GGroups::getName, GGroups::getIcon,
                        GGroups::getTag, GGroups::getParentId, GGroups::getProjectId, GGroups::getProjectName,
                        GGroups::getOrderNum, GGroups::getSpace)
                .in(!ProjectHolder.getProjectInfo().getProjectIdList().isEmpty()&&gGroups.getProjectId()==null,
                        GGroups::getProjectId, ProjectHolder.getProjectInfo().getProjectIdList())
                .eq(gGroups.getProjectId()!=null, GGroups::getProjectId, gGroups.getProjectId())
                .list();
        return buildGroupTree(list);
    }

    /**
     * 查询组下面的站点
     * @param gGroups 组
     * @return 组
     */
    @Override
    public List<GGroupSiteVo> selectGGroupsListSites(GGroups gGroups) {
        //构建查询器
        MPJLambdaWrapper<GSiteGroups> gSiteGroupsMPJLambdaWrapper = new MPJLambdaWrapper<GSiteGroups>()
                .select(GSiteGroups::getId, GSiteGroups::getParentId, GSiteGroups::getSiteId)
//                .select(GGroups::getName)//起个别名
//                .selectAs(GGroups::getName, "parentName")
                .select(GSites::getName, GSites::getIcon, GSites::getType, GSites::getSpace, GSites::getSpaceValue,
                        GSites::getAreaCode,GSites::getFullAreaCode)
                .leftJoin(GGroups.class, GGroups::getId, GSiteGroups::getParentId)
                .leftJoin(GSites.class, GSites::getId, GSiteGroups::getSiteId)
                .eq(GSiteGroups::getParentId, gGroups.getParentId())
                //按名称模糊匹配
                .like(StringUtils.isNotBlank(gGroups.getSearchValue()), GSites::getName, gGroups.getSearchValue());
        List<GGroupSiteVo> gGroupSiteVos = gSiteGroupsMapper.selectJoinList(GGroupSiteVo.class, gSiteGroupsMPJLambdaWrapper);
        gSiteGroupsMapper.selectJoinList(GGroupSiteVo.class,gSiteGroupsMPJLambdaWrapper);
        //查询该机构下的行政区划列表
        SysDept sysDept = new LambdaQueryChainWrapper<>(sysDeptMapper)
                .select(SysDept::getDeptId, SysDept::getProvinceCode, SysDept::getCityCode, SysDept::getCountyCode, SysDept::getTownCode, SysDept::getVillageCode)
                .eq(SysDept::getDeptId, ProjectHolder.getProjectInfo().getProjectDeptId())
                .one();
        if(Objects.isNull(sysDept)){
            throw new ServiceException("未查询到机构信息");
        }
        List<Long> adcodeList = new ArrayList<>();
        adcodeList.addAll(JsonUtils.parseArray(sysDept.getProvinceCode(), Long.class));
        adcodeList.addAll(JsonUtils.parseArray(sysDept.getCityCode(), Long.class));
        adcodeList.addAll(JsonUtils.parseArray(sysDept.getCountyCode(), Long.class));
        adcodeList.addAll(JsonUtils.parseArray(sysDept.getTownCode(), Long.class));
        adcodeList.addAll(JsonUtils.parseArray(sysDept.getVillageCode(), Long.class));
        //根据区域代码过滤站点
        if(!adcodeList.isEmpty()){
            gGroupSiteVos = gGroupSiteVos
                    .stream()
                    .filter(gGroupSiteVo -> adcodeList.contains(Long.valueOf(gGroupSiteVo.getAreaCode()))).collect(Collectors.toList());
        }
        return gGroupSiteVos;
    }

    /**
     * 构建组树状列表
     */
    private List<GGroups> buildGroupTree(List<GGroups> groups) {
        Map<Long, GGroups> map = new HashMap<>();
        List<GGroups> roots = new ArrayList<>();
        for (GGroups group : groups) {
            map.put(group.getId(), group);
        }
        return combinationGroupsTree(groups, map, roots);
    }

    /**
     * 组合组树状结构列表
     */
    private List<GGroups> combinationGroupsTree(List<GGroups> groups, Map<Long, GGroups> map, List<GGroups> roots) {
        for (GGroups group : groups) {
            Long parentId = group.getParentId();
            if (parentId == null || !map.containsKey(parentId)) {
                roots.add(group);
            } else {
                GGroups parent = map.get(parentId);
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(group);
            }
        }
        return roots;
    }

    /**
     * 构建组和站点树状列表
     */
    private List<GGroups> buildTreeSite(List<GGroups> groupsList,List<String> areaCodeList) {
        // 构建一个Map，用于存储每个组对象:id->组对象
        Map<Long, GGroups> map = new HashMap<>();
        //根组列表
        List<GGroups> roots = new ArrayList<>();
        //所有站点列表
        List<GGroupSiteVo> gGroupSiteAllList = selectGGroupsAllListSites(new GGroups());
        //根据区域代码过滤站点
        if(Objects.nonNull(areaCodeList) && !areaCodeList.isEmpty()){
            gGroupSiteAllList = gGroupSiteAllList.stream()
                    .filter(site -> areaCodeList.contains(site.getAreaCode())).collect(Collectors.toList());
        }
        for (GGroups group : groupsList) {
            //查询组的直接子站点列表
            //过滤全部站点列表找到当前组下面的所有站点
            List<GGroupSiteVo> currentGroupSiteList = gGroupSiteAllList.stream()
                    .filter(site -> site.getParentId().equals(group.getId()))
                    .collect(Collectors.toList());
            //将子站点列表添加到组对象中
            List<GGroups> childrenList= group.getChildren();
            currentGroupSiteList.forEach(site->{
                GGroups gGroups1 = new GGroups();
                gGroups1.setId(site.getId());
                gGroups1.setName(site.getName());
                gGroups1.setSiteType(site.getType());
                gGroups1.setIcon(site.getIcon());
                gGroups1.setSpace(site.getSpace());
                gGroups1.setSpaceValue(site.getSpaceValue());
                gGroups1.setNodeType(1);
                gGroups1.setSiteId(site.getId());
                childrenList.add(gGroups1);
            });
            map.put(group.getId(), group);
        }
        //构建组树状结构
        return combinationGroupsTree(groupsList, map, roots);
    }
    /**
    * 查询项目下全部站点
    */
    public List<GGroupSiteVo> selectGGroupsAllListSites(GGroups gGroups) {
        MPJLambdaWrapper<GSiteGroups> gSiteGroupsMPJLambdaWrapper = new MPJLambdaWrapper<GSiteGroups>()
                .select(GSiteGroups::getId, GSiteGroups::getParentId, GSiteGroups::getSiteId)
                .select(GSites::getName, GSites::getIcon, GSites::getType, GSites::getSpace,
                        GSites::getSpaceValue,GSites::getAreaCode,GSites::getFullAreaCode)
                .leftJoin(GGroups.class, GGroups::getId, GSiteGroups::getParentId)
                .leftJoin(GSites.class, GSites::getId, GSiteGroups::getSiteId)
                .in(!ProjectHolder.getProjectInfo().getProjectIdList().isEmpty(),GGroups::getProjectId,ProjectHolder.getProjectInfo().getProjectIdList());
        return gSiteGroupsMapper.selectJoinList(GGroupSiteVo.class,gSiteGroupsMPJLambdaWrapper);
    }


    /**
     * 新增组
     *
     * @param gGroups 组
     * @return 结果
     */
    @Override
    public int insertGGroups(GGroups gGroups)
    {
        //同一个父节点下组名不能重复
        List<GGroups> duplicateNameList = new LambdaQueryChainWrapper<>(gGroupsMapper)
                .select(GGroups::getId)
                .eq(GGroups::getName, gGroups.getName().trim())
                .eq(GGroups::getParentId, gGroups.getParentId())
                .list();
        if(!duplicateNameList.isEmpty()){
            throw new ServiceException("组名重复!");
        }
        gGroups.setCreateTime(DateUtils.getNowDate());
        return gGroupsMapper.insertGGroups(gGroups);
    }

    /**
     * 修改组
     * @param gGroups 组
     * @return 结果
     */
    @Override
    public int updateGGroups(GGroups gGroups)
    {
        //同一个父节点下组名不能重复
        List<GGroups> duplicateNameList = new LambdaQueryChainWrapper<>(gGroupsMapper)
                .select(GGroups::getId)
                .eq(GGroups::getParentId, gGroups.getParentId())
                .eq(GGroups::getName, gGroups.getName().trim())
                .ne(GGroups::getId, gGroups.getId())
                .list();

        if(!duplicateNameList.isEmpty()){
            throw new ServiceException("组名重复!");
        }
        gGroups.setUpdateTime(DateUtils.getNowDate());
        return gGroupsMapper.updateGGroups(gGroups);
    }


    /**
     * 删除组信息
     * @param id 组主键
     * @return 结果
     */
    @Override
    public int deleteGGroupsById(Long id)
    {
        //判断组下面是否有节点
        return gGroupsMapper.deleteGGroupsById(id);
    }

    /**
     * 查询组和站点(叶子节点)的树状结构
     * @param gGroups 组
     * @return 列表
     */
    @Override
    public List<?> selectGGroupsAndSitesList(GGroups gGroups) {
        //超级管理员不显示
        if(ProjectHolder.getProjectInfo().getProjectIdList().isEmpty()){
            return new ArrayList<>();
        }
        //查询项目下的全部站点
        List<GGroups> groupSiteTreeList = new LambdaQueryChainWrapper<>(gGroupsMapper)
                .select(GGroups::getId, GGroups::getName, GGroups::getParentId, GGroups::getIcon,GGroups::getTag,
                        GGroups::getSpace, GGroups::getSpaceValue, GGroups::getProjectId)
                //根据站点标签过滤
                .eq(Objects.nonNull(gGroups.getTag()), GGroups::getTag, gGroups.getTag())
                .in(GGroups::getProjectId, ProjectHolder.getProjectInfo().getProjectIdList())
                .list();

        //构建组和站点树状列表
        List<GGroups> gGroupsList = buildTreeSite(groupSiteTreeList,gGroups.getAreaCodeList());
        //组的树状结构外层数组元素套一层数组：方便前端数据渲染
        return gGroupsList.stream().map(gGroups1 -> {
            List<GGroups> list1 = new ArrayList<>();
            list1.add(gGroups1);
            return list1;
        }).collect(Collectors.toList());
    }
}
