<template>
  <div class="marquee-box">
    <div class="scroll-area">
      <!-- 设置margin,使内容 有从无到有的出现效果 -->
      <div class="marquee-container">
        <div class="icon">
          <i
            v-if="config.customize.icon.position === 'left'"
            :class="config.customize.icon.name"
            :style="{ color: config.customize.icon.color, fontSize: config.customize.fontSize + 'px' }"
          />
        </div>

        <svg class="svg-container">
          <defs>
            <linearGradient
              :id="'backgroundGradient-'+config.code"
              :x1="0"
              :y1="['to top right'].includes(config.customize.bgGradientDirection) ? '100%' : '0'"
              :x2="['to right','to bottom right','to top right'].includes(config.customize.bgGradientDirection) ? '100%' : '0'"
              :y2="['to bottom','to bottom right'].includes(config.customize.bgGradientDirection) ? '100%' : '0'"
            >
              <stop
                offset="0%"
                :stop-color="config.customize.backgroundColorType === 'pure' ? config.customize.backgroundColor : config.customize.bgGradientColor0"
              />
              <stop
                offset="100%"
                :stop-color="config.customize.backgroundColorType === 'pure' ? config.customize.backgroundColor : config.customize.bgGradientColor1"
              />
            </linearGradient>
            <linearGradient
              :id="'textGradient-'+config.code"
              :x1="0"
              :y1="['to top right'].includes(config.customize.textGradientDirection) ? '100%' : '0'"
              :x2="['to right','to bottom right','to top right'].includes(config.customize.textGradientDirection) ? '100%' : '0'"
              :y2="['to bottom','to bottom right'].includes(config.customize.textGradientDirection) ? '100%' : '0'"
            >
              <stop
                offset="0%"
                :stop-color="config.customize.textColorType === 'pure' ? config.customize.textColor : config.customize.textGradientColor0"
              />
              <stop
                offset="100%"
                :stop-color="config.customize.textColorType === 'pure' ? config.customize.textColor : config.customize.textGradientColor1"
              />
            </linearGradient>
          </defs>
          <rect
            v-if="config.customize.backgroundColorType !== 'transparent'"
            width="100%"
            height="100%"
            :fill="`url(#backgroundGradient-${config.code})`"
          />
          <text
            :x="10"
            :y="config.customize.fontSize"
            :style="{ fontSize: config.customize.fontSize + 'px', fontWeight: config.customize.fontWeight }"
            :fill="`url(#textGradient-${config.code})`"
          >
            <animate
              v-if="isAnimate"
              :attributeName="attributeName[config.customize.direction]"
              :from="from[config.customize.direction]"
              :to="to[config.customize.direction]"
              :dur="config.customize.dur + 's'"
              repeatCount="indefinite"
            />

            {{ config.customize.title }}
          </text>
        </svg>
        <div class="icon">
          <i
            v-if="config.customize.icon.position === 'right'"
            :class="config.customize.icon.name"
            :style="{ color: config.customize.icon.color, fontSize: config.customize.fontSize + 'px' }"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Speech from 'speak-tts'
import { EventBus } from 'data-room-ui/js/utils/eventBus'
import commonMixins from 'data-room-ui/js/mixins/commonMixins'
import paramsMixins from 'data-room-ui/js/mixins/paramsMixins'
import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
import cloneDeep from 'lodash/cloneDeep'
export default {
  props: {
    // 卡片的属性
    config: {
      type: Object,
      default: () => ({})
    }
  },
  data () {
    return {
      customClass: {},
      attributeName: {
        right: 'x',
        left: 'x',
        top: 'y',
        bottom: 'y'
      },
      // 动画开始
      from: {
        left: '-100%',
        right: '100%',
        top: '-100%',
        bottom: '100%'
      },
      // 动画结束
      to: {
        left: '100%',
        right: '-100%',
        top: '100%',
        bottom: '-100%'
      },
      isAnimate: true,
      // 组件内部数据
      innerData: null,
      // 音频播放
      aduio: null,
      // 语音播报
      speech: null,
      // 语音播报定时器
      speechTimer: null
    }
  },
  computed: {

  },
  mixins: [paramsMixins, commonMixins],
  mounted () {
    this.chartInit()
    // 如果点击了生成图片,则先关闭动画
    EventBus.$on('stopMarquee', () => {
      this.isAnimate = false
    })
    // 图片生成完成后,再开启动画
    EventBus.$on('startMarquee', () => {
      this.isAnimate = true
    })
    document.addEventListener('visibilitychange', this.handleVisibilityChange)
  },
  beforeDestroy () {
    EventBus.$off('stopMarquee')
    EventBus.$off('startMarquee')
    // 销毁语音播报定时器
    if (this.speechTimer) {
      clearInterval(this.speechTimer)
    }
  },
  methods: {
    dataFormatting (config, data) {
      // 数据返回成功则赋值
      if (data.success) {
        data = data.data
        // 获取到后端返回的数据,有则赋值
        if (config.dataHandler) {
          try {
            // 此处函数处理data
            eval(config.dataHandler)
          } catch (e) {
            console.error(e)
          }
        }
        config.option.data = data
        config.customize.title = config.option.data[config.dataSource.dimensionField] || config.customize.title
        this.innerData = config
        // 语音播报
      } else {
        // 数据返回失败则赋前端的模拟数据
        config.option.data = []
      }
      return config
    },
    // 语音播报
    voiceBroadcast (config) {
      if (this.innerData) {
        if (config.customize.voiceBroadcast) {
          if (this.innerData.dataSource.businessKey && this.innerData.option.data[this.innerData.dataSource.metricField]) {
            // 如果aduio存在,先销毁这个实例,或者替换它的URL
            if (this.aduio) {
              this.aduio.pause()
              this.aduio = null
            }
            this.aduio = new Audio()
            this.aduio.src = this.innerData.option.data[this.innerData.dataSource.metricField]
            this.aduio.play()
          } else if (config.customize.title) {
            this.speechBroadcast(config.customize.title)
            // 根据配置的时间,定时播报,第一次播报后,再定时播报
            this.speechBroadcast(config.customize.title)
            if (config.customize.dur) {
              this.speechTimer = setInterval(() => {
                this.speechBroadcast(config.customize.title)
              }, config.customize.dur * 1000)
            }
          }
        } else {
          if (this.aduio) {
            this.aduio.pause()
            this.aduio = null
          }
        }
      } else {
        if (config.customize.voiceBroadcast) {
          this.speech = new Speech()
          if (config.customize.dur) {
            this.speechBroadcast(config.customize.title)
            this.speechTimer = setInterval(() => {
              this.speechBroadcast(config.customize.title)
            }, config.customize.dur * 1000)
          }
        }
      }
    },
    // 语音播报
    speechBroadcast (text) {
      if (this.speech.hasBrowserSupport()) {
        this.speech.setLanguage('zh-CN')
        this.speech.pitch = 1
        this.speech.init()
        this.speech.speak({ text: text })
      } else {
        this.$message({
          message: '您的浏览器不支持语音播报',
          type: 'warning'
        })
      }
    },
    changeStyle (config) {
      config = { ...this.config, ...config }
      this.voiceBroadcast(config)
      // 样式改变时更新主题配置
      config.theme = settingToTheme(cloneDeep(config), this.customTheme)
      this.changeChartConfig(config)
      if (config.code === this.activeCode) {
        this.changeActiveItemConfig(config)
      }
    },
    // 监听页面是否可见
    handleVisibilityChange () {
      if (document.visibilityState === 'hidden') {
        if (this.aduio) {
          this.aduio.pause()
        }
        if (this.speech) {
          this.speech.pause()
        }
      } else {
        if (this.aduio) {
          this.aduio.play()
        }
        if (this.speech) {
          this.speech.resume()
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.marquee-box {
  width: 100%;
  height: 100%;
  white-space: nowrap;
  overflow: hidden;

  .scroll-area {
    width: 100%;
    height: 100%;

    .marquee-container {
      width: 100%;
      height: 100%;
      display: flex;

      .svg-container {
        width: 100%;
        height: 100%;
      }
    }
  }
  .icon {
    position: relative;
    top: 0;
    // 清除浮动
  }
}
</style>