package com.gh.gamecenter.video.poster.video

import android.app.Application
import android.graphics.Bitmap
import android.media.MediaMetadataRetriever
import androidx.lifecycle.*
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.entity.VideoEntity
import java.io.File
import kotlin.math.roundToLong

class VideoPosterViewModel(
    application: Application,
    val videoPath: String?,
    val videoEntity: VideoEntity?
) : AndroidViewModel(application) {

    val videoPreviewsLiveData = MutableLiveData<List<VideoPreview>>()

    val previewLiveData = MutableLiveData<VideoPreview>()


    init {
        if (videoPath != null) {
            runOnIoThread { getImagesByVideo() }
        } else if (videoEntity != null) {
            val totalThumbsCount = 10
            val startPosition = 0
            val interval = if (videoEntity.length != 0L) {
                videoEntity.length.toFloat() / totalThumbsCount
            } else {
                2f
            }
            val videoReviews = ArrayList<VideoPreview>()

            for (i in 0 until totalThumbsCount) {
                val frameTime: Long = (startPosition + interval * i).roundToLong()
                val thumbsUrl = ImageUtils.getVideoSnapshot(videoEntity.url, frameTime * 1000)
                val element = VideoPreview(frameTime, null, thumbsUrl)
                videoReviews.add(element)

                if (videoReviews.size == 1) {
                    previewLiveData.postValue(element)
                }
            }
            videoPreviewsLiveData.postValue(videoReviews)
        } else {
            throwExceptionInDebug("video not found")
        }
    }

    private fun getImagesByVideo() {
        throwExceptionInDebug("video file not found", !File(videoPath).exists())

        val mediaMetadataRetriever = MediaMetadataRetriever()
        mediaMetadataRetriever.setDataSource(videoPath)


        val totalThumbsCount = 10
        val startPosition = 0

        val durationString = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
        if (durationString == null) {
            throwExceptionInDebug("video duration must not be null")
            return
        }

        val duration = durationString.toLong()
        val interval = (duration / totalThumbsCount)
        val videoReviews = ArrayList<VideoPreview>()

        for (i in 0 until totalThumbsCount) {
            val frameTime: Long = startPosition + interval * i

            // todo 个别视频使用getFrameAtTime获取到的帧数可能是重复的,在高版本请尝试用getFrameAtIndex实现
            var bitmap: Bitmap? = null
            tryCatchInRelease {
                bitmap = mediaMetadataRetriever.getFrameAtTime(frameTime * 1000)
                // 不知道由于什么原因有可能返回null,所以重试一次吧
                if (bitmap == null) {
                    bitmap = mediaMetadataRetriever.getFrameAtTime(frameTime * 1000)
                }
            }
            if (bitmap == null) continue
            val element = VideoPreview(frameTime * 1000, bitmap)
            videoReviews.add(element)
            videoPreviewsLiveData.postValue(videoReviews)
            if (videoReviews.size == 1) {
                previewLiveData.postValue(element)
            }
        }
        mediaMetadataRetriever.release()
    }

    class VideoPreview(val time: Long, val thumbs: Bitmap? = null, val thumbsUrl: String? = null)

    class Factory(
        private val mApplication: Application,
        private val mVideoPath: String?,
        private val mVideoEntity: VideoEntity?
    ) : ViewModelProvider.NewInstanceFactory() {

        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return VideoPosterViewModel(mApplication, mVideoPath, mVideoEntity) as T
        }
    }
}