export function scanObj(obj, handler) {
  for (const key in obj) {
    if (
      typeof obj[key] === 'object' &&
      obj[key] !== null &&
      !Array.isArray(obj[key])
    ) {
      scanObj(obj[key], handler)
    } else {
      handler(obj, key)
    }
  }
}

export function filterObj(obj, fn, clone = true) {
  if (clone) {
    obj = JSON.parse(JSON.stringify(obj))
  }
  scanObj(obj, (currentObj, key) => {
    if (!fn(currentObj[key])) {
      delete currentObj[key]
    }
  })
  return obj
}

export function resetObj(obj, fn, clone = false) {
  if (clone) {
    obj = JSON.parse(JSON.stringify(obj))
  }
  scanObj(obj, (currentObj, key) => {
    const readyValue = (() => {
      if (Array.isArray(currentObj[key])) {
        return []
      }
      return undefined
    })()
    currentObj[key] = fn ? fn(currentObj, key, readyValue) : readyValue
  })
  return obj
}

export function scanObjArr(
  objArr,
  handler,
  options = { children: 'children' },
  parent
) {
  for (const obj of objArr) {
    handler(obj, objArr, parent)
    if (Array.isArray(obj[options.children])) {
      scanObjArr(obj[options.children], handler, options, obj, parent)
    }
  }
}

export function deepFindObjArr(
  objArr,
  handler,
  options = { children: 'children' }
) {
  let result
  let lock = false
  scanObjArr(
    objArr,
    (obj, objArr) => {
      if (!lock && handler(obj, objArr)) {
        lock = true
        result = obj
      }
    },
    options
  )
  return result
}
