let EZUIKitPlayerClass = null

let loadPromise = null



// scaleMode: 0=拉伸 1=等比完整显示 2=等比填满(会超出容器裁切)

const DEFAULT_SCALE_MODE = 1



function pickEZUIKitPlayer(mod) {

  if (!mod) {

    return null

  }



  const candidates = [

    mod.EZUIKitPlayer,

    mod.default?.EZUIKitPlayer,

    mod.default?.default?.EZUIKitPlayer,

    typeof mod.default === 'function' ? mod.default : null

  ]



  for (const item of candidates) {

    if (typeof item === 'function') {

      return item

    }

  }



  return null

}



export async function loadEZUIKitPlayer() {

  if (EZUIKitPlayerClass) {

    return EZUIKitPlayerClass

  }



  if (!loadPromise) {

    loadPromise = import('ezuikit-js').then((mod) => {

      EZUIKitPlayerClass = pickEZUIKitPlayer(mod)

      if (!EZUIKitPlayerClass) {

        throw new Error('EZUIKitPlayer 加载失败')

      }

      return EZUIKitPlayerClass

    })

  }



  return loadPromise

}



export function resolveEzopenUrl(camera, playerConfig = {}) {

  if (!camera) {

    return ''

  }



  if (camera.ezopenUrl) {

    return camera.ezopenUrl

  }



  const priority = playerConfig.urlPriority || ['hdPlayUrl', 'playUrl', 'ezopenUrl']

  for (const key of priority) {

    const value = camera[key]

    if (value && String(value).startsWith('ezopen://')) {

      return value

    }

  }



  const serial = camera.serialNumber || camera.serial_number

  const channel = camera.channelNumber ?? camera.channel_number ?? 1

  if (serial) {

    const quality = playerConfig.ezviz?.defaultQuality || 'hd.live'

    return `ezopen://open.ys7.com/${serial}/${channel}.${quality}`

  }



  for (const key of priority) {

    const value = camera[key]

    if (value) {

      return value

    }

  }



  return ''

}



export function buildEzvizDomId(playerId) {

  return `ezviz-player-${String(playerId).replace(/[^a-zA-Z0-9_-]/g, '_')}`

}



export function getPlayerMeasureTarget(containerEl) {

  return containerEl?.closest?.('.screen-body') || containerEl

}



export function getPlayerMeasureSize(containerEl) {

  const target = getPlayerMeasureTarget(containerEl)

  const width = Math.floor(target.clientWidth || target.getBoundingClientRect().width)

  const height = Math.floor(target.clientHeight || target.getBoundingClientRect().height)

  return {

    width: width > 0 ? width : 640,

    height: height > 0 ? height : 360

  }

}



export function syncPlayerContainer(containerEl) {

  if (!containerEl) {

    return { width: 0, height: 0 }

  }



  const measureTarget = getPlayerMeasureTarget(containerEl)

  const { width, height } = getPlayerMeasureSize(containerEl)



  measureTarget.style.overflow = 'hidden'

  containerEl.style.width = `${width}px`

  containerEl.style.height = `${height}px`

  containerEl.style.maxWidth = `${width}px`

  containerEl.style.maxHeight = `${height}px`



  return { width, height }

}



function resolveScaleMode(playerConfig = {}) {

  const mode = playerConfig.ezviz?.scaleMode

  return mode === 0 || mode === 1 || mode === 2 ? mode : DEFAULT_SCALE_MODE

}



export function applyPlayerLayout(player, containerEl, playerConfig = {}) {

  if (!player || !containerEl) {

    return { width: 0, height: 0 }

  }



  const scaleMode = resolveScaleMode(playerConfig)

  const { width, height } = syncPlayerContainer(containerEl)



  if (typeof player.setScaleMode === 'function') {

    player.setScaleMode(scaleMode)

  }



  if (width > 0 && height > 0) {

    if (typeof player.reSize === 'function') {

      player.reSize(width, height)

    } else if (typeof player.resize === 'function') {

      player.resize(width, height)

    }

  }



  return { width, height }

}



export async function createEzvizPlayer(containerEl, { url, accessToken, playerConfig = {} }) {

  if (!containerEl || !url || !accessToken) {

    return null

  }



  const EZUIKitPlayer = await loadEZUIKitPlayer()

  const scaleMode = resolveScaleMode(playerConfig)

  const { width, height } = syncPlayerContainer(containerEl)



  const player = new EZUIKitPlayer({

    id: containerEl.id,

    accessToken,

    url,

    width,

    height,

    staticPath: playerConfig.staticPath || '/ezuikit_static',

    template: playerConfig.ezviz?.template || 'simple',

    scaleMode,

    audio: playerConfig.ezviz?.audio ?? false

  })



  const relayout = () => applyPlayerLayout(player, containerEl, playerConfig)



  requestAnimationFrame(relayout)

  window.setTimeout(relayout, 100)



  if (player?.eventEmitter?.on) {

    player.eventEmitter.on('firstFrameDisplay', relayout)

    player.eventEmitter.on('decoderLoaded', relayout)

    player.eventEmitter.on('resize', relayout)

  }



  return player

}



export async function destroyEzvizPlayer(player) {

  if (!player) {

    return

  }



  try {

    if (typeof player.stop === 'function') {

      await player.stop()

    }

  } catch (_) {

    // ignore stop errors during teardown

  }



  try {

    if (typeof player.destroy === 'function') {

      player.destroy()

    }

  } catch (_) {

    // ignore destroy errors during teardown

  }

}



export async function resizeEzvizPlayer(player, containerEl, playerConfig = {}) {

  applyPlayerLayout(player, containerEl, playerConfig)

}


