import React from "react";

/**
 * 
 * @param {*} DanmaItem 传入的弹幕Item Item
 * @param {*} DanmaData 弹幕数据 [{},{}]
 * @param {Array} speed 移动速度 [2,3,1,3]
 * @param {*} DanmaItemWidth 弹幕Item宽度 200
 * @param {*} DanmaItemHeight 弹幕Item高度/2 30
 * @returns 不知道写了啥
 */
export default function DanmaCtrl(DanmaItem, DanmaData, speed, DanmaItemWidth, DanmaItemHeight) {
  return class extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        danmaItems: new Map()
      }
      this.pos = 350
      this.top = DanmaItemHeight + 15
      this.col = speed.length
      /**  speed*(fixedTime-spaceTime)>DanmaItem.width  不重叠 */
      this.speed = speed
      this.fixedTime = 50
      this.spaceTime = 50
      this.i = 0
      this.sendTaskMap = new Map()
      this.totalMinusTime = 0
      this.nowDanmaItems = new Map()
      this.requestAnimationFrameId = null
    }

    componentDidMount() {
      for (let i = 0; i < this.col * 2; i++) {
        let t = (this.fixedTime + DanmaItemWidth / this.speed[i % this.col]) * Math.floor(i / this.col) + this.spaceTime * Math.random()
        let data = {
          danmaData: this.getDanmaData(),
          t: t
        }
        this.sendTaskMap.set(i, data)
      }
      this.danmaMove()
    }


    getDanmaData() {
      const data = {
        danmaData: DanmaData[this.i % DanmaData.length],
        i: this.i
      }
      this.i++
      return data
    }


    sendDanma(data) {
      const newDanmaItem = React.createElement(DanmaItem, {
        key: data.i,
        ...data.danmaData,
        style: {
          left: this.pos + "px",
          top: this.top * (data.i % this.col) + "px"
        }
      })

      this.nowDanmaItems.set(data.i, newDanmaItem)
      this.setState({
        danmaItems: this.nowDanmaItems
      })
    }
    danmaMove = async () => {
      this.totalMinusTime++
      let danmaContainer = document.getElementById("danmaContainer")
      if (danmaContainer) {
        let danmaItems = danmaContainer.children
        for (let i = danmaItems.length - 1; i >= 0; i--) {
          let danmaItem = danmaItems[i]
          danmaItem.style.left = danmaItem.offsetLeft - this.speed[Math.floor(danmaItem.offsetTop / this.top)] + 'px'
          if (danmaItem.offsetLeft + danmaItem.offsetWidth < -100) {

            let l = Math.floor(danmaItem.offsetTop / this.top)
            let nowDanmaItems = this.state.danmaItems
            for (let j = 0; j < this.i; j++) {
              if (j % this.col == l) {
                let v = nowDanmaItems.get(j)
                if (v) {
                  if (v == "remove") {
                    break
                  }
                  nowDanmaItems.set(j, 'remove')
                  break
                }
              }
            }
            this.nowDanmaItems = nowDanmaItems

            let t = (this.fixedTime + DanmaItemWidth / this.speed[this.i % this.col]) * Math.floor(this.i / this.col) + this.spaceTime * Math.random() - this.totalMinusTime
            let danmaData = this.getDanmaData()
            let data = {
              danmaData: danmaData,
              t: t
            }
            this.sendTaskMap.set(this.i, data)
          }
        }
      }
      this.sendTaskMap.forEach((data, i) => {
        let t = data.t--

        if (t <= 0) {
          this.sendDanma(data.danmaData)
          this.sendTaskMap.delete(i)
        }
      })
      this.requestAnimationFrameId = requestAnimationFrame(this.danmaMove)
    }


    map2arr = (map) => {
      let arr = []
      map.forEach((item, index) => {
        if (item != 'remove') {
          arr.push(item)
        } else {
          map.delete(index)
        }
      })
      return arr
    }


    componentWillUnmount() {
      this.requestAnimationFrameId && cancelAnimationFrame(this.requestAnimationFrameId)
    }

    render() {
      let {
        danmaItems
      } = this.state
      return (
        <div id="danmaContainer" >
          {this.map2arr(danmaItems)}
        </div>
      )
    }
  };
}