import { isDate, isMap, isSet } from './type_detectors'

type TShouldBlockSelfToJSON<K, V> = Date | Map<K, V> | Set<V>

const clone = <K, V>(target: TShouldBlockSelfToJSON<K, V>) => {
  if (isDate(target)) return new Date(target.getTime())
  if (isMap(target)) return new Map([...target.entries()])
  if (isSet(target)) return new Set([...target.values()])
  return {}
}

// eslint-disable-next-line @typescript-eslint/ban-types
export const blockSelfToJSON = <K, V>(target: TShouldBlockSelfToJSON<K, V>) =>
  Object.assign(clone(target), {
    toJSON: undefined
  })

// eslint-disable-next-line @typescript-eslint/ban-types
export const shouldBlockSelfToJSON = <K, V>(
  target: unknown
): target is TShouldBlockSelfToJSON<K, V> => {
  return isDate(target) || isMap(target) || isSet(target)
}
