import { unwrapAndClone } from "src/utils/unwrap-and-clone";

/**
 * Internal recursive function comparing two plain values.
 */
const _deepEqualRecursive = (a: unknown, b: unknown): boolean => {
    if (a === b) return true;

    if (a == null || b == null || typeof a !== "object" || typeof b !== "object") {
        return false;
    }

    // Handle arrays
    if (Array.isArray(a) && Array.isArray(b)) {
        if (a.length !== b.length) return false;
        return a.every((val, i) => _deepEqualRecursive(val, b[i]));
    } else if (Array.isArray(a) || Array.isArray(b)) {
        return false; // one is array, other is not
    }

    const aKeys = Object.keys(a as Record<string, unknown>);
    const bKeys = Object.keys(b as Record<string, unknown>);

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

    return aKeys.every((key) =>
        _deepEqualRecursive(
            (a as Record<string, unknown>)[key],
            (b as Record<string, unknown>)[key]
        )
    );
};

/**
 * Deep equality check that normalizes reactive objects first.
 */
export const deepEqual = (given: unknown, expected: unknown): boolean => {
    const a = unwrapAndClone(given as object);
    const b = unwrapAndClone(expected as object);
    return _deepEqualRecursive(a, b);
};
