const isEqual = (a: unknown, b: unknown): boolean => {
  if (a === b) return true

  // Handle cases where either a or b is null or not an object
  if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') {
    // Handle NaN case
    return a !== a && b !== b
  }

  // Different constructors mean objects are not equal
  if (a.constructor !== b.constructor) return false

  // Handle Arrays
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false
    for (const [i, element] of a.entries()) {
      const element2 = typeof b[i] === 'object' ? { ...b[i] } : b[i]
      if (!isEqual(element, element2)) return false
    }
    return true
  }

  // Handle Maps
  if (a instanceof Map && b instanceof Map) {
    if (a.size !== b.size) return false
    for (const [key, value] of a) {
      if (!b.has(key) || !isEqual(value, b.get(key))) return false
    }
    return true
  }

  // Handle Sets
  if (a instanceof Set && b instanceof Set) {
    if (a.size !== b.size) return false
    for (const value of a) {
      if (!b.has(value)) return false
    }
    return true
  }

  // Handle RegExp
  if (a instanceof RegExp && b instanceof RegExp) {
    return a.source === b.source && a.flags === b.flags
  }

  // Handle objects with custom valueOf or toString
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  if (a.valueOf !== Object.prototype.valueOf && a.valueOf() !== (b as any).valueOf()) return false

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  if (a.toString !== Object.prototype.toString && a.toString() !== (b as any).toString())
    return false

  // Compare object keys
  const aKeys = Object.keys(a)
  const bKeys = Object.keys(b)

  if (aKeys.length !== bKeys.length) return false

  // Ensure all keys in a are present in b
  for (const key of aKeys) {
    if (!Object.prototype.hasOwnProperty.call(b, key)) return false
  }

  // Deep compare each property
  for (const key of aKeys) {
    if (!isEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {
      return false
    }
  }

  return true
}

export default isEqual
