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

import cn.hutool.core.util.DesensitizedUtil;
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.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.basedata.domain.Substation;
import com.yfd.platform.modules.basedata.service.ISubstationAreaService;
import com.yfd.platform.modules.basedata.service.ISubstationPatroldeviceService;
import com.yfd.platform.modules.basedata.service.ISubstationService;
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 org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 系统组织框架 服务实现类
 * </p>
 *
 *
 * @since 2021-12-15
 */
@Service
@Transactional
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;

    @Resource
    private ISubstationService substationService;

    @Resource
    private ISubstationAreaService substationAreaService;

    @Resource
    private ISubstationPatroldeviceService substationPatroldeviceService;

    /***********************************
     * 用途说明：获取组织结构树
     * 参数说明
     *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);
        if (StrUtil.isNotEmpty(params)) {
            queryWrapper.like("orgname", params);    // 根据 部门名称
        }
        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);
            }
            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());//查询下一子集
            listMap.get(i).put("childList", childList);   //添加新列 子集
            if (ObjectUtil.isNotEmpty(listMap.get(i).get(""))) {
                String contactPhone = listMap.get(i).get("contactPhone").toString();
                listMap.get(i).put("contactPhone", DesensitizedUtil.mobilePhone(contactPhone));

            }
        }
        return listMap;
    }

    /***********************************
     * 用途说明：获取组织结构树
     * 参数说明
     *parentid      上级id
     * params       (根据参数查询 组织名称 负责人 描述)
     * 返回值说明:  组织树集合
     ***********************************/
    private List<Map<String, Object>> child(String parentid) {
        List<Map<String, Object>> listMap = new ArrayList<>();
        QueryWrapper<SysOrganization> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parentid", parentid); //根据上级id 查询
        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()); //循环获取下一子集
                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<Map<String, Object>> 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 = roleByUserId.stream()
                    .map(SysRole::getOrgscope)            // 提取所有角色的 orgscope 字段
                    .filter(StrUtil::isNotBlank)          // 过滤空字符串
                    .flatMap(orgscope -> Arrays.stream(orgscope.split(","))) // 拆分并扁平化处理
                    .distinct()                           // 去重
                    .collect(Collectors.toList());
            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.listMaps(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);
        /*SysUser userInfo = userService.getUserInfo();
        Integer usertype = userInfo.getUsertype();
        if (usertype != 0) {
            Set<String> orgCodeByUser = this.getOrgCodeByUser(userInfo.getId());
            Set<String> ids = new HashSet<>();
            for (String code : orgCodeByUser) {
                List<SysOrganization> list =
                        this.list(new LambdaQueryWrapper<SysOrganization>().eq(SysOrganization::getOrgcode, code));
                if (list == null || list.size() == 0) {
                    continue;
                }
                SysOrganization sysOrganization = list.get(0);
                if (sysOrganization == null) {
                    continue;
                }
                ids.add(sysOrganization.getId());
                String parentid = sysOrganization.getParentid();
                if (!"0".equals(parentid)) {
                    ids.add(parentid);
                }
            }
            if (orgCodeByUser.size() == 0) {
                return null;
            }
            queryWrapper.in(SysOrganization::getId, ids);
        }*/
        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);
        return i > 0;

    }

    /**********************************
     * 用途说明: 获取用户所对应的组织
     * 参数说明
     * 返回值说明: java.util.Set<java.lang.String>
     ***********************************/
    @Override
    public Set<String> getOrgCodeByUser(String id) {
        List<SysRole> roleByUserId = sysRoleMapper.getRoleByUserId(id);
        Set<String> codes = new HashSet<>();
        for (SysRole sysRole : roleByUserId) {
            String orgscope = sysRole.getOrgscope();
            if (StrUtil.isBlank(orgscope)) {
                continue;
            }
            String[] split = orgscope.split(",");
            for (String s : split) {
                SysOrganization sysOrganization = this.getById(s);
                if (sysOrganization == null) {
                    continue;
                }
                String parentid = sysOrganization.getParentid();
                if ("0".equals(parentid)) {
                    continue;
                }
                codes.add(sysOrganization.getOrgcode());
            }
        }
        return codes;
    }

    /**********************************
     * 用途说明: 新增系统组织框架
     * 参数说明 sysOrganization
     * 返回值说明: boolean
     ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrganization(SysOrganization sysOrganization) {
        if (StrUtil.isEmpty(sysOrganization.getParentid())) {
            //默认 填写父级id为0
            sysOrganization.setParentid("0");
        }
        //判断是否是否填写 有效 否则默认为 1
        if (StrUtil.isEmpty(sysOrganization.getIsvaild())) {
            sysOrganization.setIsvaild("1");
        }
        String orgtype = sysOrganization.getOrgtype();
        if (StrUtil.isNotBlank(orgtype) && "2".equals(orgtype)) {
            SysOrganization sysOrganization1 = this.getById(sysOrganization.getParentid());
            Substation substation = new Substation();
            // 变电站类别
            substation.setStationType(sysOrganization.getStationType());
            // 变电站名称
            substation.setStationName(sysOrganization.getOrgname());
            // 变电站编号
            substation.setStationCode(sysOrganization.getOrgcode());
            // 变电站IP
            substation.setStationIp(sysOrganization.getNodeIp());
            // 变电站节点ID
            substation.setNodeId(sysOrganization.getNodeId());
            // 电压等级
            substation.setVoltLevel(sysOrganization.getVoltLevel());
            // 所属地市
            substation.setCityName(sysOrganization.getCityName());
            // 所属省份
            substation.setProvinceName(sysOrganization.getProvinceName());
            // 公司名称
            substation.setCompanyName(sysOrganization.getCompanyName());
            // 区域ID
            substation.setSectionId(sysOrganization1.getId());
            // 区域名称
            substation.setSectionName(sysOrganization1.getOrgname());
            // 变电站地址
            substation.setStationAddress(sysOrganization.getAddress());
            // 联系电话
            substation.setContactPhone(sysOrganization.getContactPhone());
            // 联系人
            substation.setContactPerson(sysOrganization.getContactPerson());
            // 变电站介绍
            substation.setIntroduction(sysOrganization.getDescription());
            // 数据状态 0：禁用，1：启用
            substation.setDatastatus("1");
            // 是否边缘节点
            substation.setIsStationFlag(sysOrganization.getIsStationFlag());
            // 图片存储
            substation.setImages(sysOrganization.getCustom1());
            /*LambdaQueryWrapper<SubstationArea> areaQueryWrapper = new LambdaQueryWrapper<>();
            areaQueryWrapper.eq(SubstationArea::getStationCode, substation.getStationCode());
            int count1 = substationAreaService.count(areaQueryWrapper);
            if (count1 > 0) {
                return false;
            }
            int count2 =
                    substationPatroldeviceService.count(new LambdaQueryWrapper<SubstationPatroldevice>().eq
                    (SubstationPatroldevice::getStationId, substation.getStationId()));
            if (count2 > 0) {
                return false;
            }*/
            LambdaQueryWrapper<Substation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Substation::getStationCode, substation.getStationCode()).or().eq(Substation::getNodeId,
                    substation.getNodeId());
            int count = substationService.count(queryWrapper);
            if (count > 0) {
                throw new RuntimeException("当前变电站编号或节点已经存在");
            }
            int count3 = substationService.count() + 1;
            substation.setCustom1(count3);
            // 最近修改人
            substation.setLastmodifier(sysOrganization.getLastmodifier());
            // 最近修改时间
            substation.setLastmodifydate(LocalDateTime.now());
            substationService.save(substation);
        } else {
            sysOrganization.setVoltLevel("");
        }
        //填写 当前用户名称
        sysOrganization.setLastmodifier(currentUser.getUsername());
        //填写 当前日期
        sysOrganization.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        return this.save(sysOrganization);
    }

    /**********************************
     * 用途说明: 修改系统组织框架
     * 参数说明 sysOrganization
     * 返回值说明: boolean
     ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrganization(SysOrganization sysOrganization) {
        if (StrUtil.isEmpty(sysOrganization.getParentid())) {
            //默认 填写父级id为0
            sysOrganization.setParentid("0");
        }
        //判断是否是否填写 有效 否则默认为 1
        if (StrUtil.isEmpty(sysOrganization.getIsvaild())) {
            sysOrganization.setIsvaild("1");
        }
        String orgtype = sysOrganization.getOrgtype();
        if (StrUtil.isNotBlank(orgtype) && "2".equals(orgtype)) {
            SysOrganization sysOrganization1 = this.getById(sysOrganization.getParentid());
            SysOrganization byId = this.getById(sysOrganization.getId());
            String orgcode = byId.getOrgcode();
            Substation substation1 =
                    substationService.getOne(new LambdaQueryWrapper<Substation>().eq(Substation::getStationCode,
                            orgcode));
            Substation substation = new Substation();
            substation.setStationId(substation1.getStationId());
            // 变电站类别
            substation.setStationType(sysOrganization.getStationType());
            // 变电站名称
            //            substation.setStationName(sysOrganization.getOrgname());
            // 变电站编号
            //            substation.setStationCode(sysOrganization.getOrgcode());
            // 变电站IP
            substation.setStationIp(sysOrganization.getNodeIp());
            // 变电站节点ID
            substation.setNodeId(sysOrganization.getNodeId());
            // 电压等级
            substation.setVoltLevel(sysOrganization.getVoltLevel());
            // 所属地市
            substation.setCityName(sysOrganization.getCityName());
            // 所属省份
            substation.setProvinceName(sysOrganization.getProvinceName());
            // 公司名称
            substation.setCompanyName(sysOrganization.getCompanyName());
            // 区域ID
            substation.setSectionId(sysOrganization1.getId());
            // 区域名称
            substation.setSectionName(sysOrganization1.getOrgname());
            // 变电站地址
            substation.setStationAddress(sysOrganization.getAddress());
            // 联系电话
            substation.setContactPhone(sysOrganization.getContactPhone());
            // 联系人
            substation.setContactPerson(sysOrganization.getContactPerson());
            // 变电站介绍
            substation.setIntroduction(sysOrganization.getDescription());
            // 图片存储
            substation.setImages(sysOrganization.getCustom1());
            // 数据状态 0：禁用，1：启用
            substation.setDatastatus("1");
            // 是否边缘节点
            substation.setIsStationFlag(sysOrganization.getIsStationFlag());
            // 最近修改人
            substation.setLastmodifier(sysOrganization.getLastmodifier());
            // 最近修改时间
            substation.setLastmodifydate(LocalDateTime.now());
            substationService.updateSubstation(substation);
        } else {
            sysOrganization.setVoltLevel("");
        }
        //填写 当前用户名称
        sysOrganization.setLastmodifier(currentUser.getUsername());
        //填写 当前日期
        sysOrganization.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        return this.updateById(sysOrganization);
    }

    /**********************************
     * 用途说明: 设置组织是否有效
     * 参数说明 sysOrganization
     * 返回值说明: boolean
     ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setIsValid(String id, String isvaild) {
        UpdateWrapper<SysOrganization> updateWrapper = new UpdateWrapper<>();
        //根据id 修改是否有效，最近修改人，最近修改时间
        updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier"
                , userService.getUsername()).set("lastmodifydate",
                new Timestamp(System.currentTimeMillis()));
        SysOrganization sysOrganization = this.getById(id);
        String orgcode = sysOrganization.getOrgcode();
        Substation substation =
                substationService.getOne(new LambdaQueryWrapper<Substation>().eq(Substation::getStationCode,
                        orgcode));
        substation.setDatastatus(isvaild);
        substationService.setSubstationStatus(substation.getStationId(), isvaild);
        return this.update(updateWrapper);
    }

    /**********************************
     * 用途说明: 根据id删除系统组织框架
     * 参数说明 id
     * 返回值说明: boolean
     ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteById(String id) {
        SysOrganization sysOrganization = this.getById(id);
        String orgtype = sysOrganization.getOrgtype();
        List<String> ids = new ArrayList<>();
        if ("2".equals(orgtype)) {
            String[] split = id.split(",");
            ids.addAll(Arrays.asList(split));
        } else {
            this.removeById(id);
            LambdaQueryWrapper<SysOrganization> queryWrapper =
                    new LambdaQueryWrapper<>();
            List<SysOrganization> list = this.list(queryWrapper.eq(SysOrganization::getParentid, id));
            ids.addAll(list.stream().map(SysOrganization::getId).collect(Collectors.toList()));
        }
        this.deleteOrgAndStation(ids);
        return true;
    }

    /**********************************
     * 用途说明: 根据变电站id联动删除
     * 参数说明 ids
     * 返回值说明: void
     ***********************************/
    private void deleteOrgAndStation(List<String> ids) {
        for (String id : ids) {
            SysOrganization sysOrganization = this.getById(id);
            this.removeById(id);
            String orgcode = sysOrganization.getOrgcode();
            Substation one =
                    substationService.getOne(new LambdaQueryWrapper<Substation>().eq(Substation::getStationCode,
                            orgcode));
            if (one != null) {
                substationService.deleteSubstation(one.getStationId());
            }
        }
    }

    /**********************************
     * 用途说明: 生成组织范围树
     * 参数说明 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;
    }

}
