const nanoid = require('nanoid')
const pluralize = require('pluralize')

module.exports = {
  getRemovable,
  createId,
  deepQuery
}

// Returns document ids that have unsatisfied relations
// Example: a comment that references a post that doesn't exist
function getRemovable(db, opts) {
  const _ = this
  const removable = []
  _.each(db, (coll, collName) => {
    _.each(coll, doc => {
      _.each(doc, (value, key) => {
        if (new RegExp(`${opts.foreignKeySuffix}$`).test(key)) {
          // Remove foreign key suffix and pluralize it
          // Example postId -> posts
          const refName = pluralize.plural(
            key.replace(new RegExp(`${opts.foreignKeySuffix}$`), '')
          )
          // Test if table exists
          if (db[refName]) {
            // Test if references is defined in table
            const ref = _.getById(db[refName], value)
            if (_.isUndefined(ref)) {
              removable.push({ name: collName, id: doc.id })
            }
          }
        }
      })
    })
  })

  return removable
}

// Return incremented id or uuid
// Used to override lodash-id's createId with utils.createId
function createId(coll) {
  const _ = this
  const idProperty = _.__id()
  if (_.isEmpty(coll)) {
    return 1
  } else {
    let id = _(coll).maxBy(idProperty)[idProperty]

    // Increment integer id or generate string id
    return _.isFinite(id) ? ++id : nanoid(7)
  }
}

function deepQuery(value, q) {
  const _ = this
  if (value && q) {
    if (_.isArray(value)) {
      for (let i = 0; i < value.length; i++) {
        if (_.deepQuery(value[i], q)) {
          return true
        }
      }
    } else if (_.isObject(value) && !_.isArray(value)) {
      for (let k in value) {
        if (_.deepQuery(value[k], q)) {
          return true
        }
      }
    } else if (
      value
        .toString()
        .toLowerCase()
        .indexOf(q) !== -1
    ) {
      return true
    }
  }
}
