package com.ruoyi.ibs.list.domain;

import lombok.Data;

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

@Data
public class TreeNode {

    private Long id;
    private Long parentId;
    private String names;          // 节点标识（level1或level2的值）
    private String type;        // 节点类型："level1" 或 "level2"
    private Boolean useFlag; // 叶子节点（仅level2节点有）
    private Boolean enableFlag;
    private List<TreeNode> children; // 子节点（仅level1节点有）

    public TreeNode(Long id, Long parentId, String names, String type,Boolean useFlag, Boolean enableFlag) {
        this.id = id;
        this.parentId = parentId;
        this.type = type;
        this.names =names;
        this.useFlag = useFlag;
        this.enableFlag = enableFlag;
        this.children = new ArrayList<>();
    }

    // 空构造函数
    public TreeNode() {
        this.children = new ArrayList<>();
    }

    public static List<TreeNode> convertToTree(List<CustTagVo> dtoList) {
        // 缓存所有level1节点（key: level1值）
        Map<String, TreeNode> level1Map = new HashMap<>();
        // 缓存所有level2节点（key: level1+level2的组合键，避免重复）
        Map<String, TreeNode> level2Map = new HashMap<>();

        Map<String, TreeNode> level3Map = new HashMap<>();

        for (CustTagVo dto : dtoList) {
            Long id = dto.getId();
            String level1 = dto.getCustTagLevel1();
            String level2 = dto.getCustTagLevel2();
            String name   = dto.getCustTagName();
            String flag   = dto.getFlag();

            // 1. 处理level1节点（如果不存在则创建）
            TreeNode level1Node = level1Map.get(level1);
            if (level1Node == null) {
                level1Node = new TreeNode(id,null,level1, "level1",true,false);
                level1Map.put(level1, level1Node);
            }

            // 2. 处理level2节点（使用组合键确保唯一性）
            String level2Key = level1 + "_" + level2; // 组合键
            TreeNode level2Node = level2Map.get(level2Key);
            if (level2Node == null) {
                level2Node = new TreeNode(id,null,level2, "level2",true,false);
                level2Map.put(level2Key, level2Node);
                level1Node.getChildren().add(level2Node); // 关联到level1
            }

            String level3Key = level1 + "_" + level2 + "_" + name; // 组合键
            TreeNode level3Node = level3Map.get(level3Key);
            if (level3Node == null) {
                level3Node = new TreeNode(id,null,name, "level3",false,"true".equalsIgnoreCase(flag)?true:false);
                level3Map.put(level3Key, level3Node);
                level2Node.getChildren().add(level3Node); // 关联到level1
            }
        }

        // 转换为列表返回
        return new ArrayList<>(level1Map.values());
    }

    public static List<TreeNode> convertToTreeByParentId(List<CustManualTagVO> tagList) {
        if (tagList == null || tagList.isEmpty()){
            return Collections.emptyList();
        }
        List<TreeNode> nodeList = tagList.stream().map(vo -> {
            TreeNode node = new TreeNode();
            node.setId(vo.getId());
            node.setParentId(vo.getParentId());
            node.setNames(vo.getCustTagName());
            node.setEnableFlag(vo.getFlag() != null && "true".equalsIgnoreCase(vo.getFlag()));
            return node;
        }).collect(Collectors.toList());

//        Map<Long, TreeNode> nodeMap = nodeList.stream().collect(Collectors.toMap(TreeNode::getId, t -> t));
        Map<Long, TreeNode> nodeMap = nodeList.stream()
                .collect(Collectors.toMap(
                        TreeNode::getId,
                        node -> node,
                        (existing, replacement) -> existing  // 保留第一个，丢弃重复的
                ));
        List<TreeNode> roots = new ArrayList<>();
        // 构建树形结构
        for (TreeNode node : nodeMap.values()) {
            Long parentId = node.getParentId();
            if (parentId == null || parentId == 0) {
                roots.add(node);
            } else {
                TreeNode parent = nodeMap.get(parentId);
                if (parent != null) {
                    // 使用Set来避免子节点重复
                    Set<Long> childIds = parent.getChildren().stream()
                            .map(TreeNode::getId)
                            .collect(Collectors.toSet());

                    if (!childIds.contains(node.getId())) {
                        parent.getChildren().add(node);
                    }
                } else {
                    roots.add(node);
                }
            }
        }
        return roots;
    }
}
