<template>
  <div class="barrageContainer" ref="barrageContainer">
    <slot />
  </div>
</template>

<script>
import { CircularLinkedList } from './circularLinkedList.js'
export default {
  props: {
    // 动画时间
    wheelTime: {
      type: Number,
      default: 3000
    },
    // 隐藏的过度距离
    excessive: {
      type: Number,
      default: 500
    },
    // 距离顶部最小高度
    mintop: {
      type: Number,
      default: 100
    },
    // 距离底部最小高度
    minbottom: {
      type: Number,
      default: 100
    },
    // 弹幕样式
    barrageStyle: {
      type: Object,
      default: () => ({})
    },
    // 默认的数据
    // 对象中必要参数又id与time
    // 默认以text为展示内容，text可以是文本或者是返回文本的函数。没有则展示id
    defaultBarrage: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      link: new CircularLinkedList(),
      containerWidth: 0,
      containerHeight: 0
    }
  },
  created() {
    this.defaultBarrage.map(item => {
      this.push(item)
    })
  },
  methods: {
    // 计算容器高度
    kg() {
      const element = this.$refs.barrageContainer
      this.containerWidth = element.offsetWidth
      this.containerHeight = element.offsetHeight
    },
    // 向后追加
    push(val) {
      this.link.append(val)
    },
    // 向前追加
    unshift(val) {
      this.link.prepend(val)
    },
    // 执行开始
    execute() {
      if (this.link.getLength() > 0) {
        this.currentData = this.link.head
        this.kg()
        this.dongtai()
        this.$nextTick(() => {
          this.start()
        })
      }
    },
    // 关闭
    close() {
      if (this.timeId) {
        clearTimeout(this.timeId)
      }
      // 删除样式
      const style = document.getElementById('dynamic-animation-style')
      if (style) {
        style.parentNode.removeChild(style)
      }
      // 删除元素
      document.querySelectorAll('.newBarrageChild').forEach(element => {
        element.remove()
      })
    },
    // 开始
    start() {
      if (this.timeId) {
        clearTimeout(this.timeId)
      }
      // 上一个距离下一个的时间
      var timeNum2 = Math.abs(
        new Date(this.currentData?.next?.value?.time).getTime() - new Date(this.currentData?.value?.time).getTime()
      )
      // 获取间隔时间
      var timenum =
        this?.currentData?.next === this.link?.head
          ? this.wheelTime
          : timeNum2 > this.wheelTime
          ? this.wheelTime
          : timeNum2

      // 删除之前的
      var node = document.getElementById(this.currentData?.value?.id)
      if (node) {
        node.parentNode.removeChild(node)
      }
      // 追加新的元素
      var parent = this.$refs.barrageContainer
      var newChild = document.createElement('div')
      newChild.id = this.currentData?.value?.id
      newChild.className = 'barrage newBarrageChild'
      newChild.style.top = `${this.getRandomIntInRange(
        this.mintop,
        this.containerHeight > this.minbottom ? this.containerHeight - this.minbottom : this.minbottom
      )}px`
      for (var key in this.barrageStyle) {
        newChild.style[key] = this.barrageStyle[key]
      }
      newChild.style.animation = `moveRight ${this.wheelTime / 1000}s linear infinite`
      newChild.innerText =
        typeof this.currentData?.value?.text === 'function'
          ? this.currentData?.value?.text?.()
          : typeof this.currentData?.value?.text === 'string'
          ? this.currentData?.value?.text
          : this.currentData?.value?.id
      parent.appendChild(newChild)
      // 赋值下一个数据为当前数据
      this.currentData = this.currentData.next
      // 定时器下一次执行追加
      this.timeId = setTimeout(() => {
        this.start()
      }, timenum)
    },
    // 获取随机高度
    getRandomIntInRange(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min
    },
    // 生成uid
    uid() {
      let d = new Date().getTime()
      let d2 = (performance && performance.now && performance.now() * 1000) || 0
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        let r = Math.random() * 16
        if (d > 0) {
          r = (d + r) % 16 | 0
          d = Math.floor(d / 16)
        } else {
          r = (d2 + r) % 16 | 0
          d2 = Math.floor(d2 / 16)
        }
        return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)
      })
    },
    dongtai() {
      // 创建一个 <style> 标签
      const style = document.createElement('style')
      style.id = 'dynamic-animation-style'
      style.type = 'text/css'
      style.innerHTML = `
          @keyframes moveRight {
              from {
                  right: 0;
              }
              to {
                  right: ${this.containerWidth + this.excessive}px;
              }
          }
      `
      document.getElementsByTagName('head')[0].appendChild(style)
    }
  }
}
</script>

<style lang="scss">
.barrageContainer {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  .barrage {
    position: absolute;
    z-index: 9999999;
    transform: translateX(100%);
  }
}
</style>
