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

import com.engine.organization.entity.company.dto.CompListDTO;
import com.engine.organization.entity.company.param.CompSearchParam;
import com.engine.organization.entity.company.po.CompPO;
import com.engine.organization.entity.searchtree.SearchTree;
import com.engine.organization.mapper.comp.CompMapper;
import com.engine.organization.util.db.MapperProxyFactory;
import org.apache.commons.collections.CollectionUtils;
import weaver.crm.Maint.SectorInfoComInfo;
import weaver.general.StringUtil;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;

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

/**
 * @description:
 * @author:dxfeng
 * @createTime: 2022/05/16
 * @version: 1.0
 */
public class CompBO {

    public static List<CompListDTO> buildCompDTOList(Collection<CompPO> list) {

        Map<Long, CompPO> poMaps = list.stream().collect(Collectors.toMap(CompPO::getId, item -> item));

        List<CompListDTO> dtoList = list.stream().map(e ->
                CompListDTO
                        .builder()
                        .id(e.getId())
                        .compNo(e.getCompNo())
                        .compName(e.getCompName())
                        .compNameShort(e.getCompNameShort())
                        .parentCompany(e.getParentCompany())
                        .parentCompName(null == poMaps.get(e.getParentCompany()) ? "" : poMaps.get(e.getParentCompany()).getCompName())
                        .orgCode(e.getOrgCode())
                        .industry(new SectorInfoComInfo().getSectorInfoname(Util.null2String(e.getIndustry())))
                        .compPrincipal(getUserNameById( Util.null2String(e.getCompPrincipal())))
                        .showOrder(e.getShowOrder())
                        .forbiddenTag(e.getForbiddenTag())
                        .build()).collect(Collectors.toList());
        Map<Long, List<CompListDTO>> collects = dtoList.stream().filter(item -> null != item.getParentCompany() && 0 != item.getParentCompany()).collect(Collectors.groupingBy(CompListDTO::getParentCompany));
        // 处理被引用数据
        List<String> usedIds = MapperProxyFactory.getProxy(CompMapper.class).listUsedId();
        // 兼容MySQL
        usedIds.addAll(MapperProxyFactory.getProxy(CompMapper.class).listUsedIds());
        List<String> collect = Arrays.stream(String.join(",", usedIds).split(",")).collect(Collectors.toList());
        return dtoList.stream().peek(e -> {
            List<CompListDTO> 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.getParentCompany() || 0 == item.getParentCompany()).collect(Collectors.toList());
    }

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

        return buildCompDTOList(addedList);
    }

    public static CompPO convertParamToPO(CompSearchParam param, Long employeeId) {
        if (null == param) {
            return null;
        }
        return CompPO
                .builder()
                .id(param.getId() == null ? 0 : param.getId())
                .compNo(param.getCompNo())
                .compName(param.getCompName())
                .compNameShort(param.getCompNameShort())
                .parentCompany(param.getParentCompany())
                .ecCompany(param.getEcCompany())
                .orgCode(param.getOrgCode())
                .industry(param.getIndustry())
                .compPrincipal(param.getCompPrincipal())
                .description(param.getDescription())
                .forbiddenTag(param.getForbiddenTag() == null ? null : param.getForbiddenTag() ? 0 : 1)
                .deleteType(0)
                .createTime(new Date())
                .updateTime(new Date())
                .creator(employeeId)
                .build();

    }

    public static List<SearchTree> buildSetToSearchTree(Set<CompPO> comps) {
        return comps.stream().sorted(Comparator.comparing(CompPO::getShowOrder)).map(item -> {
            SearchTree tree = new SearchTree();
            tree.setCanClick(true);
            tree.setCanceled(item.getForbiddenTag() != 0);
            tree.setIcon("icon-coms-LargeArea");
            tree.setId(item.getId().toString());
            tree.setIsParent(false);
            tree.setIsVirtual("0");
            tree.setName(item.getCompName());
            tree.setPid(null == item.getParentCompany() ? "0" : item.getParentCompany().toString());
            tree.setSelected(false);
            tree.setType("1");
            tree.setOrderNum(null == item.getShowOrder() ? 0 : item.getShowOrder());
            return tree;
        }).collect(Collectors.toList());
    }

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

    private static String getUserNameById(String userId) {
        try {
            if (StringUtil.isEmpty(userId)) {
                return "";
            }
            return new ResourceComInfo().getLastname(userId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
