<template>
  <div
    class="c-video iconfont"
    :style="styles"
  >
    <template v-if="canPlay">
      <video
        ref="player"
        class="c-video__inst"
        :src="src"
        autoplay
        :muted.prop="muted"
        @ended="onEnded"
        @error="onError"
      />
      <canvas
        v-show="isSnapping"
        ref="canvas"
        class="c-video__canvas"
      />
    </template>
  </div>
</template>

<script>
import { getAssetUrl } from '@/api/asset'

export default {
  name: 'CVideo',
  inject: ['control'],
  props: {
    node: {
      type: Object,
      default: null
    }
  },
  data () {
    return {
      ignore: false,
      url: ''
    }
  },
  computed: {
    isSnapping () {
      return this.control.snapping
    },
    styles () {
      const {
        width,
        height,
        radius
      } = this.node
      return {
        width: `${width}px`,
        height: `${height}px`,
        'font-size': `${Math.min(width, height) / 3 | 0}px`,
        'border-radius': `${radius}px`
      }
    },
    src () {
      return this.url ? getAssetUrl(this.url) : ''
    },
    muted () {
      return this.node.mute || this.control.muted
    },
    canPlay () {
      return !this.ignore && this.url
    }
  },
  watch: {
    'node.sources' () {
      this.reset()
    },
    isSnapping (val) {
      let ignore = false
      const player = this.$refs.player
      if (player) {
        if (val) {
          // 尽量保障出画面
          if (player.currentTime && player.currentTime >= 0.5) {
            player.pause()
            this.getSnap()
          } else {
            ignore = true
          }
        } else {
          player.play()
          const canvas = this.$refs.canvas
          if (canvas) {
            canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height)
          }
        }
      }
      this.ignore = ignore
    }
  },
  created () {
    this.reset()
  },
  methods: {
    reset () {
      this.$index = 0
      this.choose()
    },
    choose () {
      const { sources, toggleType } = this.node
      const length = sources.length

      if (length === 0) {
        this.url = ''
        return
      }

      if (length === 1) {
        this.url = sources[0].keyName
        return
      }

      let index
      switch (toggleType) {
        case 'cycle':
          index = this.$index
          this.$index = (index + 1) % length
          break
        case 'random':
          index = Math.random() * length | 0
          if (sources[index]?.keyName === this.url) {
            if (index === 0) {
              index += 1
            } else {
              index -= 1
            }
          }
          break
        default:
          return
      }
      this.url = sources[index].keyName
    },
    onEnded () {
      this.$refs.player.currentTime = 0
      if (this.node.sources.length > 1) {
        this.choose()
      }
      this.$refs.player.play()
    },
    onError (e) {
      console.warn('video error', e)
      if (this.node.sources.length > 1) {
        this.choose()
      }
    },
    getSnap () {
      const video = this.$refs.player
      const canvas = this.$refs.canvas
      if (video && canvas) {
        const cxt = canvas.getContext('2d')
        canvas.width = this.node.width
        canvas.height = this.node.height
        cxt.drawImage(video, 0, 0, this.node.width, this.node.height)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.c-video {
  position: relative;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.8);
  overflow: hidden;

  &::before {
    content: "\ecc1";
    font-size: inherit;
  }

  &__inst,
  &__canvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  &__inst {
    object-fit: fill;
  }
}
</style>
