package com.gh.gamecenter.home.video

import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.Surface
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.common.util.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.view.RadiusCardView
import com.gh.download.cache.ExoCacheManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.countDownTimer
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.rxTimer
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.video.detail.CustomManager
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
import io.reactivex.disposables.Disposable
import java.util.*

class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    StandardGSYVideoPlayer(context, attrs) {
    var thumbImage: SimpleDraweeView = findViewById(R.id.thumbImage)
    var containerView: RadiusCardView = findViewById(R.id.container)
    var detailBtn: TextView? = null
    private var mMuteDisposable: Disposable? = null
    private var mMaskDisposable: Disposable? = null
    private val mUUID = UUID.randomUUID().toString()
    private var shouldShowMask = true
    private var mContentLength = 0.0
    private var gameEntity: GameEntity? = null
    private var placeholderColor: String? = null
    private var mClickListener: OnClickListener? = null
    private var randomPlaceholderColor = 0

    override fun getLayoutId(): Int {
        return R.layout.empty_control_video
    }

    fun setData(entity: GameEntity?, color: String?) {
        gameEntity = entity
        placeholderColor = color
        setPlaceholderColor(mThumbImageViewLayout, false)
    }

    fun startPlayLogic(showMask: Boolean) {
        shouldShowMask = showMask
        startPlayLogic()
    }

    override fun startPlayLogic() {
        super.startPlayLogic()
        val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
        if (topVideoVoiceStatus) {
            violenceUpdateMuteStatus()
        }
        resetDetailMask()
    }

    private fun violenceUpdateMuteStatus() {
        if (mMuteDisposable != null) {
            mMuteDisposable?.dispose()
            mMuteDisposable = null
        }
        mMuteDisposable = rxTimer(25) {
            if (it >= 400) {
                mMuteDisposable?.dispose()
                mMuteDisposable = null
            }
            mute()
        }
    }

    fun mute() {
        CustomManager.getCustomManager(getKey()).isNeedMute = true
    }

    fun unMute() {
        CustomManager.getCustomManager(getKey()).isNeedMute = false
    }

    private fun disposableTimer() {
        if (mMuteDisposable != null && !mMuteDisposable!!.isDisposed) {
            mMuteDisposable?.dispose()
            mMuteDisposable = null
        }
    }

    private fun showDetailMask() {
        detailBtn = (parent as ViewGroup).findViewById(R.id.detailBtn)
        if (mMaskDisposable != null) {
            mMaskDisposable?.dispose()
            mMaskDisposable = null
        }
        setPlaceholderColor(detailBtn)
        mMaskDisposable = countDownTimer(5) { finish, _ ->
            if (finish) {
                val offset = 44f.dip2px().toFloat()
                containerView.setRadius(6f, 6f, 0f, 0f)

                detailBtn?.let { mask ->
                    var params = mask.layoutParams as ConstraintLayout.LayoutParams
                    params.height = 0
                    mask.layoutParams = params
                    mask.alpha = 0f
                    mask.visibility = VISIBLE
                    val heightAnimator = ValueAnimator.ofFloat(0f, offset).apply {
                        addUpdateListener {
                            params = mask.layoutParams as ConstraintLayout.LayoutParams
                            params.height = (it.animatedValue as Float).toInt()
                            mask.layoutParams = params
                        }
                    }
                    val alphaAnimator = ValueAnimator.ofFloat(0f, 1F).apply {
                        addUpdateListener {
                            mask.alpha = it.animatedValue as Float
                        }
                    }
                    val animatorSet = AnimatorSet()
                    animatorSet.playTogether(heightAnimator, alphaAnimator)
                    animatorSet.duration = 300L
                    animatorSet.doOnEnd {
                        uploadVideoStreamingPlaying("出现遮罩")
                    }
                    animatorSet.start()
                }
            }
        }
    }

    private fun setPlaceholderColor(view: View?, isOnlyTop: Boolean = true) {
        if (!placeholderColor.isNullOrEmpty()) {
            try {
                //去掉透明度
                val color = if (placeholderColor!!.length == 9) {
                    "#${placeholderColor!!.substring(3)}"
                } else {
                    placeholderColor
                }
                if (color!!.length < 7) {
                    setRandomBackground(view, isOnlyTop)
                } else {
                    val topRadius = if (isOnlyTop) 0f else 6f
                    val drawable = DrawableView.getCornerDrawable(Color.parseColor(color), topRadius, topRadius, 6f, 6f)
                    view?.background = drawable
                }
            } catch (e: Exception) {
                setRandomBackground(view, isOnlyTop)
            }
        } else {
            setRandomBackground(view, isOnlyTop)
        }
    }

    private fun setRandomBackground(view: View?, isOnlyTop: Boolean = true) {
        if (randomPlaceholderColor == 0) {
            randomPlaceholderColor = RandomUtils.getRandomPlaceholderColor()
        }
        val topRadius = if (isOnlyTop) 0f else 6f
        val drawable = DrawableView.getCornerDrawable(
            ContextCompat.getColor(context, randomPlaceholderColor),
            topRadius,
            topRadius,
            6f,
            6f
        )
        view?.background = drawable
    }

    fun resetDetailMask() {
        detailBtn?.visibility = View.GONE
        containerView.setRadius(6f, 6f, 6f, 6f)
        if (mMaskDisposable != null && !mMaskDisposable!!.isDisposed) {
            mMaskDisposable?.dispose()
            mMaskDisposable = null
        }
    }

    override fun releaseVideos() {
        super.releaseVideos()
        uploadVideoStreamingPlaying("结束播放")
        CustomManager.releaseAllVideos(getKey())
    }

    override fun onAutoCompletion() {
        super.onAutoCompletion()
        uploadVideoStreamingPlaying("播放完毕")
    }

    override fun getGSYVideoManager(): GSYVideoViewBridge {
        CustomManager.getCustomManager(getKey()).initContext(context.applicationContext)
        return CustomManager.getCustomManager(getKey())
    }

    fun getKey(): String {
        return mUUID
    }

    fun getUrl(): String {
        return mUrl
    }

    /******************* 下方两个重载方法，在播放开始前不屏蔽封面，不需要可屏蔽 ********************/

    override fun onSurfaceUpdated(surface: Surface) {
        super.onSurfaceUpdated(surface)
        if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
            mThumbImageViewLayout.visibility = View.INVISIBLE
            if (shouldShowMask) {
                showDetailMask()
                shouldShowMask = true
            }
            uploadVideoStreamingPlaying("开始播放")
        }
    }

    fun updateThumb(url: String) {
        ImageUtils.display(thumbImage, url)
    }

    override fun setViewShowState(view: View?, visibility: Int) {
        if (view === mThumbImageViewLayout && visibility != View.VISIBLE) {
            return
        }
        super.setViewShowState(view, visibility)
    }

    /********************************各类UI的状态显示*********************************************/

    override fun touchSurfaceMoveFullLogic(absDeltaX: Float, absDeltaY: Float) {
        super.touchSurfaceMoveFullLogic(absDeltaX, absDeltaY)
        //不给触摸快进，如果需要，屏蔽下方代码即可
        mChangePosition = false
        //不给触摸音量，如果需要，屏蔽下方代码即可
        mChangeVolume = false
        //不给触摸亮度，如果需要，屏蔽下方代码即可
        mBrightness = false
    }

    override fun touchDoubleUp(e: MotionEvent?) {

    }

    fun getCurrentPosition(): Long {
        return mCurrentPosition
    }

    fun setCurrentPosition(mCurrentPosition: Long) {
        this.mCurrentPosition = mCurrentPosition
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        disposableTimer()
        resetDetailMask()
    }

    fun setOnVideoClickListener(listener: OnClickListener) {
        mClickListener = listener
    }

    override fun onClick(v: View?) {
        //super.onClick(v)
        mClickListener?.onClick(v)
    }

    fun uploadVideoStreamingPlaying(action: String, hasDetailMask: Boolean? = null) {
        if (gameEntity == null) return
        val topVideo = gameEntity?.topVideo
        if (topVideo == null || topVideo.url.isEmpty()) return
        runOnIoThread(isHeavyWightTask = true) {
            val videoPlayTs = currentPositionWhenPlaying / 1000
            val videoTotalTime = duration / 1000
            val progress = if (videoTotalTime != 0) videoPlayTs.toFloat() / videoTotalTime.toFloat() * 100 else 0f
            if (mContentLength == 0.0) {
                mContentLength = ExoCacheManager.getContentLength(topVideo.url) / 1024.0 / 1024.0
            }

            //https://exoplayer.dev/hello-world.html#a-note-on-threading
            runOnUiThread {
                LogUtils.uploadHomeVideoStreamingPlaying(
                    action, hasDetailMask
                        ?: (detailBtn?.visibility == View.VISIBLE), topVideo.id, topVideo.title,
                    gameEntity?.id, gameEntity?.name, mContentLength, videoTotalTime, videoPlayTs, progress.toInt()
                )
            }
        }
    }
}