<template>
  <div class="camera-player">
    <div
        :id="playerId"
        ref="playerShellRef"
        class="camera-player-shell"
        @click="handleShellClick"
    >
      <div v-if="!ready" class="camera-player-placeholder">
        <strong>{{ loading ? '正在连接摄像头...' : '点击开始播放摄像头画面' }}</strong>
        <span>{{ error || statusText }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onBeforeUnmount, nextTick, watch } from 'vue'
import EZUIKit from 'ezuikit-js'
import { getCameraPlayToken } from '@/api/worn/camera'

const props = defineProps({
  deviceSerial: String
})

const emit = defineEmits(['state-change'])

const playerShellRef = ref(null)
const playerId = `player-${Date.now()}`

const loading = ref(false)
const ready = ref(false)
const playing = ref(false)
const error = ref('')
const statusText = ref('等待播放')

let playerInstance = null

async function getToken() {
  const res = await getCameraPlayToken(props.deviceSerial)
  const data = res.data || {}

  if (!data.accessToken) {
    throw new Error('未获取到accessToken')
  }

  return data.accessToken
}

async function play() {
  if (!props.deviceSerial || loading.value) return

  loading.value = true
  error.value = ''
  statusText.value = '获取播放授权...'
  emitState()

  try {
    const token = await getToken()

    await nextTick()
    destroy()

    statusText.value = '连接摄像头...'
    emitState()

    const shell = playerShellRef.value
    const rect = shell.getBoundingClientRect()

    playerInstance = new EZUIKit.EZUIKitPlayer({
      id: playerId,
      width: rect.width || 600,
      height: rect.height || 400,
      template: 'pcLive',
      url: `ezopen://open.ys7.com/${props.deviceSerial}/1.live`,
      accessToken: token,
      autoplay: true,

      handleSuccess: () => {
        loading.value = false
        ready.value = true
        playing.value = true
        statusText.value = '播放中'
        emitState()
      },

      handleError: (err) => {
        console.error('播放失败:', err)
        loading.value = false
        ready.value = false
        playing.value = false
        error.value = '摄像头播放失败'
        statusText.value = '播放失败'
        emitState()
      }
    })

  } catch (e) {
    console.error('异常:', e)
    loading.value = false
    ready.value = false
    playing.value = false
    error.value = e.message
    statusText.value = '播放异常'
    emitState()
  }
}

function emitState() {
  emit('state-change', {
    loading: loading.value,
    ready: ready.value,
    playing: playing.value,
    error: error.value,
    statusText: statusText.value
  })
}

function destroy() {
  if (playerInstance) {
    try { playerInstance.stop?.() } catch {}
    try { playerInstance.destroy?.() } catch {}
    playerInstance = null
  }
  ready.value = false
  playing.value = false
}

function handleShellClick() {
  if (!ready.value && !loading.value) {
    play()
  }
}

watch(() => props.deviceSerial, () => {
  destroy()
  error.value = ''
  statusText.value = '点击开始播放摄像头'
  emitState()
})

onBeforeUnmount(() => {
  destroy()
})

defineExpose({
  play,
  destroy
})
</script>

<style scoped>
.camera-player {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.camera-player-shell {
  height: 260px;
  border-radius: 16px;
  background: #000;
  overflow: hidden;
  position: relative;
  cursor: pointer;
}

.camera-player-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #fff;
}
</style>