import lodash from 'lodash'
import { unref } from 'vue'
/**
 * 通用防抖
 *
 * @param callback 回调函数
 * @param wait     等待毫秒数
 * @param type     回调函数额外参数
 * @param options  防抖额外参数
 * @returns
 */
export const lodashFunc = (callback: Function, wait: number, type?: any, options?: any) => {
  return lodash.debounce(
    function () {
      type ? callback(type) : callback()
    },
    wait,
    options
  )
}

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

  const childrenListMap: any = {}
  const nodeIds: any = {}
  const tree = <any>[]

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

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

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

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

/**
 * 参数处理
 *
 * @param {*} params  参数
 */
export function tansParams(params: { [x: string]: any }) {
  let result = ''
  for (const propName of Object.keys(params)) {
    const value = params[propName]
    const part = encodeURIComponent(propName) + '='
    if (value !== null && value !== '' && typeof value !== 'undefined') {
      if (typeof value === 'object') {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && value !== '' && typeof value[key] !== 'undefined') {
            let params = propName + '[' + key + ']'
            const subPart = encodeURIComponent(params) + '='
            result += subPart + encodeURIComponent(value[key]) + '&'
          }
        }
      } else {
        result += part + encodeURIComponent(value) + '&'
      }
    }
  }
  return result
}

// 转换字符串，undefined,null等转化为""
export function parseStrEmpty(str: string | undefined) {
  if (!str || str === 'undefined' || str === 'null') {
    return ''
  }
  return str
}
// 验证是否为blob格式
export function blobValidate(data: any) {
  return data.type !== 'application/json'
}

export const setEnumMap = async (enumMap, { prop, enum: enumValue }: any) => {
  if (!enumValue) return

  // 如果当前 enumMap 存在相同的值 return
  if (enumMap.value.has(prop!) && (typeof enumValue === 'function' || enumMap.value.get(prop!) === enumValue)) return

  // 当前 enum 为静态数据，则直接存储到 enumMap
  if (typeof enumValue !== 'function') return enumMap.value.set(prop!, unref(enumValue!))

  // 为了防止接口执行慢，而存储慢，导致重复请求，所以预先存储为[]，接口返回后再二次存储
  enumMap.value.set(prop!, [])

  // 当前 enum 为后台数据需要请求数据，则调用该请求接口，并存储到 enumMap
  let { data } = await enumValue()
  enumMap.value.set(prop!, data)
}

export const handelEnum = (enumMap, item: any) => {
  let enumData = enumMap.value.get(item.formItem.prop)
  if (!enumData) return []
  // 返回对象类型
  if (item.type === 'select-tree' && item.attrs?.labelKey && item.attrs?.valueKey) {
    enumData = enumData.map((el: { [key: string]: any }) => {
      return {
        ...el,
        label: el[item.attrs?.labelKey || 'label'],
        children: el[item.attrs?.children || 'children'] || []
      }
    })
  }
  return enumData
}
