<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
    // 默认以text为展示内容，text可以是文本或者是返回文本的函数。没有则展示id
    defaultBarrage: {
      type: Array,
      default: () => []
    },
    // 密集度，越大越密集
    intensity: {
      type: Number,
      default: 3
    },
    // 是否固定间隔
    isImmobilization: {
      type: Boolean,
      default: false
    }
  },
  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)
    },
    // 执行开始
    execute() {
      if (this.link.getLength() > 0) {
        this.currentData = this.link.head
        this.parent = this.$refs.barrageContainer
        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)
      }

      if (this?.currentData === this.link?.head) {
        this.StartPointTime = new Date()
      }

      // 上一个距离下一个的时间
      if (this.isImmobilization && this.currentData.value.time) {
        var timenum = this.currentData.value.time
      } else if (this?.currentData?.next === this.link?.head && document.getElementById(this.link?.head?.value?.id)) {
        var timenum = Math.abs(this.wheelTime - Math.abs(new Date().getTime() - this.StartPointTime.getTime()))
      } else {
        var timenum = this.getRandomIntInRange(0, this.wheelTime / (this.intensity <= 0 ? 1 : this.intensity))
      }

      // 记录间隔时间
      if (this.isImmobilization) {
        this.currentData.value.time = timenum
      }

      // 删除之前的
      var node = document.getElementById(this.currentData?.value?.id)
      if (node) {
        node.parentNode.removeChild(node)
      }

      // 创建新的元素
      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 forwards`
      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

      // 添加
      this.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
    },
    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>
