package com.yfd.platform.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.system.domain.SysOrganization;
import com.yfd.platform.system.domain.SysRole;
import com.yfd.platform.system.domain.SysUser;
import com.yfd.platform.system.mapper.SysOrganizationMapper;
import com.yfd.platform.system.mapper.SysRoleMapper;
import com.yfd.platform.system.service.ISysOrganizationService;
import com.yfd.platform.system.service.IUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 系统组织框架 服务实现类
 * </p>
 *
 * @author zhengsl
 * @since 2021-12-15
 */
@Service
public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMapper, SysOrganization> implements ISysOrganizationService {

    @Resource
    private UserServiceImpl currentUser;

    @Resource
    private IUserService userService;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysOrganizationMapper sysOrganizationMapper;

    /***********************************
     * 用途说明：获取组织结构树
     * 参数说明
     *parentid      上级id
     * params       名称（根据名称查询二级）
     * 返回值说明:  组织树集合
     ***********************************/
    @Override
    public List<Map<String, Object>> getOrgTree(String parentid,
                                                String params) {
        List<Map<String, Object>> listMap = new ArrayList<>();
        QueryWrapper<SysOrganization> queryWrapper = new QueryWrapper<>();
        //根据父级id查询
        queryWrapper.eq("parentid", parentid);   // 根据 部门名称
        SysUser userInfo = userService.getUserInfo();
        if (userInfo.getUsertype() != 0) {
            List<SysRole> roleByUserId =
                    sysRoleMapper.getRoleByUserId(userInfo.getId());
            List<String> ids = new ArrayList<>();
            // 循环当前角色
            for (SysRole sysRole : roleByUserId) {
                // 获取角色的组织Id
                String orgscope = sysRole.getOrgscope();
                if (StrUtil.isBlank(orgscope)) {
                    continue;
                }
                // 拆分组织Id
                String[] split = orgscope.split(",");
                List<String> stringList = Arrays.asList(split);
                Set<String> set = new HashSet<>();
                if (stringList.size() > 0) {
                    List<SysOrganization> list =
                            sysOrganizationMapper.selectList(new LambdaQueryWrapper<SysOrganization>().in(SysOrganization::getId, stringList));
                    list.forEach(l -> set.add(l.getParentid()));
                }
                ids.addAll(stringList);
                ids.addAll(set);
            }
            if (ids.size() > 0) {
                queryWrapper.in("id", ids);
            }

        }
        listMap = this.listMaps(queryWrapper.orderByAsc("orgcode"));
        for (int i = 0; i < listMap.size(); i++) {
            List<Map<String, Object>> childList = child(listMap.get(i).get(
                    "id").toString(), params);//查询下一子集
            listMap.get(i).put("childList", childList);   //添加新列 子集
            // 检查 childList 是否为空，如果为空则删除该条目
            if (childList == null || childList.isEmpty()) {
                listMap.remove(i);
                i--;  // 移除元素后，需要调整索引，避免跳过元素
            }


        }
        return listMap;
    }

    /***********************************
     * 用途说明：获取组织结构树
     * 参数说明
     *parentid      上级id
     * params       (根据参数查询 组织名称 负责人 描述)
     * 返回值说明:  组织树集合
     ***********************************/
    private List<Map<String, Object>> child(String parentid, String params) {
        List<Map<String, Object>> listMap = new ArrayList<>();
        QueryWrapper<SysOrganization> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parentid", parentid); //根据上级id 查询
        if (StrUtil.isNotEmpty(params)) {
            queryWrapper.like("orgname", params);    // 根据 部门名称
        }

        listMap = this.listMaps(queryWrapper.orderByAsc("orgcode"));
        if (listMap.size() > 0) {              //判断是否存在子集
            for (int i = 0; i < listMap.size(); i++) {             //遍历表数据
                List<Map<String, Object>> childList =
                        child(listMap.get(i).get("id").toString(), params); //循环获取下一子集
                listMap.get(i).put("childList", childList); //添加新列 子集
            }
        }
        return listMap;
    }

    /***********************************
     * 用途说明：新增系统组织框架
     * 参数说明
     * sysOrganization     系统组织框架对象
     * 返回值说明:  是否新增成功
     ***********************************/
    @Override
    public boolean addOrg(SysOrganization sysOrganization) {
        QueryWrapper<SysOrganization> queryWrapper = new QueryWrapper<>();
        SysOrganization parent = null;
        int codeMax = 0;
        //查询最大的编号   判断是否存在父级id  有值 根据父级id查询   否则 根据父级id为0 查询
        queryWrapper.select("max(orgcode)");
        if (StrUtil.isNotEmpty(sysOrganization.getParentid())) {
            //根据父级id查询父级信息
            parent = this.getById(sysOrganization.getParentid());
            queryWrapper.eq("parentid", sysOrganization.getParentid());
        } else {
            //默认 填写父级id为0
            sysOrganization.setParentid("0");
            queryWrapper.eq("parentid", "0");
        }
        List<Object> max = this.listObjs(queryWrapper);
        //判断查询是否存在  存在转换成int类型并给codeMax替换值
        if (max.size() > 0) {
            codeMax =
                    Integer.parseInt(max.get(0).toString().substring(max.get(0).toString().length() - 2));
        }
        //2位数字编号
        DecimalFormat df = new DecimalFormat("00");
        //编号
        String code = df.format(codeMax + 1);
        //查询到父级不为空 重新赋值 父级编号+新的序号
        if (parent != null) {
            code = parent.getOrgcode() + df.format(codeMax + 1);
        }
        //判断是否是否填写 有效 否则默认为 1
        if (StrUtil.isEmpty(sysOrganization.getIsvaild())) {
            sysOrganization.setIsvaild("1");
        }
        //填写 编号
        sysOrganization.setOrgcode(code);
        //填写 当前用户名称
        sysOrganization.setLastmodifier(currentUser.getUsername());
        //填写 当前日期
        sysOrganization.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        return this.save(sysOrganization);
    }

    /***********************************
     * 用途说明：根据企业ID查询组织详情
     * 参数说明
     * id        企业id
     * 返回值说明:  系统组织框架对象
     ***********************************/
    @Override
    public List<SysOrganization> getOrganizationById(String id,
                                                     String orgName) {

        LambdaQueryWrapper<SysOrganization> queryWrapper =
                new LambdaQueryWrapper<>();
        SysUser userInfo = userService.getUserInfo();
        if (userInfo.getUsertype() != 0) {
            List<SysRole> roleByUserId =
                    sysRoleMapper.getRoleByUserId(userInfo.getId());
            List<String> ids = new ArrayList<>();
            // 循环当前角色
            for (SysRole sysRole : roleByUserId) {
                // 获取角色的组织Id
                String orgscope = sysRole.getOrgscope();
                if (StrUtil.isBlank(orgscope)) {
                    continue;
                }
                // 拆分组织Id
                String[] split = orgscope.split(",");
                List<String> stringList = Arrays.asList(split);
                ids.addAll(stringList);
            }
            if (ObjectUtil.isNotEmpty(ids)) {
                queryWrapper.in(SysOrganization::getId, ids);
            }

        }
        if (StrUtil.isNotBlank(orgName)) {
            queryWrapper.like(SysOrganization::getOrgname, orgName);
        }
        queryWrapper.eq(SysOrganization::getParentid, id).orderByDesc(SysOrganization::getOrgcode);
        return this.list(queryWrapper);
    }

    /***********************************
     * 用途说明：获取组织范围树结构
     * 参数说明
     *parentid      上级id
     * params       名称（根据名称查询二级）
     * 返回值说明:  组织树集合
     ***********************************/
    @Override
    public List<Map<String, Object>> getOrgScopeTree(String roleId) {
        LambdaQueryWrapper<SysOrganization> queryWrapper =
                new LambdaQueryWrapper<>();
        queryWrapper.eq(SysOrganization::getIsvaild, '1');
        queryWrapper.orderByAsc(SysOrganization::getOrgcode);
        List<Map<String, Object>> listMaps = this.listMaps(queryWrapper);
        // 获取当前角色
        SysRole sysRole = sysRoleMapper.selectById(roleId);
        String orgscope = sysRole.getOrgscope();
        List<String> ids = new ArrayList<>();
        if (StrUtil.isNotBlank(orgscope)) {
            String[] split = orgscope.split(",");
            ids = Arrays.asList(split);
        }

        for (Map<String, Object> map : listMaps) {
            String id = (String) map.get("id");
            if (ids.contains(id)) {
                map.put("checkinfo", true);
            } else {
                map.put("checkinfo", false);
            }
            map.put("bool", true);
        }
        // 生成组织树
        List<Map<String, Object>> listMap = buildTrees(listMaps);
        return listMap;
    }

    /**********************************
     * 用途说明: 修改角色组织范围
     * 参数说明 roleId     角色id
     * 参数说明 orgscope   组织id集合
     * 返回值说明: boolean 是否修改成功
     ***********************************/
    @Override
    public boolean updateOrgScopeByRoleId(String roleId, String orgscope) {
        SysRole sysRole = new SysRole();
        sysRole.setId(roleId);
        sysRole.setOrgscope(orgscope);
        int i = sysRoleMapper.updateById(sysRole);
        if (i > 0) {
            return true;
        } else {
            return false;
        }

    }

    /**********************************
     * 用途说明: 生成组织范围树
     * 参数说明 sysMenus
     * 返回值说明: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     ***********************************/
    public List<Map<String, Object>> buildTrees(List<Map<String, Object>> sysMenus) {
        List<Map<String, Object>> resultMenuList = new ArrayList<>();
        // 获取父节点
        for (Map<String, Object> sysMenu : sysMenus) {
            if ("0".equals(sysMenu.get("parentid"))) {
                resultMenuList.add(sysMenu);
            }
        }
        // 寻找子节点
        for (Map<String, Object> sysMenu : resultMenuList) {
            sysMenu.put("checkinfo", true);
            List<Map<String, Object>> children = new ArrayList<>();
            List<String> array = new ArrayList<>();
            for (Map<String, Object> menu : sysMenus) {
                String id = (String) sysMenu.get("id");
                String parentid = (String) menu.get("parentid");
                if (id.equals(parentid)) {
                    // 如果存在一个子节点没有被选中，父节点则不是全选状态
                    if (!(boolean) menu.get("checkinfo")) {
                        sysMenu.put("checkinfo", false);
                    } else {
                        // 将处于选中状态的子节点加入到数组中
                        array.add((String) menu.get("orgname"));
                    }
                    children.add(menu);
                }
            }
            // 所有子节点加入父节点
            sysMenu.put("children", children);
            sysMenu.put("array", array);
        }
        return resultMenuList;
    }

    /**
     * 组织集合递归生成树状菜单(Map)
     *
     * @param sysOrgList 组织集合
     * @return
     */
    public List<Map<String, Object>> buildTree(List<Map<String, Object>> sysOrgList) {
        List<Map<String, Object>> resultOrgList = new ArrayList<>();
        for (Map<String, Object> sysOrg : sysOrgList) {
            List<Map<String, Object>> childrenList = new ArrayList<>();
            List<String> array = new ArrayList<>();
            for (Map<String, Object> org : sysOrgList) {
                if (org.get("parentid").equals(sysOrg.get("id"))) {
                    if (!(boolean) org.get("checkinfo")) {
                        sysOrg.put("checkinfo", false);
                    }
                    array.add((String) org.get("orgname"));
                    childrenList.add(org);
                }
            }
            if ("0".equals(sysOrg.get("parentid"))) {
                if (childrenList.size() > 0) {
                    sysOrg.put("children", childrenList);
                }
                resultOrgList.add(sysOrg);
            }
            sysOrg.put("array", array);
        }
        return resultOrgList;
    }
}
