import React, { useEffect, useState } from "react"
import { render as reactRender } from "react-dom"
import './CollectAni.less'

/**
 * 获取元素相对视窗原点的位置
 * @param {HTMLElement} ele 
 */
function getElementPos(ele) {
  if (typeof ele === 'string') {
    ele = document.getElementById(ele)
  }
  const { top, left, width, height } = ele.getBoundingClientRect()
  return {
    x: left + width/2,
    y: top + height/2
  }
}

const defaultProps = {
  icon: '',
  from: null,
  to: null,
  count: 10,
  duration: 1000,
}

class CollectAni extends React.PureComponent {
  /**
   * 
   * @param {Object} props 
   * @param {String} props.icon
   * @param {Object} props.fromPos
   * @param {Object} props.toPos
   * @param {Number} props.count
   * @param {Number} props.duration
   */
  constructor(props = defaultProps) {
    super(props)

    this.fromPos = this.props.fromPos
    this.toPos = this.props.toPos
    this.endCount = 0
    this.collectRef = React.createRef()
  }

  renderElements() {
    const { count, icon, duration, width, height } = this.props
    const preDuration = Math.ceil(duration/count)
    // const disX = this.toPos.x - this.fromPos.x
    // const disY = this.toPos.y - this.fromPos.y

    let i = 0
    const iconElemList = []
    while (i < count) {
      iconElemList.push(
        <FlyObject
          width={width}
          height={height}
          key={i}
          delay={preDuration * i}
          duration={preDuration * 3}
          pos={this.fromPos}
          toPos={this.toPos}
          icon={icon}
          onTransitionEnd={this.onTransitionEnd}
        />
      )
      i++
    }
    return iconElemList
  }

  onTransitionEnd = () => {
    this.endCount ++
    if (this.endCount === this.props.count) { // 卸载组件
      console.log(this.props.destroy)
      typeof this.props.destroy === 'function' && this.props.destroy()
    }
  }

  render() {
    return (
      <div ref={this.collectRef} className="KCollectAni">
        {this.renderElements()}
      </div>
    )
  }
}

CollectAni.show = function(props = {
  icon: '',
  from: null,
  to: null,
  width: 0,
  height: 0,
  count: 10,
  duration: 1000,
}, callback) {
  props.fromPos = getElementPos(props.from)
  props.toPos = getElementPos(props.to)
  const element = document.createElement('div')
  document.body.appendChild(element)

  // // 防止动画结束了DOM元素还在，这里兜底处理
  const aniTimer = setTimeout(() => {
    destroy()
  }, props.duration + 500)

  // 当所有的移动节点动画结束后调用
  function destroy() {
    document.body.removeChild(element)
    if (aniTimer) clearTimeout(aniTimer)
    typeof callback === 'function' && callback()
  }
  props.destroy = destroy

  reactRender(<CollectAni {...props} />, element)
}

function FlyObject(props) {
  const { delay, duration, pos, icon, width, height, toPos } = props
  const [playing, setPlaying] = useState(false)

  useEffect(() => {
    const timer = setTimeout(() => {
      setPlaying(true)
    }, 50)
    return function() {
      clearTimeout(timer)
    }
  }, [])

  function onTransitionEnd(e) {
    e.target.style.display = 'none'
    typeof props.onTransitionEnd === 'function' && props.onTransitionEnd()
  }

  return <img
    src={icon}
    style={{
      width: width/100 + 'rem',
      height: height/100 + 'rem',
      left: playing ? toPos.x + 'px' : pos.x + 'px',
      top: playing ? toPos.y + 'px' : pos.y + 'px',
      transition: playing ? `all ${duration}ms ${delay}ms` : 'unset',
      transform: 'translate(-50%, -50%)',
    }}
    onTransitionEnd={e => onTransitionEnd(e)}
  />
}

export default CollectAni
