import throttle from 'lodash/function/throttle'

import isAccelerating from './is-accelerating'

const ACTIVE_CLASS = 'is-active'
const COORD_MAX = 5
const HOVER_DELAY = 250

const $ = global.jQuery

class SmarterHover {
  constructor(el) {
    this.$el = $(el)
    this.enterId = null
    this.exitId = null
    this.coordinates = []

    this.bindEvents(el)
  }

  bindEvents(el) {
    this.$el.on('mouseenter', (e) => {
      this.exitId = null
      this.enterId = setTimeout(this.makeActive.bind(this), HOVER_DELAY)

      this.$el.on('mousemove', throttle(this.handleMove.bind(this), HOVER_DELAY / 4))
    })

    this.$el.on('mouseleave', (e) => {
      clearTimeout(this.enterId)
      clearTimeout(this.exitId)

      this.enterId = null

      this.exitId = setTimeout(this.makeInactive.bind(this), HOVER_DELAY / 2)
    })

    this.$el.on('click', (e) => {
      if (e.target === el) {
        this.makeActiveNow()
      }
    })
  }

  makeActiveNow() {
    this.resetCoordinates()
    this.$el.addClass(ACTIVE_CLASS)
  }

  makeActive() {
    if (!this.exitId) {
      this.makeActiveNow.call(this)
    }
    this.enterId = null
  }

  makeInactive() {
    this.$el.removeClass(ACTIVE_CLASS)
    this.$el.off('mousemove')
    this.exitId = null
  }

  addCoordinate(x, y) {
    this.coordinates.push({ x, y })

    if (this.coordinates.length > COORD_MAX) {
      this.coordinates.shift()
    }
  }

  resetCoordinates() {
    this.coordinates = []
  }

  handleMove(move) {
    this.addCoordinate(move.pageX, move.pageY)

    if (!this.exitId && !isAccelerating(this.coordinates)) {
      this.makeActiveNow()
    }
  }
}

export { SmarterHover }

export default function (el) {
  return new SmarterHover(el)
}
