/**
 * 判断当前模块是否是目标模块的子模块
 * @param {Object} target 目标模块
 * @param {Object} current 当前模块
 * @param {Function} [predicate=(target, current) => target.id === current.id] 每次迭代调用的断言函数
 * @returns
 */
const isAncestor = (
  target,
  current,
  predicate = (target, current) => target.id === current.id
) => {
  if (!(current && current.id && target.children && target.children.length)) {
    return false
  }
  return target.children.some(child => {
    if (predicate(child, current)) {
      return true
    }
    if (child.children && child.children.length) {
      return isAncestor(child, current)
    }
    return false
  })
}

const listToTree = (list, options) => {
  const { key = 'id', parent = 'parentId', children = 'children' } =
    options || {}
  let info = list.reduce((map, node) => {
    map[node[key]] = node
    node[children] = []
    return map
  }, {})
  return list.filter(node => {
    info[node[parent]] && info[node[parent]][children].push(node)
    return !node[parent]
  })
}

/**
 * 树转换为列表，递归实现
 * @param {Array} tree 树结构
 * @param {Array} [result=[]] 初始结果列表
 * @returns
 */
const treeToList = (tree, result = []) => {
  tree.forEach(node => {
    result.push(node)

    node.children && treeToList(node.children, result)
  })
  return result
}

/**
 * 通过value值获取对应的label值
 * @param {Array} tree 列表
 * @param {any} value 值
 * @param {string} [labelKey='name'] label对应的键名称
 * @param {string} [valueKey='code'] value对于的键名称
 * @param {string} [valueKey='value'] value对于的键名称
 */
const getTreeLabelByValue = ({
  tree,
  value,
  labelKey = 'name',
  valueKey = 'code',
  childrenKey = 'children',
}) => {
  // 待优化  辣鸡
  let label
  const findValueByTree = ({
    tree,
    value,
    labelKey,
    valueKey,
    childrenKey,
  }) => {
    if (!Array.isArray(tree)) {
      return false
    }
    for (let i = 0; i < tree.length; i++) {
      const item = tree[i]
      if (item[valueKey] === value && !item[childrenKey]) {
        label = item[labelKey]
        return label
      } else if (item[childrenKey] && Array.isArray(item[childrenKey])) {
        findValueByTree({
          tree: item[childrenKey],
          value,
          labelKey,
          valueKey,
          childrenKey,
        })
      }
    }
  }
  findValueByTree({
    tree,
    value,
    labelKey,
    valueKey,
    childrenKey,
  })
  return label
}

export { isAncestor, listToTree, treeToList, getTreeLabelByValue }
