<template>
  <div class="root">
    <div class="container-shell">
      <div id="container" ref="container" :style="{ width: width, height: height }"></div>
    </div>
    <div id="jb-pro-ptz-btns" style="display: none">
      <div class="jb-pro-ptz-btns">
        <div class="jb-pro-ptz-btn">
          <div class="jb-pro-ptz-expand jb-pro-ptz-icon">
            <div
              class="jb-pro-ptz-expand-icon-fangda icon"
              onclick="handlePtzScale('fangda')"
            ></div>
            <span class="icon-title-tips">
              <span class="icon-title">放大</span>
            </span>
          </div>
          <div class="jb-pro-ptz-narrow jb-pro-ptz-icon">
            <div
              class="jb-pro-ptz-narrow-icon-suoxiao icon"
              onclick="handlePtzScale('suoxiao')"
            ></div>
            <span class="icon-title-tips">
              <span class="icon-title">缩小</span>
            </span>
          </div>
        </div>

        <div class="jb-pro-ptz-btn">
          <div class="jb-pro-ptz-aperture-far jb-pro-ptz-icon">
            <div
              class="jb-pro-ptz-aperture-icon-guangquan icon"
              onclick="handlePtzScale('guangquan')"
            ></div>
            <span class="icon-title-tips">
              <span class="icon-title">光圈+</span>
            </span>
          </div>
          <div class="jb-pro-ptz-aperture-near jb-pro-ptz-icon">
            <div
              class="jb-pro-ptz-aperture-icon-guangquan- icon"
              onclick="handlePtzScale('guangquan-')"
            ></div>
            <span class="icon-title-tips">
              <span class="icon-title">光圈-</span>
            </span>
          </div>
        </div>

        <div class="jb-pro-ptz-btn">
          <div class="jb-pro-ptz-focus-far jb-pro-ptz-icon">
            <div class="jb-pro-ptz-focus-icon-jujiao icon" onclick="handlePtzScale('jujiao')"></div>
            <span class="icon-title-tips">
              <span class="icon-title">聚焦+</span>
            </span>
          </div>
          <div class="jb-pro-ptz-focus-near jb-pro-ptz-icon">
            <div
              class="jb-pro-ptz-focus-icon-jujiao- icon"
              onclick="handlePtzScale('jujiao-')"
            ></div>
            <span class="icon-title-tips">
              <span class="icon-title">聚焦-</span>
            </span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { ptzdirection, ptzscale } from '@/api/pms/video/sipdevice'
import { func } from 'vue-types'

// 定义props
const props = defineProps({
  playerinfo: {
    type: Object,
    default: null
  },
  width: {
    type: String,
    default: '1000px'
  },
  height: {
    type: String,
    default: '630px'
  }
})

// 定义响应式数据
const container = ref(null)
const isPlaybackPause = ref(false)
const useWebGPU = ref(false)
const isInit = ref(false)
const playinfo = ref({})
const playtype = ref('play')

const operateBtns = reactive({
  fullscreen: true,
  zoom: true,
  play: true,
  audio: true
})

// jessibucaPlayer实例存储
let jessibucaPlayer = {}

// Watch playerinfo变化
watch(
  () => props.playerinfo,
  (newVal, oldVal) => {
    playinfo.value = newVal
    if (newVal && newVal.playtype !== '') {
      playtype.value = newVal.playtype
    }
  }
)

// 组件挂载时执行
onMounted(() => {
  playinfo.value = props.playerinfo
  if (playinfo.value && playinfo.value.playtype !== '') {
    playtype.value = playinfo.value.playtype
  }
  init()
})

// 组件销毁前执行
onBeforeUnmount(() => {
  // 清理资源
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].destroy()
    delete jessibucaPlayer[currentInstanceId.value]
  }
})

// 实例ID
const currentInstanceId = ref(`player_${Date.now()}_${Math.floor(Math.random() * 10000)}`)

// 初始化
const init = async () => {
  await loadJessibuca()
  var isSupportWebgpu = 'gpu' in navigator
  if (isSupportWebgpu) {
    console.log('支持webGPU')
    useWebGPU.value = true
  } else {
    console.log('暂不支持webGPU，降级到webgl渲染')
    useWebGPU.value = false
  }

  const useVconsole = isMobile() || isPad()
  if (useVconsole && window.VConsole) {
    new window.VConsole()
  }

  nextTick(() => {
    initplayer()
  })
}

// 动态加载 Jessibuca
function loadJessibuca() {
  return new Promise((resolve, reject) => {
    if (window.Jessibuca) {
      resolve(window.Jessibuca)
      return
    }

    const script = document.createElement('script')
    script.src = '/js/jessibuca-pro/jessibuca-pro.js'
    script.onload = () => resolve(window.Jessibuca)
    script.onerror = reject
    document.head.appendChild(script)
  })
}

// 初始化播放器
const initplayer = () => {
  isPlaybackPause.value = false
  initconf()

  jessibucaPlayer[currentInstanceId.value] = new window.JessibucaPro({
    container: container.value,
    videoBuffer: Number(0.2), // 缓存时长
    decoder: '/js/jessibuca-pro/decoder-pro.js',
    isResize: false,
    useWCS: false,
    useMSE: false,
    useSIMD: true,
    wcsUseVideoRender: false,
    loadingText: '加载中',
    debug: false,
    debugLevel: 'debug',
    showBandwidth: true, // 显示网速
    showPlaybackOperate: true,
    operateBtns: { ...operateBtns },
    forceNoOffscreen: true,
    isNotMute: true, // 默认关闭声音
    showPerformance: false,
    playbackForwardMaxRateDecodeIFrame: 4,
    useWebGPU: useWebGPU.value // 使用WebGPU
  })

  let jessibuca = jessibucaPlayer[currentInstanceId.value]

  initcallback(jessibuca)

  isInit.value = true
  initPtzBtns()
}

function initPtzBtns() {
  const ptzBtns = document.querySelector('.jessibuca-ptz-controls')
  ptzBtns.appendChild(document.querySelector('#jb-pro-ptz-btns .jb-pro-ptz-btns').cloneNode(true))
  ptzBtns.querySelector('.jb-pro-ptz-expand-icon-fangda').addEventListener('click', () => {
    handlePtzScale('fangda')
  })
  ptzBtns.querySelector('.jb-pro-ptz-narrow-icon-suoxiao').addEventListener('click', () => {
    handlePtzScale('suoxiao')
  })
  ptzBtns.querySelector('.jb-pro-ptz-aperture-icon-guangquan').addEventListener('click', () => {
    handlePtzScale('guangquan')
  })
  ptzBtns.querySelector('.jb-pro-ptz-aperture-icon-guangquan-').addEventListener('click', () => {
    handlePtzScale('guangquan-')
  })
  ptzBtns.querySelector('.jb-pro-ptz-focus-icon-jujiao').addEventListener('click', () => {
    handlePtzScale('jujiao')
  })
  ptzBtns.querySelector('.jb-pro-ptz-focus-icon-jujiao-').addEventListener('click', () => {
    handlePtzScale('jujiao-')
  })
}

function handlePtzScale(arrow) {
  let inOut = 0
  let irisInOut = 0
  let focusInOut = 0
  switch (arrow) {
    case 'fangda': {
      inOut = 1
      break
    }
    case 'suoxiao': {
      inOut = 2
      break
    }
    case 'guangquan': {
      irisInOut = 1
      break
    }
    case 'guangquan-': {
      irisInOut = 2
      break
    }
    case 'jujiao': {
      focusInOut = 1
      break
    }
    case 'jujiao-': {
      focusInOut = 2
      break
    }
  }

  var data = {
    inOut: inOut,
    irisInOut: irisInOut,
    focusInOut: focusInOut
  }
  if (playinfo.value && playinfo.value.playtype !== '') {
    ptzscale(playinfo.value.deviceId, playinfo.value.channelId, data).then((response) => {})
  }
}

// 初始化配置
const initconf = () => {
  if (playtype.value === 'play') {
    //直播按钮配置
    operateBtns.ptz = true
  } else {
    //录像回放按钮配置
    operateBtns.ptz = false
  }
}

// 初始化回调
const initcallback = (jessibuca) => {
  jessibuca.on('error', function (error) {
    console.log('jessibuca error', error)
  })

  jessibuca.on('playFailedAndPaused', function (reason, lastFrameInfo, msg) {
    console.log('playFailedAndPaused', reason, msg)
  })

  jessibuca.on('visibilityChange', (value) => {
    if (value === true) {
      // 窗口显示
      console.log('visibilityChange true')
    } else {
      // 窗口隐藏
      console.log('visibilityChange false')
    }
  })

  jessibuca.on('pause', function (pause) {
    console.log('pause success!', pause)
  })

  jessibuca.on('play', function (flag) {})

  jessibuca.on('loading', function (load) {
    console.log('loading success!', load)
  })

  jessibuca.on('stats', function (s) {
    // console.log('stats is', s)
  })

  jessibuca.on('timeout', function (error) {
    console.log('timeout:', error)
  })

  jessibuca.on('playbackPreRateChange', (rate) => {
    jessibuca.forward(rate)
  })

  let pre = 0
  let cur = 0
  jessibuca.on('timeUpdate', function (ts) {
    cur = parseInt(ts / 60000)
    if (pre !== cur) {
      pre++
    }
  })

  jessibuca.on(window.JessibucaPro.EVENTS.ptz, (arrow) => {
    console.log('ptz arrow', arrow)
    handlePtz(arrow)
  })

  jessibuca.on('crashLog', (data) => {
    console.log('crashLog is', data)
  })
}

// 注册回调
const registercallback = (events, func) => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].on(events, func)
  }
}

// 判断是否为移动设备
const isMobile = () => {
  return /iphone|ipad|android.*mobile|windows.*phone|blackberry.*mobile/i.test(
    window.navigator.userAgent.toLowerCase()
  )
}

// 判断是否为平板设备
const isPad = () => {
  return /ipad|android(?!.*mobile)|tablet|kindle|silk/i.test(
    window.navigator.userAgent.toLowerCase()
  )
}

// 播放
const play = (url) => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].play(url)
  }
}

// 暂停
const pause = () => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].pause()
  }
}

// 重新播放
const replay = (url) => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].destroy().then(() => {
      initplayer()
      play(url)
    })
  } else {
    initplayer()
    play(url)
  }
}

// 处理PTZ控制
const handlePtz = (arrow) => {
  let leftRight = 0
  let upDown = 0
  if (arrow === 'left') {
    leftRight = 2
  } else if (arrow === 'right') {
    leftRight = 1
  } else if (arrow === 'up') {
    upDown = 1
  } else if (arrow === 'down') {
    upDown = 2
  }

  const data = {
    leftRight: leftRight,
    upDown: upDown,
    moveSpeed: 125
  }

  if (playinfo.value && playinfo.value.playtype !== '') {
    ptzdirection(playinfo.value.deviceId, playinfo.value.channelId, data).then(async (response) => {
      //console.log("云台方向控制：" + JSON.stringify(response))
    })
  }
}

// 回放
const playback = (url, playTimes) => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].playback(url, {
      playList: playTimes,
      fps: 25, //FPS（定频(本地设置)生效）
      showControl: true,
      showRateBtn: true,
      isUseFpsRender: true, // 是否使用固定的fps渲染，如果设置的fps小于流推过来的，会造成内存堆积甚至溢出
      isCacheBeforeDecodeForFpsRender: false, // rfs渲染时，是否在解码前缓存数据
      supportWheel: true, // 是否支持滚动轴切换精度。
      rateConfig: [
        { label: '正常', value: 1 },
        { label: '2倍', value: 2 },
        { label: '4倍', value: 4 },
        { label: '8倍', value: 8 }
      ]
    })
    isPlaybackPause.value = false
  }
}

// 暂停回放
const playbackPause = () => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].playbackPause()
    isPlaybackPause.value = true
  }
}

// 重新回放
const replayback = (url, playTimes) => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].destroy().then(() => {
      initplayer()
      playback(url, playTimes)
    })
  } else {
    initplayer()
    playback(url, playTimes)
  }
}

// 设置回放开始时间
const setPlaybackStartTime = (curTime) => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].setPlaybackStartTime(curTime)
  }
}

// 销毁播放器
const destroy = () => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].destroy().then(() => {
      initplayer()
    })
  }
}

// 关闭播放器
const close = () => {
  if (jessibucaPlayer[currentInstanceId.value]) {
    jessibucaPlayer[currentInstanceId.value].close()
  }
}

// 暴露给父组件的方法
defineExpose({
  play,
  pause,
  replay,
  playback,
  playbackPause,
  replayback,
  setPlaybackStartTime,
  destroy,
  close,
  registercallback
})
</script>

<style scoped lang="scss">
.root {
  display: flex;
  margin-right: 3rem;
}

.container-shell {
  backdrop-filter: blur(5px);
  position: relative;
  border-radius: 10px;
}

.container-shell:before {
  position: absolute;
  color: darkgray;
  left: 10px;
}

#container {
  background: rgba(13, 14, 27, 0.7);
  border-radius: 5px;
  width: 600px;
  height: 500px;
}

.err {
  position: absolute;
  top: 40px;
  left: 10px;
  color: red;
}

.option {
  position: absolute;
  top: 4px;
  right: 10px;
  display: flex;
  place-content: center;
  font-size: 12px;
}

.option span {
  color: white;
}

@media (max-width: 720px) {
  #container {
    width: 90vw;
    height: 52.7vw;
  }
}

.jb-pro-ptz-btns {
  .jb-pro-ptz-btn {
    display: flex;
    justify-content: space-around;

    .jb-pro-ptz-icon {
      position: relative;

      .icon {
        width: 28px;
        height: 28px;
        margin-top: 3px;
      }
    }

    .jb-pro-ptz-expand-icon-fangda {
      background-image: url('@/assets/icon/fangda.png');
    }

    .jb-pro-ptz-narrow-icon-suoxiao {
      background-image: url('@/assets/icon/suoxiao.png');
    }

    .jb-pro-ptz-aperture-icon-guangquan {
      background-image: url('@/assets/icon/guangquan+.png');
    }

    .jb-pro-ptz-aperture-icon-guangquan- {
      background-image: url('@/assets/icon/guangquan-.png');
    }

    .jb-pro-ptz-focus-icon-jujiao {
      background-image: url('@/assets/icon/jujiao+.png');
    }

    .jb-pro-ptz-focus-icon-jujiao- {
      background-image: url('@/assets/icon/jujiao-.png');
    }

    .jb-pro-ptz-icon:hover {
      .icon-title-tips {
        visibility: visible;
        opacity: 1;
      }

      .jb-pro-ptz-expand-icon-fangda {
        background-image: url('@/assets/icon/fangda-hov.png');
      }

      .jb-pro-ptz-narrow-icon-suoxiao {
        background-image: url('@/assets/icon/suoxiao-hov.png');
      }

      .jb-pro-ptz-aperture-icon-guangquan {
        background-image: url('@/assets/icon/guangquan-hov+.png');
      }

      .jb-pro-ptz-aperture-icon-guangquan- {
        background-image: url('@/assets/icon/guangquan-hov-.png');
      }

      .jb-pro-ptz-focus-icon-jujiao {
        background-image: url('@/assets/icon/jujiao-hov+.png');
      }

      .jb-pro-ptz-focus-icon-jujiao- {
        background-image: url('@/assets/icon/jujiao-hov-.png');
      }
    }
  }

  img {
    cursor: pointer;
  }
}
</style>
