import mongoose from 'mongoose';

export const renameKeys = (obj, oldName, newName) => {
  const keyValues = Object.keys(obj).map((key) => {
    let newKey;
    if (key === oldName) {
      newKey = newName;
    } else {
      newKey = key;
    }
    if (Array.isArray(obj[key])) {
      obj[key] = obj[key].map(obj => renameKeys(obj, oldName, newName));
    }
    if ((obj[key] instanceof Object) && !(obj[key] instanceof Date) && !(obj[key] instanceof mongoose.Types.ObjectId)) {
      obj[key] = renameKeys(obj[key], oldName, newName);
    }
    return {
      [newKey]: obj[key]
    };
  });
  return Object.assign({}, ...keyValues);
}

export const normalizeObject = (obj, oldName = '_id', newName = 'id') => {
  const keyValues = Object.keys(obj).map((key) => {
    if (key === '__v') {
      delete obj[key];
      return;
    }
    let newKey;
    if (key === oldName) {
      newKey = newName;
    } else {
      newKey = key;
    }
    if (Array.isArray(obj[key])) {
      obj[key] = obj[key].map((nestedObj) => normalizeObject(nestedObj, oldName, newName));
      return { [newKey]: obj[key] }
    }
    if ((obj[key] instanceof Object) && !(obj[key] instanceof Date) && !(obj[key] instanceof mongoose.Types.ObjectId)) {
      obj[key] = normalizeObject(obj[key], oldName, newName);
      return { [newKey]: obj[key] }
    }
    return {
      [newKey]: obj[key]
    };
  });
  return Object.assign({}, ...keyValues);
}

const mongoValidator = (id: string) => {
  if (mongoose.Types.ObjectId.isValid(id)) {
    return (String)(new mongoose.Types.ObjectId(id)) === id;
  }
  return false;
}

export const isValidId = (id: string | mongoose.Types.ObjectId) => {
  if (!id) {
    return false;
  }
  if (typeof id !== 'string') {
    id = id.toString();
  }
  const regex = new RegExp(/^[a-f\d]{24}$/i);
  const regexResult = regex.test(id);
  return regexResult && mongoValidator(id);
}
