import { defineComponent, nextTick, onMounted, reactive, toRefs, watch } from 'vue'
import 'plyr/dist/plyr.css'
import Plyr from 'plyr'
import styles from './index.module.less'

import iconLoop from '../../image/icon-loop.svg'
import iconLoopActive from '../../image/icon-loop-active.svg'
import iconplay from '../../image/icon-play.svg'
import iconpause from '../../image/icon-pause.svg'
import { iconVideoBg } from '../../image/icons.json'

export default defineComponent({
  name: 'video-play',
  props: {
    item: {
      type: Object,
      default: () => {
        return {}
      }
    },
    activeModel: {
      type: Boolean,
      default: true
    }
  },
  emits: ['play', 'pause', 'ended', 'close'],
  setup(props, { emit, expose }) {
    const { item } = toRefs(props)
    const data = reactive({
      videoContianerRef: null as unknown as HTMLAudioElement,
      videoState: 'pause' as 'init' | 'play' | 'pause',
      animationState: 'start' as 'start' | 'end',
      videoItem: null as unknown as Plyr
    })
    const controlID = 'v' + Date.now() + Math.floor(Math.random() * 100)
    const playBtnId = 'play' + Date.now() + Math.floor(Math.random() * 100)
    const loopBtnId = 'loop' + Date.now() + Math.floor(Math.random() * 100)

    const togglePlay = (e: Event) => {
      e.stopPropagation()
      if (!data.videoContianerRef.paused) {
        data.videoItem?.pause()
      } else {
        data.videoContianerRef?.play()
      }
    }
    const toggleLoop = () => {
      const loopBtn = document.getElementById(loopBtnId)
      if (!loopBtn || !data.videoItem) return
      const isLoop = data.videoItem.loop
      if (isLoop) {
        loopBtn.classList.remove(styles.active)
      } else {
        loopBtn.classList.add(styles.active)
      }
      data.videoItem.loop = !data.videoItem.loop
    }
    const onDefault = () => {
      document.getElementById(controlID)?.addEventListener('click', (e: Event) => {
        e.stopPropagation()
        if (data.videoContianerRef.paused) return
        emit('close')
      })
      document.getElementById(controlID)?.addEventListener('touchmove', () => {
        if (data.videoContianerRef.paused) return
        emit('close')
      })
      document.getElementById(playBtnId)?.addEventListener('click', togglePlay)
      document.getElementById(loopBtnId)?.addEventListener('click', toggleLoop)
      setName()
    }
    const setName = () => {
      const nameEl = document.getElementById('videoItemName')
      if (nameEl) {
        nameEl.innerHTML = item.value.name || ''
      }
    }

    const changePlayBtn = (code: string) => {
      const playBtn = document.getElementById(playBtnId)
      if (!playBtn) return
      if (code == 'play') {
        playBtn.classList.remove(styles.btnPause)
        playBtn.classList.add(styles.btnPlay)
      } else {
        playBtn.classList.remove(styles.btnPlay)
        playBtn.classList.add(styles.btnPause)
      }
    }
    const controls = `
            <div id="${controlID}" class="plyr__controls bottomFixed ${styles.controls}">
                <div class="${styles.time}">
                    <div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
                    <div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
                </div>
                <div class="${styles.slider}">
                    <div class="plyr__progress">
                        <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" aria-label="Seek">
                        <progress class="plyr__progress__buffer" min="0" max="100" value="0">% buffered</progress>
                        <span role="tooltip" class="plyr__tooltip">00:00</span>
                    </div>
                </div>
                <div class="${styles.actions}">
                    <div class="${styles.actionWrap}">
                        <button id="${playBtnId}" class="${styles.actionBtn}">
                            <div class="van-loading van-loading--circular" aria-live="polite" aria-busy="true"><span class="van-loading__spinner van-loading__spinner--circular" style="color: rgb(255, 255, 255);"><svg class="van-loading__circular" viewBox="25 25 50 50"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
                            <img class="${styles.playIcon}" src="${iconplay}" />
                            <img class="${styles.playIcon}" src="${iconpause}" />
                        </button>
                        <button id="${loopBtnId}" class="${styles.actionBtn} ${styles.loopBtn}">
                            <img class="loop" src="${iconLoop}" />
                            <img class="loopActive" src="${iconLoopActive}" />
                        </button>
                    </div>
                    <div id="videoItemName"></div>
                </div>
            </div>`

    onMounted(() => {
      data.videoItem = new Plyr(data.videoContianerRef, {
        autoplay: true,
        controls: controls,
        ratio: '16:9', // 强制所有视频的纵横比
        hideControls: false, // 在 2 秒没有鼠标或焦点移动、控制元素模糊（制表符退出）、播放开始或进入全屏时自动隐藏视频控件。只要移动鼠标、聚焦控制元素或暂停播放，控件就会立即重新出现。
        clickToPlay: false, // 单击（或点击）视频容器将切换播放/暂停
        fullscreen: { enabled: false, fallback: false, iosNative: false } // 不适用全屏
      })

      nextTick(() => {
        onDefault()
      })
    })

    const toggleHideControl = (isShow: boolean) => {
      data.videoItem?.toggleControls(isShow)
    }
    watch(
      () => props.activeModel,
      () => {
        toggleHideControl(props.activeModel)
      }
    )

    watch(
      () => props.item,
      () => {
        setName()
      }
    )
    let videoTimer = null as any
    const handlePlayVideo = () => {
      clearTimeout(videoTimer)
      nextTick(() => {
        data.videoContianerRef.play().catch((err) => {
          console.log('🚀 ~ err:', err)
          videoTimer = setTimeout(() => {
            if (err?.message?.includes('play()')) {
              emit('play')
            }
            handlePlayVideo()
          }, 1000)
        })
      })
    }

    let videoErrorTimer = null as any
    let videoErrorCount = 0
    const handleErrorVideo = () => {
      if (videoErrorCount > 5) {
        return
      }
      clearTimeout(videoErrorTimer)
      nextTick(() => {
        videoErrorTimer = setTimeout(() => {
          data.videoContianerRef.src = props.item?.content
          emit('play')
          data.videoContianerRef.load()
          // eslint-disable-next-line @typescript-eslint/no-unused-vars
          handleErrorVideo()
        }, 1000)
      })
      videoErrorCount++
    }
    const getVideoRef = () => {
      return data.videoContianerRef;
    }
    expose({
      getVideoRef
    })

    return () => (
      <div class={styles.videoWrap}>
        <video
          ref={(el) => (data.videoContianerRef = el as unknown as HTMLAudioElement)}
          class={styles.itemDiv}
          src={props.item?.content}
          poster={iconVideoBg}
          webkit-playsinline
          playsinline
          x5-video-player-type="h5"
          onLoadedmetadata={() => {
            data.videoState = 'pause'
            changePlayBtn('play')
            nextTick(() => {
              data.videoContianerRef.currentTime = 0
              nextTick(handlePlayVideo)
            })
          }}
          onPlay={() => {
            videoErrorCount = 0
            console.log('开始播放')
            data.videoState = 'play'
            changePlayBtn('pause')
            emit('close')
            emit('play')
            clearTimeout(videoErrorTimer)
          }}
          onPause={() => {
            console.log('暂停播放')
            data.videoState = 'pause'
            changePlayBtn('play')
            emit('pause')
          }}
          onEnded={() => {
            console.log('播放结束')
            data.videoState = 'pause'
            changePlayBtn('play')
            emit('ended')
          }}
          onError={handleErrorVideo}
        ></video>
      </div>
    )
  }
})
