import { fullscreen, isFullscreen, exitFullscreen } from './util'
import EventName from './event/eventName'
import lcStore from "./service/lcStore";

let index = 0
export default class Api {
  constructor({ video, playContainer, event, flv, hls, resolution, screenNum }) {
    this.player = video
    this.playContainer = playContainer
    this.flv = flv
    this.hls = hls
    this.event = event
    this.scale = 1
    this.position = [0, 0]
    // 分辨率
    this.resolution = resolution
    // 分屏数 其他模式为空
    this.screenNum = screenNum || 0
  }
  /**
   * 播放器销毁后 动态跟新api下的flv，hls对象
   * @param {*} param0
   */
  updateChunk({ flv, hls }) {
    this.flv = flv
    this.hls = hls
  }
  /**
   * 全屏
   */
  requestFullScreen() {
    if (!isFullscreen(this.playContainer)) {
      fullscreen(this.playContainer)
    }
  }
  /**
   * 退出全屏
   */
  cancelFullScreen() {
    if (isFullscreen(this.playContainer)) {
      exitFullscreen()
    }
  }
  play() {
    if (this.player.paused) {
      this.player.play()
    }
  }
  pause() {
    if (!this.player.paused) {
      this.player.pause()
    }
  }
  destroy() {
    this.player?.removeAttribute('src')
    this.flv?.pause()
    this.unload()
    if (this.flv) {
      index++
      this.flv.detachMediaElement && this.flv.detachMediaElement()
      this.flv.destroy()
    }
    if (this.hls) {
      index++
      this.hls.destroy()
    }

    this.player = null
    this.playContainer = null
    this.flv = null
    this.hls = null
    this.event = null
    this.scale = null
    this.position = null
    // this.playbackRate = 1
    console.warn('destroy', index)
  }

  /**
   * 设置currentTime实现seek
   * @param {*} seconds
   * @param {*} noEmit
   */
  seekTo(seconds, noEmit) {
    const buffered = this.getBufferedTime()
    if (this.flv && buffered[0] > seconds) {
      this.flv.unload()
      this.flv.load()
    }
    if (this.player) {
      // console.log(this.player.currentTime)
      this.player.currentTime = seconds
      if (!noEmit) {
        this.event.emit(EventName.SEEK, seconds)
      }
    }
  }

    /**
   * 设置currentTime实现seek
   * @param {*} seconds
   * @param {*} noEmit
   */
    seekHsTo(seconds, noEmit) {
      if (this.player) {
        this.player.currentTime = seconds
        if (!noEmit) {
          this.event.emit(EventName.SEEK, seconds)
        }
      }
    }
  success(notEmit){
    !notEmit && this.event?.emit(EventName.RELOAD)
  }
  /**
   * 视频重载
   */
  reload(notEmit) {
    if (this.getCurrentTime !== 0) {
      this.seekTo(0)
    }
    if (this.hls) {
      this.hls.swapAudioCodec()
      this.hls.recoverMediaError()
    }
    this.unload()
    this.load()
    this.play()
    !notEmit && this.event.emit(EventName.RELOAD)
  }
  unload() {
    this.flv && this.flv.unload()
    this.hls && this.hls.stopLoad()
  }
  load() {
    if (this.flv) {
      this.flv.load()
    }
    if (this.hls) {
      this.hls.startLoad()
      this.hls.loadSource(this.hls.url)
    }
  }
  setVolume(fraction) {
    this.player.volume = fraction
  }
  mute() {
    this.player.muted = true
  }
  unmute() {
    this.player.muted = false
  }

  /**
   * 开启画中画功能
   */
  requestPictureInPicture() {
    if (this.player.requestPictureInPicture && document.pictureInPictureElement !== this.player) {
      this.player.requestPictureInPicture()
    }
  }
  /**
   * 关闭画中画功能
   */
  exitPictureInPicture() {
    if (document.exitPictureInPicture && document.pictureInPictureElement === this.player) {
      document.exitPictureInPicture()
    }
  }

  // /**
  //  * 设置播放速率
  //  * @param {*} rate
  //  */
  // setPlaybackRate(rate) {
  //   this.player.playbackRate = rate
  // }
  /**
   * 获取视频总时长
   */
  getDuration() {
    if (!this.player) return null
    const { duration, seekable } = this.player
    if (duration === Infinity && seekable.length > 0) {
      return seekable.end(seekable.length - 1)
    }
    return duration
  }
  /**
   * 获取当前播放时间
   */
  getCurrentTime() {
    if (!this.player) return null
    return this.player.currentTime
  }

  /**
   * 获取缓存时间
   */
  getSecondsLoaded() {
    return this.getBufferedTime()[1]
  }

  /**
   * 获取当前视频缓存的起止时间
   */
  getBufferedTime() {
    if (!this.player) return []
    const { buffered } = this.player
    if (buffered.length === 0) {
      return [0, 0]
    }
    const end = buffered.end(buffered.length - 1)
    const start = buffered.start(buffered.length - 1)
    const duration = this.getDuration()
    if (end > duration) {
      return duration
    }
    return [start, end]
  }
  /**
   * 快进通过seekTo方法实现
   * @param {*} second
   */
  fastForward(second = 5) {
    const duration = this.getDuration()
    const currentTime = this.getCurrentTime()
    const time = currentTime + second
    if(time > duration - 1 ){
      this.event.emit(EventName.FAST_FORWARD_WITH_SEEK, second)
    }else{
      this.seekTo(time)
    }
  }

  /**
   * 快退通过seekTo方法实现
   * @param {*} second
   */
  backWind(second = 5) {
    const currentTime = this.getCurrentTime()
    const time = currentTime - second
    this.seekTo(time < 1 ? 1 : time)
  }

  /**
   * 视频截屏方法
   */
  snapshot() {
    let canvas = document.createElement('canvas')
    let ctx = canvas.getContext('2d')
    canvas.width = this.player.videoWidth
    canvas.height = this.player.videoHeight
    ctx.drawImage(this.player, 0, 0, canvas.width, canvas.height)
    setTimeout(() => {
      canvas.remove()
      canvas = null
      ctx = null
    }, 200)
    return canvas.toDataURL()
  }
  setScale(num, isRest = false) {
    let scale = this.scale + num
    if (isRest) {
      scale = num
    } else {
      if (scale < 1) {
        scale = 1
      }
      if (scale > 3) {
        scale = 3
      }
    }
    this.scale = scale
    this.player.style.transition = 'transform 0.3s'
    this.__setTransform()
    this.event.emit(EventName.TRANSFORM)
    setTimeout(() => {
      this.player.style.transition = 'unset'
    }, 1000)
  }
  getScale() {
    return this.scale
  }
  /**
   * 获取当前播放对象分辨率
   * @returns 
   */
  getResolution(){
    return this.resolution
  }
  
  /**
   * 获取当前分屏数
   * @returns 
   */
  getCurrentScreen(){
    return this.screenNum
  }
  
  setPosition(position, isAnimate) {
    this.position = position
    this.player.style.transition = isAnimate ? 'transform 0.3s' : 'unset'
    this.__setTransform()
  }
  getPosition() {
    return this.position
  }
  __setTransform() {
    this.player.style.transform = `scale(${this.scale}) translate(${this.position[0]}px,${this.position[1]}px)`
  }
  exeRatioCommand(ratio){
    lcStore.setStreamResolution(ratio)
  }


    /**
   * 设置播放速率
   * @param {*} rate
   */
  setPlaybackRate(rate) {
    this.playbackRate = rate
    this.player && (this.player.playbackRate = rate)
  }

  restPlayRate(){
    this.player.playbackRate = this.playbackRate
  }

  getPlayerIng(){
    return this.player.playbackRate
  }

  getApi() {
    return {
      play: this.play.bind(this),
      reload: this.reload.bind(this),
      unload: this.reload.bind(this),
      success: this.success.bind(this),
      pause: this.pause.bind(this),
      seekTo: this.seekTo.bind(this),
      seekHsTo: this.seekHsTo.bind(this),
      setVolume: this.setVolume.bind(this),
      mute: this.mute.bind(this),
      unmute: this.unmute.bind(this),
      requestPictureInPicture: this.requestPictureInPicture.bind(this),
      exitPictureInPicture: this.exitPictureInPicture.bind(this),
      setPlaybackRate: this.setPlaybackRate.bind(this),
      destroy: this.destroy.bind(this),
      getDuration: this.getDuration.bind(this),
      getCurrentTime: this.getCurrentTime.bind(this),
      getSecondsLoaded: this.getSecondsLoaded.bind(this),
      getBufferedTime: this.getBufferedTime.bind(this),
      fastForward: this.fastForward.bind(this),
      backWind: this.backWind.bind(this),
      snapshot: this.snapshot.bind(this),
      requestFullScreen: this.requestFullScreen.bind(this),
      cancelFullScreen: this.cancelFullScreen.bind(this),
      __player: this.player,
      flv: this.flv,
      hls: this.hls,
      restPlayRate: this.restPlayRate.bind(this),
      getPlayerIng: this.getPlayerIng.bind(this),
    }
  }
}
