import React, { Component } from 'react'
import h from 'react-hyperscript'
import anime from 'animejs'

import Animate from 'reusableComponents/Animate'

import styles from './tooltip.css'

export default class ToolTip extends Component {
  state = {
    visible: false
  }

  animeSettings = {
    duration: 225
  }

  handleHoverIn = () => this.setState({ visible: true })

  handleHoverOut = () => this.setState({ visible: false })

  // to handle touch devices
  handleClick = () => this.setState({ visible: !this.state.visible })

  handleKeyDown = e => {
    const keycode = e.which || e.keyCode
    if (keycode === 13) this.setState({ visible: !this.state.visible })
  }

  onEnter = (el, cb) => {
    const { scrollWidth: elWidth, scrollHeight: elHeight } = el
    const {
      width: visibleTextWidth,
      top: visibleTextTop,
      left: visibleTextLeft,
      right: visibleTextRight,
      height: visibleTextHeight } = this.visibleText.getBoundingClientRect()
    const distanceFromBottom = window.innerHeight - (visibleTextTop + visibleTextHeight)
    const distanceFromRight = window.innerWidth - (visibleTextLeft + visibleTextWidth)

    const computeMarginLeft = () => {
      if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft || elWidth > distanceFromRight) return '0px'
      return `${-(elWidth - visibleTextWidth) / 2}px`
    }

    const computeTop = () => {
      if (visibleTextTop > distanceFromBottom) return `${visibleTextTop - elHeight}px`
      return `${visibleTextTop + visibleTextHeight}px`
    }

    const computeLeft = () => {
      if (elWidth > distanceFromRight) return `${(visibleTextRight - elWidth)}px`
      return `${visibleTextLeft}px`
    }

    const computeTransformOrigin = () => {
      if (visibleTextTop > distanceFromBottom) {
        if (elWidth > distanceFromRight) return 'right bottom 0'
        if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft) return 'left bottom 0'
        return 'center bottom 0'
      } else {
        if (elWidth > distanceFromRight) return 'right top 0'
        if ((elWidth - visibleTextWidth) / 2 > visibleTextLeft) return 'left top 0'
        return 'center top 0'
      }
    }

    el.style.top = computeTop()
    el.style.left = computeLeft()
    el.style.marginLeft = computeMarginLeft()
    el.style.transformOrigin = computeTransformOrigin()
    anime({
      targets: el,
      scale: {
        ...this.animeSettings,
        easing: [0.175, 0.885, 0.32, 1.275],
        value: 1
      },
      complete: cb
    })
  }

  onLeave = (el, cb) => {
    anime({
      targets: el,
      scale: { ...this.animeSettings, easing: 'easeInOutQuad', value: 0 },
      complete: () => {
        el.style.top = 0
        el.style.left = 0
        el.style.marginLeft = 0
        return cb()
      }
    })
  }

  renderToolTips() {
    const { onEnter, onLeave, state: { visible }, props } = this

    return h(
      Animate,
      {
        trigger: visible,
        onEnter,
        onLeave,
        customClassName: styles.hiddenText,
        customStyle: { transform: 'scale(0)' }
      },
      h('span', props.hiddenText)
    )
  }

  render() {
    return h(
      'span',
      {
        onClick: this.handleClick,
        onMouseEnter: this.handleHoverIn,
        onMouseLeave: this.handleHoverOut,
        onKeyDown: this.handleKeyDown,
        className: styles.root,
        tabIndex: '0'
      },
      [
        h('span', { ref: visibleText => { this.visibleText = visibleText }, className: styles.text }, this.props.children),
        this.renderToolTips()
      ]
    )
  }

  static propTypes = {
    hiddenText: React.PropTypes.string
  }

  static defaultProps = {
    hiddenText: 'add some text'
  }
}

@@ -919,24 +919,28 @@
 leTextHeight
+%0A   
  %7D = this.vi
@@ -1003,16 +1003,22 @@
 Bottom =
+%0A     
  window.
@@ -1097,16 +1097,22 @@
 mRight =
+%0A     
  window.
@@ -1202,32 +1202,41 @@
  =%3E %7B%0A      if (
+%0A        
 (elWidth - visib
@@ -1272,16 +1272,24 @@
 tLeft %7C%7C
+%0A       
  elWidth
@@ -1300,33 +1300,42 @@
 istanceFromRight
-)
+%0A      ) %7B
  return '0px'%0A  
@@ -1331,16 +1331,18 @@
 rn '0px'
+ %7D
 %0A      r
@@ -1472,16 +1472,18 @@
 mBottom)
+ %7B
  return 
@@ -1510,24 +1510,26 @@
 elHeight%7Dpx%60
+ %7D
 %0A      retur
@@ -1660,17 +1660,16 @@
 turn %60$%7B
-(
 visibleT
@@ -1686,17 +1686,16 @@
  elWidth
-)
 %7Dpx%60%0A   
@@ -1946,32 +1946,34 @@
 visibleTextLeft)
+ %7B
  return 'left bo
@@ -1971,32 +1971,34 @@
  'left bottom 0'
+ %7D
 %0A        return 
@@ -2155,16 +2155,18 @@
 extLeft)
+ %7B
  return 
@@ -2169,32 +2169,34 @@
 urn 'left top 0'
+ %7D
 %0A        return 
@@ -3473,17 +3473,50 @@
   h(
-'span', %7B
+%0A          'span',%0A          %7B%0A           
  ref
@@ -3533,16 +3533,30 @@
 ext =%3E %7B
+%0A             
  this.vi
@@ -3582,37 +3582,81 @@
 Text
- %7D, className: styles.text %7D,
+%0A            %7D,%0A            className: styles.text%0A          %7D,%0A         
  thi
@@ -3671,16 +3671,25 @@
 children
+%0A        
 ),%0A     

clean up code