/**
 * 解析blob响应内容并下载
 * @param {*} res blob响应内容
 * @param {String} mimeType MIME类型
 */
export function resolveBlob(res) {
  const aLink = document.createElement('a')
  var blob = new Blob([res.data])
  // //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
  var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
  var contentDisposition = decodeURI(res.headers['content-disposition'])
  var result = patt.exec(contentDisposition)
  var fileName = result[1]
  fileName = fileName.replace(/\"/g, '')
  aLink.href = URL.createObjectURL(blob)
  aLink.setAttribute('download', fileName) // 设置下载文件名称
  document.body.appendChild(aLink)
  aLink.click()
  document.body.removeChild(aLink)
}

/**
 * 设置 localStorage Item
 * @param key 键
 * @param value值
 * 使用方法 setItem(token,xxxx)
 */
export const setItem = (key, value) => {
  if (typeof value === 'object') {
    value = JSON.stringify(value)
  }
  window.localStorage.setItem(key, value)
}

/**
 * 获取 localStorage Item
 * @param key 键
 * 使用方法 getItem(token)
 */
export const getItem = (key) => {
  const data = window.localStorage.getItem(key)
  try {
    if (data) return JSON.parse(data)
  } catch (err) {
    return data
  }
}

/**
 * 移除 localStorage Item
 * @param key 键
 * 使用方法 removeItem(token)
 */
export const removeItem = (key) => {
  window.localStorage.removeItem(key)
}

/**
 * 移除所有 localStorage Item
 * @param key 键
 * 使用方法 removeAllItem()
 */
export const removeAllItem = () => {
  window.localStorage.clear()
}

/**
 * 防抖
 * @param fn 需要包装的函数
 * @param delay 延迟时间，单位ms
 * 使用方法 const debounceTask = debounce(task, 1000)
 */
export const debounce = (fn, delay) => {
  let timer
  return (...args) => {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

/**
 * 节流
 * @param fn 需要包装的函数
 * @param delay 时间，单位ms 多少ms 执行一次
 * 使用方法 const throttleTask = throttle(task, 1000)
 */
export const throttle = (fn, delay) => {
  let timer
  return (...args) => {
    if (timer) return
    timer = setTimeout(() => {
      fn.apply(this, args)
      timer = null
    }, delay)
  }
}

/**
 * 将字符串复制到剪切板
 * @param t 需要复制的文字
 * 使用方法 copyText(t).then(()=>{})
 */

export const copyText = (t) => {
  return new Promise((resolve, reject) => {
    try {
      const input = document.createElement('textarea')
      input.value = t
      document.body.appendChild(input)
      input.select()
      document.execCommand('copy')
      input?.parentElement?.removeChild(input)
      resolve(t)
    } catch (e) {
      reject(e)
    }
  })
}

/**
 * 返回指定长度的字符串
 * @param n 长度
 * 使用方法 const text = randomString(9)
 */
export const randomString = (n) => {
  const str = 'abcdefghijklmnopqrstuvwxyz9876543210'
  let tmp = ''
  const l = str.length
  for (let i = 0; i < n; i++) {
    tmp += str.charAt(Math.floor(Math.random() * l))
  }
  return tmp
}

/**
 * 数组去重
 * @param arr 需要去重的数组
 * 使用方法 const newArr = unique([1,1,2,3])
 */
export const unique = (arr) => Array.from(new Set(arr))

/**
 * 回到顶部
 * 使用方法  goToTop();
 */

export const goToTop = () => window.scrollTo(0, 0)

/**
 * 校验数组是否为空
 * @param arr 需要效验的数组
 * 使用方法 isNotEmpty([1, 2, 3]); Result: true
 */

export const isNotEmpty = (arr) => Array.isArray(arr) && arr.length > 0

/**
 * 判断数组 字符 对象是否为空
 * @param {*}  data 传入的数据
 * @returns true or false
 */

export const isNull = (data) => {
  if (!data) return true
  if (JSON.stringify(data) === '{}') return true
  if (JSON.stringify(data) === '[]') return true
}

/***
 * 遍历方式获取树的最大层次
 */
export const calculationLevel = (arr) => {
  //递归计算树形数据最大的层级数
  let maxLevel = 0
  !(function multiArr(arr, level) {
    ++level
    maxLevel = Math.max(level, maxLevel)
    for (let i = 0; i < arr.length; i++) {
      let item = arr[i]
      item.level = level
      if (item.children && item.children.length > 0) {
        multiArr(item.children, level)
      } else {
        delete item.children
      }
    }
  })(arr, 0)
  return maxLevel
}

//colspan记录节点的所有叶子节点个数
export const getLeafCountTree = (json) => {
  // if(json.children == null){
  //   json.children
  // }
  if (!json.children) {
    json.colspan = 1
    return 1
  } else {
    let leafCount = 0
    for (let i = 0; i < json.children.length; i++) {
      leafCount = leafCount + getLeafCountTree(json.children[i])
    }
    json.colspan = leafCount
    return leafCount
  }
}

/**
 * 从树结构中根据指定id 查找返回对应 {}
 * @param {*}  data 传入的数据
 * @returns
 */
export const treeFind = function (tree, targeAttr, val) {
  if (!tree) {
    return null
  }
  if (tree[targeAttr] === val) {
    return tree
  }
  for (let i = 0; i < tree.children.length; i++) {
    const res = treeFind(tree.children[i], targeAttr, val)

    if (res) return res
  }
  return null
}

/**
 * 转换字符串，undefined,null等转化为
 * @param str undefined,null等转化为 ""
 *
 */
export const praseStrEmpty = (str) => {
  if (!str || str == 'undefined' || str == 'null') {
    return ''
  }
  return str
}

/**
 *
 * @param {*} targe
 * @param {*} hash
 */
export const deepClone = function (target, hash = new WeakMap()) {
  if (target === null) return target
  if (target instanceof Date) return new Date(target)
  if (target instanceof RegExp) return new RegExp(target)
  if (target instanceof HTMLElement) return target
  if (typeof target !== 'object') return target

  if (hash.get(target)) return hash.get(target)

  const cloneTarget = new target.constructor()
  hash.set(target, cloneTarget)

  for (const key in target) {
    if (target.hasOwnProperty(key)) {
      cloneTarget[key] = deepClone(target[key], hash)
    }
  }
  return cloneTarget
}

export const compareObj = (obj1, obj2, nature) => obj1[nature] === obj2[nature]

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
export function handleTree(data, id, parentId, children) {
  let config = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children'
  }

  var childrenListMap = {}
  var nodeIds = {}
  var tree = []

  for (let d of data) {
    let parentId = d[config.parentId]
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = []
    }
    nodeIds[d[config.id]] = d
    childrenListMap[parentId].push(d)
  }

  for (let d of data) {
    let parentId = d[config.parentId]
    if (nodeIds[parentId] == null) {
      tree.push(d)
    }
  }

  for (let t of tree) {
    adaptToChildrenList(t)
  }

  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]]
    }
    if (o[config.childrenList]) {
      for (let c of o[config.childrenList]) {
        adaptToChildrenList(c)
      }
    }
  }
  return tree
}

/**
 *
 * @param {*}  arr    需要构造的数组
 * @param {*}  key    被构造的字段
 * @param {*}  newKey 构造的新字段
 * @returns
 */
export const constructThree = (arr, key, newKey) => {
  arr.forEach((item) => {
    item[newKey] = deepClone(item[key])
    if (item.children) {
      constructThree(item.children, key, newKey)
    }
  })
  return arr
}
