/**
 * 数组转换递归
 * @param {Array} list 源数据
 * @returns {Array} 递归数据
 */
export const getListToTree = <T extends { children?: any[] }>(list: T[], {
  parentId = 0,
  idKey = 'id',
  parentKey = 'parentId'
} = {}): T[] => {
  const _list = JSON.parse(JSON.stringify(list))
  const arr: T[] = []
  for (const i in _list) {
    const item: T = _list[i]
    if (parentId === item[parentKey]) {
      const children = getListToTree(_list, {
        parentId: item[idKey], idKey, parentKey
      })
      if (children.length) item.children = children
      arr.push(item)
    }
  }
  return arr
}

/**
 * 数组转换递归
 * @param {Array} arr 源数据
 * @param {Number | String} option.id 节点id
 * @param {Number | String} option.pid 父节点id
 * @param {Function} option.fn
 * @returns {Array} 递归数据
 */
export function getArrayToTree <T>(arr: T[], option: {
  id?: string
  pid?: string
  fn?: (child: T) => void
} = {}): T[] {
  const list: T[] = JSON.parse(JSON.stringify(arr))
  const { id = 'id', pid = 'pid', fn = () => {} } = option
  const map = {}
  list.forEach(v => {
    map[v[id]] = v
  })
  const treeData: T[] = []
  list.forEach((child: T) => {
    if (fn) fn(child)
    const mapItem = map[child[pid]]
    if (mapItem) {
      (mapItem.children || (mapItem.children = [])).push(child)
    } else {
      treeData.push(child)
    }
  })
  return treeData
}

/**
 * 递归转换扁平数组
 * @param {Array} arr 源数据
 * @returns {Array} 递归数据
 */
export function getTreeToArray <T extends { children?: T[] }>(arr: T[]): T[] {
  let list: T[] = []
  arr.forEach((child: T) => {
    list.push(child)
    if (Array.isArray(child.children)) {
      list = [...list, ...getTreeToArray(child.children)]
    }
  })
  return list
}
