'use strict';

import React from 'react';
import { observer } from 'mobx-react';
import './barrage.less';

/**
 * 等待一段时间
 * @param {number} time 等待的时间ms
 */
function WaitTime(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

/**
 * 设置元素style
 * @param {object} option 配置
 * @param {HTMLElement} option.element HTMLElement
 * @param {object} option.style element.style
 * @param {Function} [option.onTransitionEnd] transitionend回调
 * @param {Function} [option.onAnimationEnd] animationend回调
 */
function SetElementStyle({ element, style, onTransitionEnd, onAnimationEnd }) {
  const { transition, animation } = style;
  if (transition !== undefined) element.style.transition = transition;
  if (animation !== undefined) element.style.animation = animation;
  setTimeout(() => {
    Object.keys(style).forEach(v => {
      if (v != 'transition' && v != 'animation') {
        element.style[v] = style[v];
      }
    });
  })
  if (onTransitionEnd) {
    element.removeEventListener('transitionend', onTransitionEnd);
    element.addEventListener('transitionend', onTransitionEnd);
  }
  if (onAnimationEnd) {
    element.removeEventListener('animationend', onAnimationEnd);
    element.addEventListener('animationend', onAnimationEnd);
  }
}

@observer
class Barrage extends React.Component {
  constructor(props) {
    super(props);
    const {
      num = 2,// 数量，每一次同时出现几行
      // 数据
      data = [],
      // render方法
      renderLine
    } = props
    this.state = {
      /** 弹幕内容 */
      barrageData: new Array(num).fill(''),
    };
  }

  /** 弹幕节点列表 */
  barrageList = [];

  componentDidMount() {
    setTimeout(() => {
      const { data = [] } = this.props
      this.setBarrage(data);
    }, 100);
  }

  /** 设置弹幕 */

  setBarrage = async (data) => {
    /** 设置弹幕文字方法 */

    const setMsg = (i) => {
      const getPrizeName = data || [];
      const index = Math.floor(Math.random() * getPrizeName.length);
      const content = getPrizeName[index];
      this.state.barrageData[i] = content;
      this.setState({
        barrageData: this.state.barrageData,
      });
    };
    /** 跑弹幕方法 */
    const runNode = (node, i) => {
      const dom = node;
      const domWidth = dom.getClientRects()[0].width;
      const fz = Number(document.documentElement.style.fontSize.replace('px', ''));
      const width = domWidth / fz;
      SetElementStyle({
        element: node,
        style: {
          transition: `transform ${10 - 1 * i}s linear`,
          transform: `translateX(${-7.5 - width}rem)`,
        },
      });
    };
    // 启动弹幕
    this.barrageList.forEach((node, i) => {
      setMsg(i);
      runNode(node, i);
      node.addEventListener('transitionend', async () => {
        SetElementStyle({
          element: node,
          style: {
            transition: '',
            transform: '',
          },
        });
        setMsg(i);
        await WaitTime(100);
        runNode(node, i);
      });
    });

  };

  render() {
    const { barrageData } = this.state;
    const {
      renderLine = (data) => {
        return <div>{data}</div>
      }
    } = this.props
    return (
      <div
        className="barrage-wrapper"
      >
        {barrageData.map((v, i) => {
          return (
            <div
              id="c-barrage"
              className="barrage c-barrage"
              key={i}
              style={{
                left: `${7.5}rem`,
                top: `${1 * i}rem`,
              }}
              ref={(ref) => (this.barrageList[i] = ref)}
            >
              {renderLine(v)}
            </div>
          );
        })}
      </div>
    );
  }
}

export default Barrage;
