package org.nl.system.service.dept.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.SecurityUtils;
import org.nl.common.utils.dto.CurrentUser;
import org.nl.common.domain.vo.DeptVo;
import org.nl.system.service.dept.dto.DeptTree;
import org.nl.common.utils.CopyUtil;
import org.nl.config.IdUtil;
import org.nl.system.service.dept.ISysDeptService;
import org.nl.system.service.dept.dao.SysDept;
import org.nl.system.service.dept.dao.mapper.SysDeptMapper;
import org.nl.system.service.dept.dto.DeptQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 部门 服务实现类
 * </p>
 *
 * @author generator
 * @since 2022-12-15
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public Map<String, Object> buildTree(DeptQuery query) {
        List<SysDept> list = this.list(query.build());
        List<DeptTree> deptTrees = CopyUtil.copyList(list, DeptTree.class);
        return this.buildTree(deptTrees);
    }

    @Override
    public Map<String, Object> getSuperior(List<Long> deptIds) {
        return null;
    }

    private Map<String, Object> buildTree(List<DeptTree> deptDtos) {
        List<DeptTree> trees= new ArrayList<>();
        Set<DeptTree> depts = new LinkedHashSet<>();
        List<String> deptNames = deptDtos.stream().map(DeptTree::getName).collect(Collectors.toList());
        boolean isChild;
        for (DeptTree deptDTO : deptDtos) {
            isChild = false;
            if (deptDTO.getPid() == null) {
                trees.add(deptDTO);
            }
            for (DeptTree it : deptDtos) {
                if (it.getPid() != null && deptDTO.getDept_id().equals(it.getPid())) {
                    isChild = true;
                    if (deptDTO.getChildren() == null) {
                        deptDTO.setChildren(new ArrayList<>());
                    }
                    deptDTO.getChildren().add(it);
                }
            }
            if (isChild) {
                depts.add(deptDTO);
            } else if (deptDTO.getPid() != null && !deptNames.contains(this.getById(deptDTO.getPid()).getName())) {
                depts.add(deptDTO);
            }
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("totalElements", deptDtos.size());
        map.put("content", CollectionUtil.isEmpty(trees) ? deptDtos : trees);
        return map;
    }

    @Override
    public Page queryVo(DeptQuery query, PageQuery pageQuery) {
        if (query.getPid_is_null() == null){
            if (query.getPid() == null){
                query.setPid_is_null(true);
            }
            if (StringUtils.isNotEmpty(query.getName()) || query.getIs_used()!=null){
                query.setPid_is_null(null);
            }
        }
        Page page = this.page(pageQuery.build(SysDept.class), query.build());
        page.setRecords(CopyUtil.copyList(page.getRecords(), DeptVo.class));
        if (StringUtils.isNotEmpty(query.getName()) || query.getIs_used()!=null){
            page.getRecords().forEach(a->((DeptVo)a).setHas_children(false) );
        }
        return page;
    }


    @Override
    public void saveUserDeptRelation(String userId, Collection<String> deptIds) {
        if (StringUtils.isEmpty(userId) || CollectionUtils.isEmpty(deptIds)){
            return;
        }
        sysDeptMapper.saveDeptRelation(userId,deptIds);
    }

    @Override
    public void delUserDeptRelation(String user) {
        sysDeptMapper.delDeptRelation(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDept(SysDept dept) {
        if (dept == null ||StringUtils.isEmpty(dept.getDept_id())){
            return;
        }
       this.updateById(dept);
       //删除节点信息
        sysDeptMapper.updateSubCount(dept.getDept_id());
        if (StringUtils.isNotEmpty(dept.getPid())){
            sysDeptMapper.updateSubCount(dept.getPid());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delateDept(Set<String> deptIds) {
        if (CollectionUtils.isEmpty(deptIds)){
            return;
        }
        verification(deptIds);
        Set<String> depts = new HashSet<>();
        Set<String> pids = new HashSet<>();
        List<SysDept> deptList = sysDeptMapper.selectList(new QueryWrapper<SysDept>().in("dept_id", deptIds));
        for (String deptId : deptIds) {
            depts.add(deptId);
            String allChild = sysDeptMapper.findAllChild(deptId);
            if (StringUtils.isNotEmpty(allChild)){
                String[] split = allChild.split(",");
                depts.addAll(Arrays.asList(split));
            }
        }
        this.remove(new QueryWrapper<SysDept>().in("dept_id", depts));
        deptList.forEach(dept -> {
            if (StringUtils.isNotEmpty(dept.getPid())){sysDeptMapper.updateSubCount(dept.getPid());}
        });

    }

    private void verification(Set<String> depeIds) {
        if (!CollectionUtils.isEmpty(depeIds)){
            List<Map> deptRelation = sysDeptMapper.getDeptRelation(depeIds);
            if (!CollectionUtils.isEmpty(deptRelation)){
                throw new BadRequestException("部门存在绑定的人员，请先解绑人员对应部门");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createDept(SysDept dept) {
        dept.setDept_id(IdUtil.getStringId());
        CurrentUser user = SecurityUtils.getCurrentUser();
        dept.setCreate_id(user.getId());
        dept.setCreate_name(user.getPresonName());
        dept.setCreate_time(new Date());
        this.save(dept);
        // 清理缓存
        if (StringUtils.isNotEmpty(dept.getPid())){
            sysDeptMapper.updateSubCount(dept.getPid());
        }
    }
}
