/**
 * 从树形数据中根据id匹配节点，并返回该节点及其所有子节点的id数组。常用于表格数据通过树形目录进行筛选
 * @param {Array} tree - 树形数据。
 * @param {number | string} targetId - 目标节点的id。
 * @param {'string' | 'array'} type - 返回结果为逗号分隔字符串还是数组。
 * @return {String | Array} 包含匹配节点及其所有子节点的id的逗号分隔字符串或数组。
 * @example
 * findNodeAndChildrenIds([
 *   {id:'',children:[{id:'1'} , {id:'2'}]}
 * ],'xxx')
 */
export function findNodeAndChildrenIds(
  tree = [],
  targetId = '',
  type = 'string'
) {
  let ids = []

  // 收集节点及其子节点的所有id
  function collectIds(node) {
    ids.push(node.id)
    if (node.children && node.children.length > 0) {
      for (const child of node.children) {
        collectIds(child)
      }
    }
  }

  // 遍历树形数据找到目标节点
  function traverse(nodes) {
    for (const node of nodes) {
      if (node.id === targetId) {
        // 找到目标节点，开始收集id
        collectIds(node)
        return true // 停止遍历，因为已经找到目标节点
      }
      if (node.children && node.children.length > 0) {
        const found = traverse(node.children)
        if (found) return true // 如果在子节点中找到目标，停止遍历
      }
    }
    return false // 当前分支没有找到目标节点
  }

  traverse(tree)
  return type === 'string' ? ids.join(',') : ids
}

/**
 * 递归函数：通过指定字段和id查询某一层级的数据
 * @param {Array} tree - 树形数据。
 * @param {number | string} identifier - 目标节点的唯一标识符键值。
 * @param {string} fieldName - 目标节点的唯一标识符键名。
 * @return {Object} 匹配层级的数据
 * @example
 * findDataByField([
 *   {id:'',children:[{id:'1'} , {id:'2'}]}
 * ],'1')
 */
export function findDataByField(tree, identifier, fieldName = 'id') {
  for (let node of tree) {
    if (node[fieldName] === identifier) {
      return node
    }
    if (node.children) {
      const result = findDataByField(node.children, identifier, fieldName)
      if (result) {
        return result
      }
    }
  }
  return null
}
