/* eslint-disable import/prefer-default-export */
import _ from 'lodash'
import OurVue from 'vue'

export function install (Vue, args = {}) {
  if (install.installed) return
  install.installed = true

  if (OurVue !== Vue) {
    console.error('Multiple instances of Vue detected')
  }

  const components = args.components || {}
  const directives = args.directives || {}

  _.forEach(directives, (value, key) => {
    const directive = directives[key]
    Vue.directive(key, directive)
  });

  (function registerComponents (_components) {
    if (_components) {
      _.forEach(_components, (value, key) => {
        const component = _components[key]
        if (component && !registerComponents(component.$_shipnity_subcomponents)) {
          Vue.component(key, component)
        }
      })
      return true
    }
    return false
  }(components))

  if (Vue.$_shipnity_installed) return
  Vue.$_shipnity_installed = true
  Vue.mixin({
    beforeCreate () {
      const options = this.$options
      if (options.shipnity) {
        options.shipnity.init(this, this.$ssrContext)
        this.$shipnity = Vue.observable(options.shipnity.framework)
        this.$vuetify = Vue.observable(options.shipnity.framework)
      } else {
        this.$shipnity = (options.parent && options.parent.$shipnity) || this
        this.$vuetify = (options.parent && options.parent.$shipnity) || this
      }
    },
    beforeMount () {
      if (this.$options.shipnity && this.$el && this.$el.hasAttribute('data-server-rendered')) {
        this.$shipnity.isHydrating = true
        this.$shipnity.breakpoint.update(true)
      }
    },
    mounted () {
      if (this.$options.shipnity && this.$shipnity.isHydrating) {
        this.$shipnity.isHydrating = false
        this.$shipnity.breakpoint.update()
      }
    }
  })
}
