import Hls from 'hls.js'
import flvjs from 'flv.js'

const DEFAULT_FORMAT_RULES = [
  { type: 'hls', match: '.m3u8', library: 'hls.js' },
  { type: 'flv', match: '.flv', library: 'flv.js' },
  { type: 'mp4', match: '.mp4', library: 'native' },
  { type: 'webm', match: '.webm', library: 'native' }
]

export function getFormatRules(playerConfig) {
  const rules = playerConfig?.formatRules
  return Array.isArray(rules) && rules.length ? rules : DEFAULT_FORMAT_RULES
}

export function detectStreamType(url, playerConfig) {
  if (!url) {
    return 'native'
  }
  const lower = ('' + url).toLowerCase()
  const rules = getFormatRules(playerConfig)
  for (const rule of rules) {
    const match = rule.match ? ('' + rule.match).toLowerCase() : ''
    if (match && lower.includes(match)) {
      return rule.type || 'native'
    }
  }
  return 'native'
}

export function resolveStreamUrl(camera, playerConfig) {
  if (!camera) {
    return ''
  }
  const priority = playerConfig?.urlPriority || ['hdStreamUrl', 'streamUrl', 'playUrl', 'preview']
  for (const key of priority) {
    const value = camera[key]
    if (value) {
      return value
    }
  }
  return ''
}

export function createLivePlayer(videoEl, url, playerConfig = {}) {
  if (!videoEl || !url) {
    return null
  }

  const streamType = detectStreamType(url, playerConfig)
  const options = playerConfig?.playerOptions || {}

  if (streamType === 'hls') {
    if (videoEl.canPlayType('application/vnd.apple.mpegurl')) {
      videoEl.src = url
      videoEl.play().catch(() => {})
      return { type: 'native-hls', videoEl }
    }
    if (Hls.isSupported()) {
      const hls = new Hls({
        enableWorker: true,
        lowLatencyMode: true,
        ...(options.hls || {})
      })
      hls.loadSource(url)
      hls.attachMedia(videoEl)
      hls.on(Hls.Events.MANIFEST_PARSED, () => {
        videoEl.play().catch(() => {})
      })
      hls.on(Hls.Events.ERROR, (_, data) => {
        if (data?.fatal) {
          console.error('HLS 播放失败:', data)
        }
      })
      return { type: 'hls', instance: hls, videoEl }
    }
  }

  if (streamType === 'flv' && flvjs.isSupported()) {
    const flvPlayer = flvjs.createPlayer(
      {
        type: 'flv',
        url,
        isLive: true,
        hasAudio: true,
        hasVideo: true,
        ...(options.flv || {})
      },
      {
        enableWorker: true,
        enableStashBuffer: false,
        ...(options.flvMedia || {})
      }
    )
    flvPlayer.attachMediaElement(videoEl)
    flvPlayer.load()
    flvPlayer.play().catch(() => {})
    return { type: 'flv', instance: flvPlayer, videoEl }
  }

  videoEl.src = url
  videoEl.play().catch(() => {})
  return { type: 'native', videoEl }
}

export function destroyLivePlayer(player) {
  if (!player) {
    return
  }
  if (player.type === 'hls' && player.instance) {
    player.instance.destroy()
  } else if (player.type === 'flv' && player.instance) {
    player.instance.pause()
    player.instance.unload()
    player.instance.detachMediaElement()
    player.instance.destroy()
  }
  if (player.videoEl) {
    player.videoEl.pause()
    player.videoEl.removeAttribute('src')
    player.videoEl.load()
  }
}
