package com.engine.organization.entity.department.bo;

import com.engine.organization.entity.department.dto.DepartmentListDTO;
import com.engine.organization.entity.department.param.DeptSearchParam;
import com.engine.organization.entity.department.po.DepartmentPO;
import com.engine.organization.entity.department.vo.SingleDeptTreeVO;
import com.engine.organization.entity.searchtree.SearchTree;
import com.engine.organization.mapper.comp.CompMapper;
import com.engine.organization.mapper.department.DepartmentMapper;
import com.engine.organization.mapper.employee.EmployeeMapper;
import com.engine.organization.util.db.MapperProxyFactory;
import org.apache.commons.collections.CollectionUtils;
import weaver.general.Util;

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

/**
 * @Author weaver_cl
 * @description:
 * @Date 2022/5/20
 * @Version V1.0
 **/
public class DepartmentBO {

    public static List<DepartmentListDTO> buildDeptDTOList(Collection<DepartmentPO> list) {

        // 递归添加父级数据
        Map<Long, DepartmentPO> poMaps = list.stream().collect(Collectors.toMap(DepartmentPO::getId, item -> item));
        List<DepartmentListDTO> dtoList = list.stream().map(e ->
                DepartmentListDTO
                        .builder()
                        .id(e.getId())
                        .deptNo(e.getDeptNo())
                        .deptName(e.getDeptName())
                        .deptNameShort(e.getDeptNameShort())
                        .parentComp(null == e.getParentComp() ? "" : MapperProxyFactory.getProxy(CompMapper.class).listById(e.getParentComp()).getCompName())
                        .parentDept(e.getParentDept())
                        .parentDeptName(null == poMaps.get(e.getParentDept()) ? "" : poMaps.get(e.getParentDept()).getDeptName())
                        .deptPrincipal(getEmployeeNameById(e.getDeptPrincipal()))
                        .showOrder(null == e.getShowOrder() ? 0 : e.getShowOrder())
                        .forbiddenTag(e.getForbiddenTag())
                        .build()).collect(Collectors.toList());
        Map<Long, List<DepartmentListDTO>> collects = dtoList.stream().filter(item -> null != item.getParentDept() && 0 != item.getParentDept()).collect(Collectors.groupingBy(DepartmentListDTO::getParentDept));
        // 处理被引用数据
        List<String> usedIds = MapperProxyFactory.getProxy(DepartmentMapper.class).listUsedId();
        List<String> collect = Arrays.stream(String.join(",", usedIds).split(",")).collect(Collectors.toList());
        return dtoList.stream().peek(e -> {
            List<DepartmentListDTO> childList = collects.get(e.getId());
            if (CollectionUtils.isNotEmpty(childList)) {
                e.setChildren(childList);
                e.setIsUsed(1);
            } else {
                if (collect.contains(Util.null2String(e.getId()))) {
                    e.setIsUsed(1);
                } else {
                    e.setIsUsed(0);
                }
            }
        }).filter(item -> null == item.getParentDept() || 0 == item.getParentDept()).collect(Collectors.toList());
    }

    public static List<DepartmentListDTO> buildDeptDTOList(Collection<DepartmentPO> list, List<DepartmentPO> filterList) {
        // 搜索结果为空，直接返回空
        if (CollectionUtils.isEmpty(filterList)) {
            return Collections.emptyList();
        }
        // 递归添加父级数据
        Map<Long, DepartmentPO> poMaps = list.stream().collect(Collectors.toMap(DepartmentPO::getId, item -> item));
        List<DepartmentPO> addedList = new ArrayList<>();
        for (DepartmentPO po : filterList) {
            dealParentData(addedList, po, poMaps);
        }
        return buildDeptDTOList(addedList);
    }

    public static DepartmentPO convertParamsToPO(DeptSearchParam param, long employeeId) {
        if (null == param) {
            return null;
        }
        return DepartmentPO
                .builder()
                .id(param.getId() == null ? 0 : param.getId())
                .deptNo(param.getDeptNo())
                .deptName(param.getDepartmentName())
                .deptNameShort(param.getDeptNameShort())
                .parentComp(null == param.getParentComp() ? param.getSubcompanyid1() : param.getParentComp())
                .ecCompany(param.getEcCompany())
                .parentDept(null == param.getParentDept() ? param.getDepartmentid() : param.getParentDept())
                .ecDepartment(param.getEcDepartment())
                .deptPrincipal(param.getDeptPrincipal())
                .showOrder(param.getShowOrder())
                .forbiddenTag(param.getForbiddenTag() == null ? null : param.getForbiddenTag() ? 0 : 1)
                .description(param.getDescription())
                .deleteType(0)
                .createTime(new Date())
                .updateTime(new Date())
                .creator(employeeId)
                .build();
    }

    public static List<SingleDeptTreeVO> buildSingleDeptTreeVOS(List<DepartmentPO> departmentPOs, Long parentComp) {

        if (CollectionUtils.isEmpty(departmentPOs)) {
            return Collections.emptyList();
        }

        List<SingleDeptTreeVO> singleDeptTreeVOS = departmentPOs.stream().map(e ->
                SingleDeptTreeVO
                        .builder()
                        .id(e.getId())
                        .deptNo(e.getDeptNo())
                        .deptName(e.getDeptName())
                        .parentComp(e.getParentComp())
                        .parentDept(e.getParentDept())
                        .parentDeptName(e.getParentDept() == null ? "" : getDeptNameById(e.getParentDept()))
                        .deptPrincipalName(getEmployeeNameById(e.getDeptPrincipal()))
                        .build()).collect(Collectors.toList());
        //获取非一级部门
        Map<Long, List<SingleDeptTreeVO>> collects = singleDeptTreeVOS.stream().filter(item -> !parentComp.equals(item.getParentComp()) && null != item.getParentDept()).collect(Collectors.groupingBy(SingleDeptTreeVO::getParentDept));

        return singleDeptTreeVOS.stream().peek(e -> e.setChildren(collects.get(e.getId()))).filter(item -> parentComp.equals(item.getParentComp())).collect(Collectors.toList());
    }

    public static List<SearchTree> buildSetToSearchTree(Set<DepartmentPO> departmentPOS) {
        return buildSetToSearchTree(departmentPOS, true);
    }


    public static List<SearchTree> buildSetToSearchTree(Set<DepartmentPO> departmentPOS, boolean isLeaf) {
        return departmentPOS.stream().map(item -> {
            SearchTree tree = new SearchTree();
            tree.setCanClick(true);
            tree.setCanceled(item.getForbiddenTag() != 0);
            tree.setIcon(isLeaf ? "icon-coms-Branch" : "icon-coms-LargeArea");
            tree.setId(item.getId().toString());
            tree.setIsParent(false);
            tree.setIsVirtual("0");
            tree.setName(item.getDeptName());
            tree.setPid(null == item.getParentDept() ? "0" : item.getParentDept().toString());
            tree.setSelected(false);
            tree.setType("2");
            tree.setParentComp(null == item.getParentComp() ? "0" : item.getParentComp().toString());
            tree.setOrderNum(null == item.getShowOrder() ? 0 : item.getShowOrder());
            return tree;
        }).collect(Collectors.toList());
    }


    public static String getDeptNameById(Long id) {
        return MapperProxyFactory.getProxy(DepartmentMapper.class).getDeptNameById(id);
    }

    public static String getEmployeeNameById(Long id) {
        return MapperProxyFactory.getProxy(EmployeeMapper.class).getEmployeeNameById(id);
    }


    /**
     * 递归获取查询后数据的父级数据
     *
     * @param addedList
     * @param po
     * @param poMaps
     */
    private static void dealParentData(List<DepartmentPO> addedList, DepartmentPO po, Map<Long, DepartmentPO> poMaps) {
        if (!addedList.contains(po)) {
            addedList.add(po);
        }
        DepartmentPO parentPO = poMaps.get(po.getParentDept());
        if (null != parentPO) {
            dealParentData(addedList, parentPO, poMaps);
        }
    }


}
