package com.njcn.gather.tool.addledger.component;

import com.njcn.gather.tool.addledger.pojo.constant.AddLedgerConst;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据台账树组装器。
 */
@Component
public class AddLedgerTreeBuilder {

    public List<AddLedgerTreeNodeVO> buildTree(List<AddLedgerLedgerPO> ledgers) {
        Map<String, AddLedgerTreeNodeVO> nodeMap = new LinkedHashMap<String, AddLedgerTreeNodeVO>();
        if (ledgers == null || ledgers.isEmpty()) {
            return new ArrayList<AddLedgerTreeNodeVO>();
        }
        for (AddLedgerLedgerPO ledger : ledgers) {
            AddLedgerTreeNodeVO node = new AddLedgerTreeNodeVO();
            node.setId(ledger.getId());
            node.setParentId(ledger.getPid());
            node.setParentIds(ledger.getPids());
            node.setName(ledger.getName());
            node.setLevel(ledger.getLevel());
            node.setSort(ledger.getSort());
            nodeMap.put(node.getId(), node);
        }
        List<AddLedgerTreeNodeVO> roots = new ArrayList<AddLedgerTreeNodeVO>();
        for (AddLedgerTreeNodeVO node : nodeMap.values()) {
            AddLedgerTreeNodeVO parent = nodeMap.get(node.getParentId());
            if (parent == null || AddLedgerConst.ROOT_PARENT_ID.equals(node.getParentId())) {
                roots.add(node);
            } else {
                parent.getChildren().add(node);
            }
        }
        sortTree(roots);
        return roots;
    }

    private void sortTree(List<AddLedgerTreeNodeVO> nodes) {
        nodes.sort(Comparator.comparing(AddLedgerTreeNodeVO::getSort, Comparator.nullsLast(Integer::compareTo))
                .thenComparing(AddLedgerTreeNodeVO::getName, Comparator.nullsLast(String::compareTo)));
        for (AddLedgerTreeNodeVO node : nodes) {
            sortTree(node.getChildren());
        }
    }
}
