package com.starry.admin.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.starry.admin.common.domain.TreeSelect;
import com.starry.admin.modules.system.mapper.SysDeptMapper;
import com.starry.admin.modules.system.mapper.SysRoleMapper;
import com.starry.admin.modules.system.module.entity.SysDeptEntity;
import com.starry.admin.modules.system.module.entity.SysRoleEntity;
import com.starry.admin.modules.system.service.SysDeptService;
import com.starry.common.annotation.DataScope;
import com.starry.common.constant.UserConstants;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2022-07-12
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDeptEntity> implements SysDeptService {

    @Resource
    private SysRoleMapper roleMapper;

    @Override
    @DataScope(deptAlias = "d")
    public List<SysDeptEntity> selectDeptList(SysDeptEntity dept) {
        return baseMapper.selectDeptList(dept);
    }

    @Override
    public String checkDeptNameUnique(SysDeptEntity dept) {
        Long deptId = dept.getDeptId() == null ? -1L : dept.getDeptId();
        List<SysDeptEntity> infos = list(new LambdaQueryWrapper<SysDeptEntity>()
                .eq(SysDeptEntity::getDeptName, dept.getDeptName()).eq(SysDeptEntity::getParentId, dept.getParentId()));
        // 查出有数据 并且不是自己，则不唯一
        if (CollectionUtil.isNotEmpty(infos) && infos.get(0).getDeptId().longValue() != deptId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean create(SysDeptEntity dept) {
        SysDeptEntity info = getById(dept.getParentId());
        // 若父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(String.valueOf(info.getStatus()))) {
            throw new RuntimeException("部门停用，不允许新增");
        }
        dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
        dept.setDeptLevel(info.getDeptLevel() == null ? 0 : info.getDeptLevel() + 1);
        return save(dept);
    }

    @Override
    public boolean update(SysDeptEntity dept) {
        // 新的上级部门
        SysDeptEntity newParentDept = getById(dept.getParentId());
        // 当前部门
        SysDeptEntity oldDept = getById(dept.getDeptId());
        if (newParentDept != null && oldDept != null) {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
            String oldAncestors = oldDept.getAncestors();
            dept.setAncestors(newAncestors);
            updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors);
        }
        return updateById(dept);
    }

    @Override
    public boolean delete(List<Long> ids) {
        return removeBatchByIds(ids);
    }

    @Override
    public boolean hasChildByDeptId(Long deptId) {
        List<SysDeptEntity> list = baseMapper
                .selectList(new LambdaQueryWrapper<SysDeptEntity>().eq(SysDeptEntity::getParentId, deptId));
        if (CollectionUtil.isNotEmpty(list)) {
            return true;
        }
        return false;
    }

    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<SysDeptEntity> depts) {
        List<SysDeptEntity> deptList = buildDeptTree(depts);
        // 转换成树结构的list
        return deptList.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    public List<SysDeptEntity> buildDeptTree(List<SysDeptEntity> depts) {
        List<SysDeptEntity> returnList = new ArrayList<>();
        // 所有部门id
        List<Long> tempList = new ArrayList<>();
        for (SysDeptEntity dept : depts) {
            tempList.add(dept.getDeptId());
        }
        for (SysDeptEntity dept : depts) {
            // 如若是顶级节点，遍历该父节点下的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (CollectionUtil.isEmpty(returnList)) {
            returnList = depts;
        }
        return returnList;
    }

    /**
     * 修改子元素关系
     *
     * @param deptId
     *            被修改的部门ID
     * @param newAncestors
     *            新的父ID集合
     * @param oldAncestors
     *            旧的父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
        List<SysDeptEntity> childrens = baseMapper.selectChildrenDeptById(deptId);
        if (CollectionUtil.isNotEmpty(childrens)) {
            for (SysDeptEntity child : childrens) {
                child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
                updateById(child);
            }
        }
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<SysDeptEntity> list, SysDeptEntity t) {
        List<SysDeptEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDeptEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysDeptEntity> getChildList(List<SysDeptEntity> list, SysDeptEntity t) {
        List<SysDeptEntity> tList = new ArrayList<>();
        for (SysDeptEntity n : list) {
            if (n.getParentId() != null && n.getParentId().longValue() == t.getDeptId().longValue()) {
                tList.add(n);
            }
        }
        return tList;
    }

    /**
     * 判断是否还有子节点
     */
    private boolean hasChild(List<SysDeptEntity> list, SysDeptEntity t) {
        return !getChildList(list, t).isEmpty();
    }

    /**
     * 根据角色ID查询部门树信息
     *
     * @param roleId
     *            角色ID
     * @return 选中部门列表
     */
    @Override
    public List<Long> selectDeptListByRoleId(Long roleId) {
        SysRoleEntity role = roleMapper.selectRoleById(roleId);
        return baseMapper.selectDeptListByRoleId(roleId, role.isDeptCheckStrictly());
    }

    /**
     * 查询部门树结构信息
     *
     * @param dept
     *            部门信息
     * @return 部门树信息集合
     */
    @Override
    public List<TreeSelect> selectDeptTreeList(SysDeptEntity dept) {
        List<SysDeptEntity> depts = this.selectDeptList(dept);
        return buildDeptTreeSelect(depts);
    }
}
