class TreeNode {
  /// 元数据
  dynamic data;

  /// 展示数据
  String title = '';

  /// 是否选择 三态支持 空的时候为半选
  bool? isChecked = false;

  /// 子节点
  List<TreeNode> children = [];

  /// 父节点
  TreeNode? parent;

  /// 展开
  bool expand = false;

  /// 是否可以展开
  bool canExpand = false;

  /// 是否可以选择
  bool canCheck = false;

  /// 是否禁用
  bool isForbid = false;

  bool hasKey(String key) {
    return title.contains(key) || childHasKey(key);
  }

  bool childHasKey(String key) {
    for (var child in children) {
      if (child.hasKey(key)) {
        return true;
      }
    }
    return false;
  }

  List<dynamic> getCheckedData() {
    List<dynamic> result = [];
    if (isChecked == true && !isForbid) {
      result.add(data);
    }
    for (var node in children) {
      result.addAll(node.getCheckedData());
    }
    return result;
  }

  void checkParent() {
    parent?.isChecked = true;
    parent?.checkParent();
  }

  /// 数据转换
  static List<TreeNode> formatNodes(
    List<dynamic>? elements,
    String childKey,
    TreeNode Function(dynamic) format, {
    TreeNode? parent,
  }) {
    List<TreeNode> nodes = [];
    elements?.forEach((element) {
      TreeNode node = format(element);
      node.children =
          formatNodes(element[childKey], childKey, format, parent: node);
      node.canExpand = node.canExpand && node.children.isNotEmpty;
      node.parent = parent;
      nodes.add(node);
    });
    return nodes;
  }

  static List<TreeNode> searchNode(List<TreeNode> nodes, String key) {
    List<TreeNode> result = [];
    for (var node in nodes) {
      if (node.title.contains(key)) {
        result.add(node);
      }
      result.addAll(searchNode(node.children, key));
    }
    return result;
  }
}
