package com.gh.common.video

import android.content.Context
import android.media.AudioManager
import android.net.TrafficStats
import android.net.Uri
import android.os.Message
import android.view.Surface
import com.google.android.exoplayer2.SeekParameters
import com.google.android.exoplayer2.video.DummySurface
import com.shuyu.gsyvideoplayer.cache.ICacheManager
import com.shuyu.gsyvideoplayer.model.GSYModel
import com.shuyu.gsyvideoplayer.model.VideoOptionModel
import com.shuyu.gsyvideoplayer.player.BasePlayerManager
import tv.danmaku.ijk.media.player.IMediaPlayer

/**
 * 基于Exo2PlayerManager修改，主要做了如下改动：
 * 1.使用CustomIjkExo2MediaPlayer代替IjkExo2MediaPlayer
 * 2.复用mediaPlayer的实例，提高内存利用效率
 */
class CustomExo2PlayerManager : BasePlayerManager() {

    private var context: Context? = null

    private var mediaPlayer: CustomIjkExo2MediaPlayer? = null

    private var surface: Surface? = null

    private var dummySurface: DummySurface? = null

    private var lastTotalRxBytes: Long = 0

    private var lastTimeStamp: Long = 0

    override fun getMediaPlayer(): IMediaPlayer? {
        return mediaPlayer
    }

    override fun initVideoPlayer(
        context: Context,
        msg: Message,
        optionModelList: List<VideoOptionModel?>?,
        cacheManager: ICacheManager?
    ) {
        this.context = context.applicationContext

        val mediaPlayer = this.mediaPlayer ?: CustomIjkExo2MediaPlayer().apply {
            mediaPlayer = this
        }

        if (mediaPlayer.appContext != context.applicationContext) {
            mediaPlayer.release()
            mediaPlayer.updateAppContext(context)
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
        }

        if (dummySurface == null) {
            dummySurface = DummySurface.newInstanceV17(context, false)
        }

        //使用自己的cache模式
        val gsyModel = msg.obj as GSYModel
        try {
            mediaPlayer.isLooping = gsyModel.isLooping
            mediaPlayer.isPreview = gsyModel.mapHeadData != null && gsyModel.mapHeadData.isNotEmpty()
            if (gsyModel.isCache && cacheManager != null) {
                //通过管理器处理
                cacheManager.doCacheLogic(context, mediaPlayer, gsyModel.url, gsyModel.mapHeadData, gsyModel.cachePath)
            } else {
                //通过自己的内部缓存机制
                mediaPlayer.isCache = gsyModel.isCache
                mediaPlayer.cacheDir = gsyModel.cachePath
                mediaPlayer.overrideExtension = gsyModel.overrideExtension
                mediaPlayer.setDataSource(context, Uri.parse(gsyModel.url), gsyModel.mapHeadData)
            }
            if (gsyModel.speed != 1f && gsyModel.speed > 0) {
                mediaPlayer.setSpeed(gsyModel.speed, 1f)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        initSuccess(gsyModel)
    }

    override fun showDisplay(msg: Message) {
        if (msg.obj == null) {
            mediaPlayer?.setSurface(dummySurface)
        } else {
            val holder = msg.obj as Surface
            surface = holder
            mediaPlayer?.setSurface(holder)
        }
    }

    override fun setSpeed(speed: Float, soundTouch: Boolean) {
        try {
            mediaPlayer?.setSpeed(speed, 1f)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun setNeedMute(needMute: Boolean) {
        if (needMute) {
            mediaPlayer?.setVolume(0f, 0f)
        } else {
            mediaPlayer?.setVolume(1f, 1f)
        }
    }

    override fun setVolume(left: Float, right: Float) {
        mediaPlayer?.setVolume(left, right)
    }

    override fun releaseSurface() {
        if (surface != null) {
            //surface.release();
            surface = null
        }
    }

    override fun release() {
        mediaPlayer?.setSurface(null)
        mediaPlayer?.release()
        mediaPlayer = null

        dummySurface?.release()
        dummySurface = null
        lastTotalRxBytes = 0
        lastTimeStamp = 0
    }

    override fun getBufferedPercentage(): Int {
        return mediaPlayer?.bufferedPercentage ?: 0
    }

    override fun getNetSpeed(): Long {
        return if (mediaPlayer != null) {
            getNetSpeed(context)
        } else 0
    }


    override fun setSpeedPlaying(speed: Float, soundTouch: Boolean) {}


    override fun start() {
        if (mediaPlayer != null) {
            mediaPlayer!!.start()
        }
    }

    override fun stop() {
        if (mediaPlayer != null) {
            mediaPlayer!!.stop()
        }
    }

    override fun pause() {
        if (mediaPlayer != null) {
            mediaPlayer!!.pause()
        }
    }

    override fun getVideoWidth(): Int {
        return if (mediaPlayer != null) {
            mediaPlayer!!.videoWidth
        } else 0
    }

    override fun getVideoHeight(): Int {
        return if (mediaPlayer != null) {
            mediaPlayer!!.videoHeight
        } else 0
    }

    override fun isPlaying(): Boolean {
        return if (mediaPlayer != null) {
            mediaPlayer!!.isPlaying
        } else false
    }

    override fun seekTo(time: Long) {
        if (mediaPlayer != null) {
            mediaPlayer!!.seekTo(time)
        }
    }

    override fun getCurrentPosition(): Long {
        return if (mediaPlayer != null) {
            mediaPlayer!!.currentPosition
        } else 0
    }

    override fun getDuration(): Long {
        return if (mediaPlayer != null) {
            mediaPlayer!!.duration
        } else 0
    }

    override fun getVideoSarNum(): Int {
        return if (mediaPlayer != null) {
            mediaPlayer!!.videoSarNum
        } else 1
    }

    override fun getVideoSarDen(): Int {
        return if (mediaPlayer != null) {
            mediaPlayer!!.videoSarDen
        } else 1
    }

    override fun isSurfaceSupportLockCanvas(): Boolean {
        return false
    }


    /**
     * 设置seek的临近帧。
     */
    fun setSeekParameter(seekParameters: SeekParameters?) {
        if (mediaPlayer != null) {
            mediaPlayer!!.setSeekParameter(seekParameters)
        }
    }


    private fun getNetSpeed(context: Context?): Long {
        if (context == null) {
            return 0
        }
        val nowTotalRxBytes =
            if (TrafficStats.getUidRxBytes(context.applicationInfo.uid) == TrafficStats.UNSUPPORTED.toLong()) 0 else TrafficStats.getTotalRxBytes() / 1024 //转为KB
        val nowTimeStamp = System.currentTimeMillis()
        val calculationTime = nowTimeStamp - lastTimeStamp
        if (calculationTime == 0L) {
            return calculationTime
        }
        //毫秒转换
        val speed = (nowTotalRxBytes - lastTotalRxBytes) * 1000 / calculationTime
        lastTimeStamp = nowTimeStamp
        lastTotalRxBytes = nowTotalRxBytes
        return speed
    }
}