from typing import List, Dict, Any, Callable
import copy


class TreeUtil:
    """
    树结构工具类
    """

    @staticmethod
    def list_to_tree(lists: List[Dict[str, Any]], config: Dict[str, Any] = None) -> List[Dict[str, Any]]:
        """
        数组转树结构
        :param lists: 原始列表数据
        :param config: 配置参数
        :return: 树结构数据
        """
        if config is None:
            config = {}

        config.setdefault("id", "id")
        config.setdefault("parent_id", "parent_id")
        config.setdefault("children", "children")

        map_dict = {}
        filtered_list = []

        for item in lists:
            if "level" in config and "init_level" in config and config.get("level") in item:
                if item[config["level"]] < config["init_level"]:
                    continue
            filtered_item = copy.deepcopy(item)
            map_dict[str(filtered_item[config["id"]])] = filtered_item
            filtered_list.append(filtered_item)

        tree = []
        for item in filtered_list:
            if "level" in config and "init_level" in config and config.get("level") in item:
                if item[config["level"]] < config["init_level"]:
                    continue

            parent_id = None
            if str(item[config["parent_id"]]) in map_dict:
                parent_id = item[config["parent_id"]]
            else:
                if "full_id" in config and config["full_id"] in item:
                    ids = item[config["full_id"]].split(",")
                    for id_val in ids:
                        if str(item[config["id"]]) != str(id_val) and str(id_val) in map_dict:
                            parent_id = id_val

            if parent_id is not None:
                if config["children"] not in map_dict[str(parent_id)]:
                    map_dict[str(parent_id)][config["children"]] = []
                map_dict[str(parent_id)][config["children"]].append(item)
            else:
                tree.append(item)
        return tree

    @staticmethod
    def tree_to_list(tree: List[Dict[str, Any]], config: Dict[str, Any] = None) -> List[Dict[str, Any]]:
        """
        树结构转数组
        :param tree: 树结构数据
        :param config: 配置参数
        :return: 列表数据
        """
        if config is None:
            config = {}

        config.setdefault("children", "children")
        config.setdefault("unset_children", True)

        def list_handle(tree_data, conf, handler):
            result = []
            for item in tree_data:
                new_item = copy.deepcopy(item)
                if conf["children"] in new_item:
                    children = new_item[conf["children"]]
                    if conf.get("unset_children", True):
                        del new_item[conf["children"]]
                else:
                    children = None

                result.append(new_item)
                if isinstance(children, list):
                    result.extend(handler(children, conf, handler))
            return result

        return list_handle(tree, config, list_handle)

    @staticmethod
    def get_max_depth(tree: List[Dict[str, Any]], config: Dict[str, Any] = None) -> int:
        """
        获取树节点的最大深度
        :param tree: 树结构数据
        :param config: 配置参数
        :return: 最大深度
        """
        if config is None:
            config = {}

        config.setdefault("id", "id")
        config.setdefault("children", "children")

        def calculate_depth(nodes: List[Dict[str, Any]], current_depth: int) -> int:
            if not nodes:
                return current_depth

            local_max = current_depth
            for node in nodes:
                children = node.get(config["children"], [])
                if isinstance(children, list) and children:
                    child_depth = calculate_depth(children, current_depth + 1)
                    local_max = max(local_max, child_depth)

            return local_max

        max_depth = calculate_depth(tree, 1) if tree else 0
        return max_depth
