function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
// @ts-nocheck
/**
 * @description  递归查看父级节点数据集合及当前节点数据
 * @params {Array}  list 当前需要过滤查看的数据集合、
 * @params {String/Array} nodeKey 当前用于查找匹配数据的标识值
 * @params {Object} params 指定当前数据中，筛选对应子集合字段名及匹配标识值字段名
 *                         （childrenParam：指当前子集合数据字段名（字符串表示单个，数组表示当前多个子集合字段名），keyParam： 指当前匹配标识值字段名）
 * @params {Object} extra
 *
 * @result {Array} nodeParent  当前传入nodeKey值所有上级别父级数据对象数组集合（倒序排列，根节点在最后一条）
 * @result {Array} parentKeys  当前传入nodeKey值所有上级别父级数据关键字数据集合(keyParam)（倒序排列，根节点在最后一条）
 * @result {Array} matchNode   当前传入nodeKey值所在的数据对象集合
 * */
export var getParentNodes = function getParentNodes(list, nodeKey) {
  var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
    childrenParam: 'children',
    keyParam: 'value'
  };
  var extraProps = arguments.length > 3 ? arguments[3] : undefined;
  // firstExtra 对应 rule值 SHOW_PARENT,SHOW_CHILD,SHOW_ALL 这几个值是由 'tree-select'控件配置返回的
  // const childrenParams = ['menuItems', 'menuFuncItems', 'items']
  var matchNode = [];
  var parentKeys = []; // 存储查找到的节点的父节点数据
  var nodeParent = []; // 存储查找到的节点的父节点数据
  // 移除上一次累加的数据
  var removePrevIndex = function removePrevIndex(array, item) {
    for (var i = 0; i < array.length; i += 1) {
      if (array[i][params.keyParam] === item[params.keyParam]) {
        return i;
      }
    }
    return null;
  };
  var deepFind = function deepFind(array, nodeId) {
    for (var i = 0; i < array.length; i += 1) {
      var node = array[i];
      if (node[params.keyParam] === nodeId) {
        matchNode.splice(0, 1, node); // 查找到则赋值，且跳出循环
        break;
      }
      // 如果是单个
      if (node[params.childrenParam] && node[params.childrenParam].length > 0) {
        deepFind(node[params.childrenParam] || node[params.childrenParam], nodeId);
        nodeParent.push(node); // 将当前节点数据存储到父节点数据中
        if (matchNode.length > 0) {
          break; // 在子节点查找到了，需要跳出
        } else {
          nodeParent.splice(removePrevIndex(nodeParent, node), 1); // 如果在子节点没有查找到，则将原来添加的父节点数据移除
        }
      }
      // 其他条件
      /* else if (node.menuFuncItems && node.menuFuncItems.length > 0) {
        deepFind(node.menuFuncItems, nodeId);
        nodeParent.push(node); // 将当前节点数据存储到父节点数据中
        if (matchNode.length > 0) {
          break; // 在子节点查找到了，需要跳出
        } else {
          nodeParent.splice(removePrevIndex(nodeParent, node), 1); // 如果在子节点没有查找到，则将原来添加的父节点数据移除
        }
      } else if (node.items && node.items.length > 0) {
        // 数据权限的子菜单集合 items
        deepFind(node.items, nodeId);
        nodeParent.push(node); // 将当前节点数据存储到父节点数据中
        if (matchNode.length > 0) {
          break; // 在子节点查找到了，需要跳出
        } else {
          nodeParent.splice(removePrevIndex(nodeParent, node), 1); // 如果在子节点没有查找到，则将原来添加的父节点数据移除
        }
      } else if (node.dataScopeList && node.dataScopeList.length > 0) {
        // 数据权限的子菜单集合 dataScopeList
        deepFind(node.dataScopeList, nodeId);
        nodeParent.push(node); // 将当前节点数据存储到父节点数据中
        if (matchNode.length > 0) {
          break; // 在子节点查找到了，需要跳出
        } else {
          nodeParent.splice(removePrevIndex(nodeParent, node), 1); // 如果在子节点没有查找到，则将原来添加的父节点数据移除
        }
      }*/
    }
    return matchNode; // 返回查找到的节点数据（格式为数组）
  };

  // 查找单个节点
  var findMatchItem = function findMatchItem(arrList, key) {
    var matchItem;
    for (var i = 0; i < arrList.length; i += 1) {
      var node = arrList[i];
      if (node[params.keyParam] === key) {
        matchItem = node;
        break;
      }
      if (node[params.childrenParam]) {
        matchItem = findMatchItem(node[params.childrenParam], key);
      }
    }
    return matchItem;
  };
  // nodeKey 为数组时返回当前数据（TODO。目前仅返回一级，多级情况未判断，且 nodeParent 值也未调整）
  if (Array.isArray(nodeKey)) {
    // const {showCheckedStrategy} = extraProps;
    // TODO 需要判断 showCheckedStrategy 值为 SHOW_PARENT、 SHOW_CHILD 、SHOW_ALL不同情况展示
    nodeKey.map(function (key) {
      var matchItem = findMatchItem(list, key);
      if (matchItem) matchNode.push(findMatchItem(list, key));
    });
  } else {
    deepFind(list, nodeKey);
  }
  nodeParent.forEach(function (par) {
    return parentKeys.push(par[params.keyParam]);
  }); // 将所有父节点的关键值（keyParam指定字段名）的数据集合在数组内
  return {
    nodeParent: nodeParent,
    parentKeys: parentKeys,
    matchNode: matchNode
  }; // 最终查找到的父节点数组 // nodeParent.concat(result || []);
};

/**
 * @description  递归查找指定节点的所有子菜单与子功能集合
 * @params {Array}  childNode 当前需要过滤查看的子数据集合、
 * @params {Object} params 指定当前数据中，筛选对应子集合字段名及匹配标识值字段名
 *                         （childrenParam：指当前子集合数据字段名（字符串表示单个，数组表示当前多个子集合字段名），keyParam： 指当前匹配标识值字段名）
 * @params {Object} extra
 *
 * @result {Array} childKeys  所有子项的id
 * @result {Array} nodeChildren   当前传入nodeKey值所在的数据对象集合
 * */

export var getChildrenNodes = function getChildrenNodes(childNode) {
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
    childrenParam: 'children',
    keyParam: 'value'
  };
  var childKeys = [];
  var nodeChildren = []; // 存储：authId, types
  var deepFindChild = function deepFindChild(cList) {
    Array.isArray(cList) && cList.forEach(function (item) {
      childKeys.push(item[params.keyParam]);
      nodeChildren.push(item);
      if (item[params.childrenParam]) deepFindChild(item[params.childrenParam]);
    });
  };
  deepFindChild(childNode);
  return {
    childKeys: childKeys,
    nodeChildren: nodeChildren
  };
};

/**
 * @description  查找指定节点或节点集合的完整路径数据
 * @params {Array}  list 查询的数据源
 * @params {Array | String | Number}  nodeKey 需要查询的key集合
 * @params {Object} params 指定当前数据中，筛选对应子集合字段名及匹配标识值字段名
 *                         （childrenParam：指当前子集合数据字段名（字符串表示单个，数组表示当前多个子集合字段名），keyParam： 指当前匹配标识值字段名）
 *
 * @result {Array} 所有匹配到的层级数据(如果nodeKey是数组，则返回的节点集合会分别按顺序存到数组内
 *
 * */
export var getNodePaths = function getNodePaths(list, nodeKey) {
  var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
    childrenParam: 'children',
    keyParam: 'value'
  };
  var extraProps = arguments.length > 3 ? arguments[3] : undefined;
  // 获取指定节点的路径数组
  var getPathByKey = function getPathByKey(value, arr) {
    var findNodePath = function findNodePath(node, value, nodePathArray) {
      // 这里可以自定义push的内容，而不是整个node,而且这里node也包含了children
      nodePathArray.push(node);
      // 找到符合条件的节点，通过throw终止掉递归
      if (node[params.keyParam] === value) {
        // 也可以直接使用return;结束循环
        throw "over!";
      }
      if (node[params.childrenParam] && node[params.childrenParam].length > 0) {
        for (var i = 0; i < node[params.childrenParam].length; i++) {
          findNodePath(node[params.childrenParam][i], value, nodePathArray);
        }
        // 当前节点的子节点遍历完依旧没找到，则删除路径中的该节点
        nodePathArray.pop();
      } else {
        // 找到叶子节点时，删除路径当中的该叶子节点
        nodePathArray.pop();
      }
    };

    // 用于存储节点唯一标识值路径数组
    var nodePathArray = [];
    try {
      for (var i = 0; i < arr.length; i++) {
        findNodePath(arr[i], value, nodePathArray);
      }
    } catch (e) {
      return nodePathArray;
    }
  };
  var pathNode = [];
  if (Array.isArray(nodeKey)) {
    nodeKey.map(function (key) {
      var pathItems = getPathByKey(key, list);
      if (pathItems) pathNode.push(pathItems);
    });
  } else if (typeof nodeKey === 'string') {
    var pathItems = getPathByKey(nodeKey, list);
    pathNode = pathItems || [];
  }
  return pathNode;
};

/**
 * @description  查找节点数据：点击获取对应ID的完整数据（即从树数据中深层查找与ID值相匹配的相关数据对象）
 *
 * @param [array] list 需要过滤的数据
 * @param [string] key 指定过滤的key值
 * @param [Object] optionName 指定value与children相关字段名
 *
 * @data list:<array:[{ value: '', label: '', children: []}]> 列表数据格式
 */
export var getNode = function getNode(list, key) {
  var optionName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
    value: 'value',
    children: 'children'
  };
  var matchCurrentItem = {};
  // 深层过滤当前选中的节点
  var deepFilterMatchItem = function deepFilterMatchItem(treeData, targetId) {
    (treeData || []).some(function (item) {
      if (item[optionName.value] == targetId) {
        matchCurrentItem = item;
        return true;
      }
      if (item[optionName.children]) {
        deepFilterMatchItem(item[optionName.children], targetId); // 没有查找到继续过滤
      }
    });
  };
  deepFilterMatchItem(list, key);
  return matchCurrentItem;
};

/**
 * 数组转树形结构
 * @param {array} list 被转换的数组
 * @param {number|string} root 根节点（最外层节点）的 id
 * @param {object} params 字段值（默认 { keyParam: 'id', parentParam: 'parentId' }）
 * @return array
 */

export var arrayToTree = function arrayToTree(list, rootId) {
  var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
    _ref$keyParam = _ref.keyParam,
    keyParam = _ref$keyParam === void 0 ? "id" : _ref$keyParam,
    _ref$parentParam = _ref.parentParam,
    parentParam = _ref$parentParam === void 0 ? "parentId" : _ref$parentParam,
    _ref$childrenParam = _ref.childrenParam,
    childrenParam = _ref$childrenParam === void 0 ? "children" : _ref$childrenParam;
  var res = [];
  list.forEach(function (item) {
    if (item[parentParam] === rootId) {
      var itemChildren = arrayToTree(list, item[keyParam]);
      if (itemChildren.length) item[childrenParam] = itemChildren;
      res.push(item);
    }
  });
  return res;
};
/**
 * 多根树转换成数组
 * @param {array} tree 被转换的树（仅限于只有一个根的树
 * @return array
 */
export var convertToArray = function convertToArray(tree) {
  var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
    _ref2$keyParam = _ref2.keyParam,
    keyParam = _ref2$keyParam === void 0 ? "id" : _ref2$keyParam,
    _ref2$parentParam = _ref2.parentParam,
    parentParam = _ref2$parentParam === void 0 ? "parentId" : _ref2$parentParam,
    _ref2$childrenParam = _ref2.childrenParam,
    childrenParam = _ref2$childrenParam === void 0 ? "children" : _ref2$childrenParam;
  var result = []; // 存放结果的数组
  var sortCount = 0;
  tree.forEach(function (item) {
    var loop = function loop(data) {
      sortCount++;
      result.push(_objectSpread(_objectSpread({}, data), {}, {
        sort: sortCount
      }));
      var child = data[childrenParam];
      if (child) {
        for (var i = 0; i < child.length; i++) {
          loop(child[i]);
        }
      }
    };
    loop(item);
  });
  return result;
};

/**
 * 树过滤（默认按名称过滤，也可按指定的字段名过滤）
 * @param {array} list 需要过滤的树
 * @param {string | number} nodeKey 需要筛选的名称（默认搜索名称，如果需要指定其他字段值，则参数传object
 * @param {object} params 指定当前数据中，筛选对应子集合字段名及匹配标识值字段名
 *  @value { childrenParam: 'children',  keyParam: 'name' }  childrenParam：指当前子集合数据字段名，keyParam： 指当前匹配标识值字段名）
 *
 * @return array  返回新的数组
 * */
export var filterTreeNodes = function filterTreeNodes(list, nodeKey) {
  var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
    childrenParam: 'children',
    keyParam: 'name'
  };
  var result = [];
  var filterList = _toConsumableArray(list);
  filterList.forEach(function (item) {
    var _item, _item$toLowerCase;
    var nItem = null;
    if ((((_item = item[params.keyParam || 'name']) === null || _item === void 0 || (_item$toLowerCase = _item.toLowerCase) === null || _item$toLowerCase === void 0 ? void 0 : _item$toLowerCase.call(_item)) || '').includes(nodeKey === null || nodeKey === void 0 ? void 0 : nodeKey.toLowerCase())) {
      nItem = _objectSpread(_objectSpread({}, item), {}, _defineProperty({}, params.childrenParam || 'children', []));
    }
    if (item[params.childrenParam || 'children'] && item[params.childrenParam || 'children'].length) {
      var subList = filterTreeNodes(item[params.childrenParam || 'children'], nodeKey, params);
      if (subList.length) {
        nItem = _objectSpread(_objectSpread({}, item), {}, _defineProperty({}, params.childrenParam || 'children', subList));
      }
    }
    if (nItem) {
      result.push(nItem);
    }
  });
  return result;
};

// 给节点每个层级加上level，并且将当前节点完整的路径序号值拼接起来
/**
 * @param {Array} data 树数组数据
 * @param {Number} level 起始层级序号
 * @param {Number} level 起始层级序号
 * @param {Array} parentIndexPath 父级序号集合
 * @param {Array} parentNamePath 父级名称集合
 * @param {Object} optionName 指定字段名 {children: '', label: '', title: '', name: ''}
 * @param {Object} extra 扩展配置 {separator: '/'}
 * */
export var addTreeLevels = function addTreeLevels(data) {
  var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  var parentIndexPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
  var parentNamePath = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
  var optionName = arguments.length > 4 ? arguments[4] : undefined;
  var extra = arguments.length > 5 ? arguments[5] : undefined;
  if (!Array.isArray(data)) return [];
  return data.map(function (item, index) {
    // 创建当前节点副本
    // 完整的名称路径
    var fullNamePath = _toConsumableArray(parentNamePath).concat(item[(optionName === null || optionName === void 0 ? void 0 : optionName.title) || (optionName === null || optionName === void 0 ? void 0 : optionName.label) || 'label' || 'title'] ? [item[(optionName === null || optionName === void 0 ? void 0 : optionName.title) || (optionName === null || optionName === void 0 ? void 0 : optionName.label) || 'label' || 'title']] : []);
    var node = _objectSpread(_objectSpread({}, item), {}, {
      treeNodeLevel: level,
      treeParentIndexPath: _toConsumableArray(parentIndexPath),
      // 存储父级索引路径
      treeParentNamePath: _toConsumableArray(parentNamePath),
      treeFullLevelNamePath: fullNamePath,
      treeFullLevelName: fullNamePath.join((extra === null || extra === void 0 ? void 0 : extra.separator) || '/')
    });
    // 当前节点的完整路径（用于构建子节点的父级路径）
    var currentIndexPath = [].concat(_toConsumableArray(parentIndexPath), [index]);
    var currentNamePath = [].concat(_toConsumableArray(parentNamePath), [item[(optionName === null || optionName === void 0 ? void 0 : optionName.title) || (optionName === null || optionName === void 0 ? void 0 : optionName.label) || 'label' || 'title']]);

    // 递归处理子节点
    if (Array.isArray(node[(optionName === null || optionName === void 0 ? void 0 : optionName.children) || 'children']) && node[(optionName === null || optionName === void 0 ? void 0 : optionName.children) || 'children'].length > 0) {
      node[(optionName === null || optionName === void 0 ? void 0 : optionName.children) || 'children'] = addTreeLevels(node[(optionName === null || optionName === void 0 ? void 0 : optionName.children) || 'children'], level + 1, currentIndexPath, currentNamePath, optionName, extra);
    }
    return node;
  });
};

/**
 * @description  获取树数据中所有叶子节点的上层节点路径（用于antd树组件的expandedKeys配置）
 * @params {Array}  list 树数据集合
 * @params {Object} params 指定当前数据中，子集合字段名及标识值字段名
 *                         （childrenParam：指当前子集合数据字段名，keyParam： 指当前匹配标识值字段名）
 * @params {Object} extra 额外配置
 *
 * @result {Array} leafParentKeys 所有叶子节点的上层节点key集合（去重后的数组）
 * @result {Array} leafNodes 所有叶子节点本身
 * @result {Array} leafNodesKeys 所有叶子节点的key集合
 * @result {Array} leafParentPaths 所有叶子节点的完整上层路径数组
 *
 * 用法：
 * const { leafParentKeys, leafNodes , leafNodesKeys, leafParentPaths} = getLastLeafParentNodes(treeList, { childrenParam: 'children', keyParam: 'id' })
 */

export var getLastLeafParentNodes = function getLastLeafParentNodes() {
  var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
    childrenParam: 'children',
    keyParam: 'value'
  };
  var extra = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var leafNodes = []; // 存储所有叶子节点
  var leafParentPaths = []; // 存储所有叶子节点的完整上层路径
  var expandedKeysSet = new Set(); // 用于去重的expandedKeys集合

  // 递归遍历树，找到所有叶子节点及其上层路径
  var traverseTree = function traverseTree(nodes) {
    var parentPath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
    if (!nodes || !Array.isArray(nodes)) return;
    nodes.forEach(function (node) {
      var currentPath = [].concat(_toConsumableArray(parentPath), [node]);

      // 检查是否是叶子节点（children为空或无值）
      var children = node[params.childrenParam];
      var isLeaf = !children || Array.isArray(children) && children.length === 0;
      if (isLeaf) {
        // 这是叶子节点
        leafNodes.push(node);

        // 获取完整上层路径（排除当前叶子节点本身）
        if (parentPath.length > 0) {
          leafParentPaths.push(_toConsumableArray(parentPath));

          // 将上层路径中的所有节点的key添加到expandedKeys集合中
          parentPath.forEach(function (parentNode) {
            var key = parentNode[params.keyParam];
            if (key !== undefined && key !== null) {
              expandedKeysSet.add(key);
            }
          });
        }
      } else {
        // 递归遍历子节点
        traverseTree(children, currentPath);
      }
    });
  };

  // 开始遍历
  traverseTree(list);

  // 将Set转换为数组
  var expandedKeys = Array.from(expandedKeysSet);
  return {
    leafNodes: leafNodes,
    // 所有叶子节点本身
    leafNodesKeys: leafNodes.map(function (item) {
      return item[params.keyParam];
    }),
    // 所有叶子节点的key集合
    leafParentKeys: expandedKeys,
    // 所有叶子节点的上层节点key集合（去重后的数组）
    leafParentPaths: leafParentPaths // 所有叶子节点的完整上层路径数组
  };
};