import _ from 'lodash'
import Vue from 'vue'

// v1.2

/**
 *
 * @param {*} arr (Array) The array to process.
 * @param {*} value The value to knock.
 * @param {*} f The value to first.
 * @returns (Array) Mutates the existing array, removes duplicates as well
 */
function knock (arr, value, f = false) {
  const cloneArr = _.cloneDeep(arr)
  if (cloneArr.length === _.pull(cloneArr, value).length) {
    if (f) {
      cloneArr.unshift(value)
    } else {
      cloneArr.push(value)
    }
  }
  return cloneArr
}

/**
 *
 * @param {*} arr (Array) The array to process.
 * @param {*} value The value to search.
 * @param {*} path (Array|string): The path of the property to set.
 * @returns (Array) Returns the new filtered array.
 */
function search (arr, value = '', path = null) {
  return arr.filter((obj) => _.includes(
    _.lowerCase(
      _.get(obj, path, obj)
    ),
    _.lowerCase(value)
  ))
}

/**
 *
 * @param {*} prefixStr (string) The value to prefix.
 * @param {*} curr (object) The object to process.
 * @returns (Array) Returns the new object.
 */

function prefix (prefixStr = '', curr) {
  const object = {}
  _.forEach(curr, (value, key) => {
    const newKey = prefixStr + _.upperFirst(key)
    object[newKey] = value
  })
  return object
}

/**
 *
 * @param {*} str (string) The value to pascal.
 * @returns (string) Returns string pascal case.
 */

function pascalCase (str) {
  return _.startCase(_.camelCase(str)).replace(/ /g, '')
}

/**
 *
 * @param {*} str (string) The value to url.
 * @returns (string) Returns boolean.
 */

function isURL (str) {
  const pattern = new RegExp('^(https?:\\/\\/)?' // protocol
      + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' // domain name
      + '((\\d{1,3}\\.){3}\\d{1,3}))' // OR ip (v4) address
      + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' // port and path
      + '(\\?[;&a-z\\d%_.~+=-]*)?' // query string
      + '(\\#[-a-z\\d_]*)?$', 'g') // fragment locator
    return !!pattern.test(str)
}

/**
 *
 * @param {*} str (string) The value to url.
 * @returns (string) Returns boolean.
 */

function isHTTP (str) {
  return /^https?:\/\//i.test(str)
}

/**
 *
 * @param {*} str (string) The value to email.
 * @returns (string) Returns boolean.
 */

function isEmail (str) {
  return /.+@.+\..+/.test(str)
}

_.mixin({
  knock,
  search,
  prefix,
  pascalCase,
  isURL,
  isHTTP,
  isEmail
})

Vue.prototype.$_ = _
