package cn.iocoder.yudao.module.order.vo.orderGuanlian;

import lombok.Data;

import java.util.*;

@Data
public class OrderTree {

    @Data
    public static class Order {
        private String orderNo;
        private TreeSet<String> relateOrderNos;

        public Order(String orderNo, TreeSet<String> relateOrderNos) {
            this.orderNo = orderNo;
            this.relateOrderNos = relateOrderNos;
        }
    }

    private Order order;
    private List<OrderTree> children;

    public OrderTree(Order order) {
        this.order = order;
        this.children = new ArrayList<>();
    }

    public void addChild(OrderTree child) {
        this.children.add(child);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("订单(").append(order.getOrderNo()).append(", 关联订单").append(order.getRelateOrderNos()).append(")");

        if (!children.isEmpty()) {
            sb.append("<br>");
            for (OrderTree child : children) {
                sb.append("|--- ").append(child.toString()).append("<br>");
            }
        }

        return sb.toString();
    }

    public static OrderTree buildTree(List<OrderRelation> relations, String rootNo) {
        Map<String, OrderTree> orderMap = new HashMap<>();
        Map<String, TreeSet<String>> relationMap = new HashMap<>();

        for (OrderRelation relation : relations) {
            relationMap.computeIfAbsent(relation.getOrderNo(), k -> new TreeSet<>()).add(relation.getRelateOrderNo());
            relationMap.computeIfAbsent(relation.getRelateOrderNo(), k -> new TreeSet<>()).add(relation.getOrderNo());
        }

        Queue<String> queue = new LinkedList<>();
        queue.add(rootNo);

        while (!queue.isEmpty()) {
            String currentNO = queue.poll();

            Order currentOrder = new Order(currentNO, relationMap.getOrDefault(currentNO, new TreeSet<>()));
            OrderTree currentTree = orderMap.computeIfAbsent(currentNO, k -> new OrderTree(currentOrder));

            for (String relateOrderNo : relationMap.getOrDefault(currentNO, new TreeSet<>())) {
                if (orderMap.containsKey(relateOrderNo)) {
                    continue;
                }

                Order relateOrder = new Order(relateOrderNo, relationMap.getOrDefault(relateOrderNo, new TreeSet<>()));
                OrderTree relateTree = new OrderTree(relateOrder);

                currentTree.addChild(relateTree);
                orderMap.put(relateOrderNo, relateTree);

                queue.add(relateOrderNo);
            }
        }

        return orderMap.get(rootNo);
    }



    @Data
    public static class OrderRelation {
        private String orderNo;
        private String relateOrderNo;

        public OrderRelation(String orderNo, String relateOrderNo) {
            this.orderNo = orderNo;
            this.relateOrderNo = relateOrderNo;
        }


    }
}
