import { getMappedKeys } from './getMappedKeys';

/**
 * Compares keys between two objects and returns an array of missing keys in the second object.
 * Nested objects are also checked.
 *
 * @template T
 * @param {T} obj1 - The first object to compare keys.
 * @param {T} obj2 - The second object to compare keys against.
 * @return {string[]} - An array of missing keys in `obj2` compared to `obj1`.
 */
export function compareKeysDeep<T extends { [key: string]: any }>(
  obj1: T,
  obj2: T,
  prefix = ''
): string[] {
  const missingKeys: string[] = [];

  for (const key in obj1) {
    if (!(key in obj2) || typeof obj1[key] !== typeof obj2[key]) {
      const mappedChildrenKeys = getMappedKeys(obj1[key]);
      let childrenKeys = '';
      if (mappedChildrenKeys.length > 0) {
        childrenKeys = `.${getMappedKeys(obj1[key])}`;
      }
      missingKeys.push(prefix + key + childrenKeys);
    } else if (typeof obj1[key] === 'object') {
      const nestedKeys = compareKeysDeep(
        obj1[key],
        obj2[key],
        prefix + key + '.'
      );
      missingKeys.push(...nestedKeys.map((nestedKey) => prefix + nestedKey));
    }
  }

  for (const key in obj2) {
    if (!(key in obj1) || typeof obj1[key] !== typeof obj2[key]) {
      missingKeys.push(prefix + key);
    }
  }

  return missingKeys;
}
