package com.gh.gamecenter.video.detail

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.os.Handler
import android.preference.PreferenceManager
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.Surface
import android.view.View
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.SeekBar
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.airbnb.lottie.LottieAnimationView
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.download.cache.ExoCacheManager
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.NormalShareEntity
import com.gh.gamecenter.common.observer.MuteCallback
import com.gh.gamecenter.common.observer.VolumeObserver
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.LayoutVideoDetailSurfaceBinding
import com.gh.gamecenter.entity.MenuItemEntity
import com.gh.gamecenter.entity.VideoEntity
import com.gh.gamecenter.eventbus.EBRecommed
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.comment.CommentActivity
import com.gh.gamecenter.qa.dialog.MoreFunctionPanelDialog
import com.gh.gamecenter.video.game.GameVideoActivity
import com.halo.assistant.HaloApp
import com.jakewharton.rxbinding2.view.RxView
import com.lightgame.utils.Utils
import com.shuyu.gsyvideoplayer.listener.VideoAllCallBack
import com.shuyu.gsyvideoplayer.utils.Debuger
import com.shuyu.gsyvideoplayer.utils.NetInfoModule
import com.shuyu.gsyvideoplayer.utils.NetworkUtils
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYVideoView
import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
import io.reactivex.disposables.Disposable
import org.greenrobot.eventbus.EventBus
import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit

class DetailPlayerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    StandardGSYVideoPlayer(context, attrs) {

    private val mEntrance = "(视频详情)"
    private var mVideoEntity: VideoEntity? = null
    private var mViewModel: VideoDetailContainerViewModel? = null
    private lateinit var mBinding: LayoutVideoDetailSurfaceBinding

    private var mGameName = ""
    private var mCombinedTitleAndId = ""
    private var mLastBufferPoint = 0
    private var mDuration = 0
    private var mRetry = false
    private var byStartedClick = false //第一次进入不显示mBottomContainer
    private var mContentLength = 0.0
    private var mIsDragSeek = false//是否拖动进度条
    private var mMuteCallback: MuteCallback
    private var mVolumeObserver: VolumeObserver
    private var mScheduledHideDisposable: Disposable? = null //延迟隐藏mBottomContainer计时器
    private var mLastClickTime = 0L
    private var mLastGetContentLengthTime = 0L
    private var mLottieLike: LottieAnimationView? = null
    private var mHandler: Handler? = null
    private var weChatAnimate: AnimatorSet? = null
    private var mPlayRetryCount = 0//播放错误重试次数
    private var mFragmentRef: WeakReference<Fragment>? = null
    var repeatPlayCount = 0 //重复播放次数
    var watchedContainer = findViewById<View>(R.id.watchedContainer)
    var watchedTv = findViewById<TextView>(R.id.watchedTv)

    init {
        mHandler = Handler {
            if (!mChangePosition && !mChangeVolume && !mBrightness) {
                onClickUiToggle(null)
            }
            true
        }
        gestureDetector =
            GestureDetector(getContext().applicationContext, object : GestureDetector.SimpleOnGestureListener() {

            })
        mMuteCallback = object : MuteCallback {
            override fun onMute(isMute: Boolean) {
                if (isMute) {
                    mute()
                } else {
                    unMute()
                }
            }
        }
        mVolumeObserver = VolumeObserver(mMuteCallback)
    }

    override fun onTouch(v: View?, event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_UP) {
            mHandler?.removeCallbacksAndMessages(null)
            val newClickTime = System.currentTimeMillis()
            if (newClickTime - mLastClickTime < 300) {
                touchDoubleUp(event)
            } else {
                mHandler?.sendEmptyMessageDelayed(1, 300)
            }
            mLastClickTime = newClickTime
        }
        return super.onTouch(v, event)
    }

    override fun init(context: Context) {
        super.init(context)
        mBinding = LayoutVideoDetailSurfaceBinding.bind(this.getChildAt(0))
        if (mThumbImageViewLayout != null && (mCurrentState == -1 || mCurrentState == GSYVideoView.CURRENT_STATE_NORMAL || mCurrentState == GSYVideoView.CURRENT_STATE_ERROR)) {
            mThumbImageViewLayout.visibility = View.VISIBLE
        }
        if (mIfCurrentIsFullscreen) {
            showBackBtn()
        } else {
            hideBackBtn()
        }
    }

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

    fun setViewModel(viewModel: VideoDetailContainerViewModel) {
        mViewModel = viewModel
        unMute()
        mBinding.volume.setOnClickListener {
            toggleMute()
        }
    }

    fun setFragment(fragment: Fragment) {
        mFragmentRef = WeakReference(fragment)
    }

    fun observeVolume(activity: AppCompatActivity) {
        activity.contentResolver?.registerContentObserver(
            android.provider.Settings.System.CONTENT_URI, true, mVolumeObserver
        )
    }

    fun unObserveVolume(activity: AppCompatActivity) {
        activity.contentResolver?.unregisterContentObserver(mVolumeObserver)
    }

    @SuppressLint("CheckResult")
    fun updateViewDetail(videoEntity: VideoEntity) {
        mVideoEntity = videoEntity
        mGameName = videoEntity.game?.name ?: videoEntity.gameName ?: ""
        mCombinedTitleAndId = StringUtils.combineTwoString(videoEntity.title, videoEntity.id)
        mBinding.gameNameTv.text = mGameName
        mBinding.usernameTv.text = "@${videoEntity.user.name}"
        mBinding.videoTitleTv.text = videoEntity.title
        mBinding.ipRegionTv.goneIf(!(videoEntity.ipSource != null && videoEntity.ipSource.region.isNotEmpty()))
        mBinding.ipRegionTv.text = "IP属地：${videoEntity.ipSource?.region}"

        if (videoEntity.user.badge != null) {
            mBinding.sdvUserBadge.visibility = View.VISIBLE
            ImageUtils.display(mBinding.sdvUserBadge, videoEntity.user.badge?.icon)
        } else {
            mBinding.sdvUserBadge.visibility = View.GONE
        }
        mBinding.sdvUserBadge.setOnClickListener {
            DialogUtils.showViewBadgeDialog(context, videoEntity.user.badge) {
                MtaHelper.onEvent("进入徽章墙_用户记录", "视频详情", "${videoEntity.user.name}（${videoEntity.user.id}）")
                MtaHelper.onEvent("徽章中心", "进入徽章中心", "视频详情")
                DirectUtils.directToBadgeWall(
                    context,
                    videoEntity.user.id,
                    videoEntity.user.name,
                    videoEntity.user.icon
                )
            }
        }

        if (videoEntity.me.isVoted && UserManager.getInstance().isLoggedIn) {
            mBinding.likeIv.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_video_detail_liked))
        } else {
            mBinding.likeIv.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_video_detail_like))
        }
        mBinding.attentionIv.goneIf(videoEntity.user.id == UserManager.getInstance().userId || videoEntity.me.isFollower)
        mBinding.attentionIv.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_video_detail_follow))
        if (!mBinding.likeContainer.hasOnClickListeners())
            RxView.clicks(mBinding.likeContainer)
                .throttleFirst(1, TimeUnit.SECONDS)
                .subscribe {
                    like()
                }

        mBinding.shareCountTv.text = videoEntity.shareCount.toString()
        mBinding.likeCountTv.text = videoEntity.vote.toString()
        mBinding.commentCountTv.text = videoEntity.commentCount.toString()

        mBinding.gameIconView.displayGameIcon(
            videoEntity.game?.rawIcon
                ?: videoEntity.gameIcon, videoEntity.game?.iconSubscript, videoEntity.game?.iconFloat
        )
        ImageUtils.display(mBinding.userIconIv, videoEntity.user.icon)
        if (videoEntity.user.border.isNotEmpty()) {
            mBinding.userIconBorderIv.visibility = View.VISIBLE
            ImageUtils.display(mBinding.userIconBorderIv, videoEntity.user.border)
        } else {
            mBinding.userIconBorderIv.visibility = View.INVISIBLE
        }

        mBinding.usernameTv.setOnClickListener {
            recordMta("点击用户名字")
            MtaHelper.onEvent("视频详情", "点击名字", mCombinedTitleAndId)
            uploadVideoStreamingPlaying("点击昵称")
            DirectUtils.directToHomeActivity(
                context, videoEntity.user.id
                    ?: "", 2, mEntrance, "视频详情"
            )
        }

        mBinding.userIconIv.setOnClickListener {
            recordMta("点击用户头像")
            MtaHelper.onEvent("视频详情", "点击用户头像", mCombinedTitleAndId)
            uploadVideoStreamingPlaying("点击头像")
            DirectUtils.directToHomeActivity(
                context, videoEntity.user.id
                    ?: "", 2, mEntrance, "视频详情"
            )
        }

        mBinding.gameName.setOnClickListener {
            if (videoEntity.gameActive) {
                recordMta("点击游戏名字")
                MtaHelper.onEvent("视频详情", "点击游戏名字", mCombinedTitleAndId)
                uploadVideoStreamingPlaying("点击游戏名字")
                context.startActivity(GameVideoActivity.getIntent(context, videoEntity.gameId, mEntrance, "视频详情"))
            }
        }

        mBinding.gameIconView.setOnClickListener {
            recordMta("查看游戏")
            MtaHelper.onEvent("视频详情", "查看游戏", mCombinedTitleAndId)
            uploadVideoStreamingPlaying("点击游戏图标")
            if (videoEntity.game?.exposureEvent != null) {
                GameDetailActivity.startGameDetailActivity(
                    context,
                    videoEntity.gameId,
                    mEntrance,
                    videoEntity.game?.exposureEvent
                )
            }
        }

        mBinding.commentContainer.setOnClickListener {
            recordMta("评论")
            MtaHelper.onEvent("视频详情", "评论", mCombinedTitleAndId)
            uploadVideoStreamingPlaying("打开评论弹窗")
            when (videoEntity.status) {
                "pass" -> {
                    if (mViewModel != null) {
                        mViewModel?.isPauseVideo = false
                    }
                    val intent = CommentActivity.getVideoCommentIntent(
                        context,
                        videoEntity.id,
                        videoEntity.commentCount,
                        videoEntity.user.id == UserManager.getInstance().userId,
                        false
                    )
                    (context as Activity).startActivityForResult(intent, CommentActivity.REQUEST_CODE)
                }
                "pending", "fail" -> {
                    Utils.toast(context, "该作品正在审核中，暂时无法评论哦")
                }
            }
        }

        mBinding.attentionIv.setOnClickListener {
            SensorsBridge.trackUserFollowClick(
                userId = videoEntity.user.id ?: "",
                userName = videoEntity.user.name ?: "",
                buttonName = "关注"
            )
            if (!videoEntity.me.isFollower) {
                if (!CheckLoginUtils.isLogin()) {
                    CheckLoginUtils.checkLogin(context, mEntrance) {}
                    recordMta("关注用户-请先登录")
                    uploadVideoStreamingPlaying("关注用户-请先登录")
                    MtaHelper.onEvent("视频详情", "关注用户-请先登录", mCombinedTitleAndId)
                } else {
                    if (!NetworkUtils.isAvailable(mContext)) {
                        ToastUtils.showToast("网络错误")
                        return@setOnClickListener
                    }
                    mViewModel?.follow(videoEntity)
                    mBinding.attentionLottie.visibility = View.VISIBLE
                    mBinding.attentionIv.visibility = View.GONE
                    mBinding.attentionLottie.setAnimation("lottie/follow.json")
                    mBinding.attentionLottie.playAnimation()
                    mBinding.attentionLottie.doOnAnimationEnd {
                        mBinding.attentionLottie.visibility = View.GONE
                        recordMta("关注用户")
                        uploadVideoStreamingPlaying("关注用户")
                        MtaHelper.onEvent("视频详情", "关注用户", mCombinedTitleAndId)
                    }
                }
            }
        }

        mBinding.shareContainer.setOnClickListener {
            recordMta("分享")
            val shareEntity = getShareEntity() ?: return@setOnClickListener
            if (mVideoEntity == null) return@setOnClickListener
            val entities = ArrayList<MenuItemEntity>()
            if (!mVideoEntity!!.me.isVideoFavorite) {
                entities.add(MenuItemEntity("收藏", R.drawable.icon_function_collect))
            } else {
                entities.add(MenuItemEntity("取消收藏", R.drawable.icon_function_collected))
            }
            entities.add(MenuItemEntity("投诉", R.drawable.icon_gamedetail_copyright))
            mFragmentRef?.get()?.let {
                MoreFunctionPanelDialog.getMoreDialog(
                    entities,
                    shareEntity.shareTitle,
                    shareEntity,
                    "",
                    it.tag ?: ""
                ).show(it.childFragmentManager, MoreFunctionPanelDialog::class.java.name)
            }
        }

        mBinding.watchedContainer.setOnClickListener {
            mBinding.watchedContainer.visibility = View.GONE
            EventBus.getDefault().post(EBRecommed())
        }

        mBinding.closeIv.setOnClickListener {
            mBinding.watchedContainer.visibility = View.GONE
        }

        mBinding.censoringContainer.setOnClickListener {
            DirectUtils.directToWebView(
                context,
                context.getString(R.string.upload_protocol_url),
                mEntrance
            )
        }

        mBinding.errorBtn.setOnClickListener {
            recordMta("手动点击重试")
            MtaHelper.onEvent("视频详情", "点击重试", mCombinedTitleAndId)

            if (!NetworkUtils.isAvailable(mContext)) {
                Utils.toast(context, "网络错误，视频播放失败")
                setViewShowState(mStartButton, View.INVISIBLE)
                mBinding.errorContainer.visibility = View.VISIBLE
                return@setOnClickListener
            }
            mRetry = true
            seekOnStart = mLastBufferPoint * mDuration / 100L
            startPlayLogic()
        }

        if (mViewModel?.showComment == true) {
            mViewModel?.showComment = false
            mBinding.commentContainer.performClick()
        }
        if (!videoEntity.gameActive) {
            mBinding.gameContainer.visibility = View.GONE
            mBinding.censoringContainer.visibility = View.GONE
        } else {
            when (videoEntity.status) {
                "pass" -> {
                    mBinding.gameContainer.visibility = View.VISIBLE
                    mBinding.censoringContainer.visibility = View.GONE
                }
                "fail" -> {
                    mBinding.gameContainer.visibility = View.GONE
                    mBinding.censoringContainer.visibility = View.GONE
                }
                "pending" -> {
                    mBinding.gameContainer.visibility = View.INVISIBLE
                    mBinding.censoringContainer.visibility = View.VISIBLE
                }
            }
        }
    }

    private fun getShareEntity(): NormalShareEntity? {
        if (mVideoEntity != null) {
            return NormalShareEntity(
                id = mVideoEntity!!.id,
                shareUrl = context.getString(R.string.share_community_video_url, mVideoEntity!!.shortId),
                shareIcon = mVideoEntity!!.poster,
                shareTitle = mVideoEntity!!.title,
                shareSummary = "@${mVideoEntity!!.user.name} 在光环助手发布了游戏小视频，快点开看看吧",
                shareEntrance = ShareUtils.ShareEntrance.video
            )
        }
        return null
    }

    //点赞
    private fun like(isDoubleClick: Boolean = false) {
        if (mVideoEntity!!.me.isVoted && UserManager.getInstance().isLoggedIn) {
            recordMta("取消点赞")
            MtaHelper.onEvent("视频详情", "取消点赞", mCombinedTitleAndId)
            uploadVideoStreamingPlaying("取消点赞")
            mVideoEntity?.run {
                vote--
                me.isVoted = false
                mViewModel?.needToUpdateVideoInfo?.postValue(this)
            }
            mViewModel?.undoVoteVideo(mVideoEntity)
        } else {
            if (CheckLoginUtils.isLogin()) {
                MtaHelper.onEvent("视频详情", if (isDoubleClick) "双击点赞" else "点赞", mCombinedTitleAndId)
                if (isDoubleClick) {
                    recordMta("双击点赞")
                    uploadVideoStreamingPlaying("双击点赞")
                }
                recordMta("点赞")
                uploadVideoStreamingPlaying("点赞")

                when (mVideoEntity?.status ?: "") {
                    "pass" -> {
                        playLikeAnimation()
                        mVideoEntity?.run {
                            vote++
                            me.isVoted = true
                            mViewModel?.needToUpdateVideoInfo?.postValue(this)
                        }
                        mViewModel?.voteVideo(mVideoEntity)

                        if (mViewModel?.entrance?.contains(EntranceConsts.ENTRANCE_WELCOME) == true
                            && mViewModel?.entrance?.countOccurrences("+")!! <= 1
                        ) {
                            LogUtils.uploadLikeFromWelcomeDialog()
                        }

                    }
                    "pending", "fail" -> {
                        Utils.toast(context, "该作品正在审核中，暂时无法点赞哦")
                    }
                }
            } else {
                uploadVideoStreamingPlaying("点赞-跳转登录")
                CheckLoginUtils.checkLogin(context, "视频流详情-点赞") {}
            }
        }
    }

    //添加动画View，播放点赞动画
    private fun playLikeAnimation() {
        removeLikeAnimation()
        mLottieLike = LottieAnimationView(context)
        mLottieLike?.setAnimation("lottie/like.json")
        val location = IntArray(2)
        mBinding.likeIv.getLocationInWindow(location)
        val width = mBinding.likeIv.width
        val height = mBinding.likeIv.height
        val centerX = location[0] + width / 2
        val centerY = location[1] + height / 2
        val params = RelativeLayout.LayoutParams(60f.dip2px(), 60f.dip2px())
        params.leftMargin = centerX - 60f.dip2px() / 2
        params.topMargin = centerY - 60f.dip2px() / 2
        mLottieLike?.layoutParams = params
        mBinding.likeIv.visibility = View.INVISIBLE
        mBinding.likeView.addView(mLottieLike)
        mLottieLike?.playAnimation()
        mLottieLike?.doOnAnimationEnd {
            mBinding.likeView.removeView(mLottieLike)
            mBinding.likeIv.visibility = View.VISIBLE
        }
    }

    fun removeAnimation() {
        removeAttentionAnimation()
        removeWechatAnimation()
        removeLikeAnimation()
    }

    fun removeAttentionAnimation() {
        mBinding.attentionLottie.cancelAnimation()
        mBinding.attentionLottie.visibility = View.GONE
    }

    fun removeLikeAnimation() {
        if (mLottieLike != null) {
            mBinding.likeIv.visibility = View.VISIBLE
            mBinding.likeView.removeView(mLottieLike)
            mLottieLike = null
        }
    }

    fun removeWechatAnimation() {
        weChatAnimate?.end()
        weChatAnimate = null
        mBinding.shareIv.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_video_detail_share))
    }

    private fun playWechatAnimation() {
        if (weChatAnimate == null) {
            val shrinkAnimator = mBinding.shareIv.animate().scaleX(0f).scaleY(0f)
            shrinkAnimator.duration = 250
            shrinkAnimator.doOnEnd {
                mBinding.shareIv.setImageDrawable(
                    ContextCompat.getDrawable(
                        context,
                        R.drawable.ic_video_detail_share_wechat
                    )
                )
                val enlargeAnimator = mBinding.shareIv.animate().scaleX(1f).scaleY(1f)
                enlargeAnimator.duration = 250
                enlargeAnimator.doOnEnd {
                    val scaleXAnimation = ObjectAnimator.ofFloat(mBinding.shareIv, "scaleX", 1f, 0.9f, 1f)
                    scaleXAnimation.repeatCount = -1
                    val scaleYAnimation = ObjectAnimator.ofFloat(mBinding.shareIv, "scaleY", 1f, 0.9f, 1f)
                    scaleYAnimation.repeatCount = -1

                    weChatAnimate = AnimatorSet()
                    weChatAnimate?.play(scaleXAnimation)?.with(scaleYAnimation)
                    weChatAnimate?.duration = 1500
                    weChatAnimate?.start()
                }
                enlargeAnimator.start()
            }
            shrinkAnimator.start()
        }
    }

    override fun createNetWorkState() {
        if (mNetInfoModule == null) {
            mNetInfoModule = NetInfoModule(mContext.applicationContext, NetInfoModule.NetChangeListener { state ->
                if (mNetSate != state) {
                    Debuger.printfError("******* change network state ******* $state")
                    mNetChanged = true
                }
                if (mBinding.errorContainer.visibility == View.VISIBLE && "NONE" != state) {
                    recordMta("自动重试")
                    MtaHelper.onEvent("视频详情", "自动重试", mCombinedTitleAndId)
                    seekOnStart = currentPositionWhenPlaying.toLong()
                    startPlayLogic()
                }
                mNetSate = state
            })
            mNetSate = mNetInfoModule.currentConnectionType
        }
    }

    override fun showWifiDialog() {
        val trafficVideo = PreferenceManager.getDefaultSharedPreferences(context)
            .getBoolean(Constants.SP_TRAFFIC_VIDEO, false)
        val nonWifiTips = SPUtils.getBoolean(Constants.SP_NON_WIFI_TIPS, true)
        if (!trafficVideo) {
            if (nonWifiTips) {
                Utils.toast(context, "当前为非Wi-Fi环境，请注意流量消耗")
            }
            SPUtils.setBoolean(Constants.SP_NON_WIFI_TIPS, false)
            startPlayLogic()
            return
        }
        if (nonWifiTips) {
            DialogHelper.showDialog(context, "注意", "您当前使用的移动网络，确定要继续播放视频吗？", "继续播放", "暂时不了",
                confirmClickCallback = {
                    HaloApp.put(Constants.SHOULD_SHOW_VIDEO_MOBILE_WARNING, false)
                    SPUtils.setBoolean(Constants.SP_NON_WIFI_TIPS, false)
                    startPlayLogic()
                }, cancelClickCallback = {
                    if (mViewModel?.isHomeVideo == false) {
                        (context as Activity).finish()
                    }
                })
        } else {
            startPlayLogic()
        }
    }

    fun updateThumb(url: String) {
        ImageUtils.picasso.load(url).into(findViewById<ImageView>(R.id.thumbImage))
    }

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

    override fun onSurfaceUpdated(surface: Surface) {
        super.onSurfaceUpdated(surface)
        if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
            val animation = mThumbImageViewLayout.animate().alpha(0f).setDuration(100)
            animation.doOnEnd {
                mThumbImageViewLayout.visibility = View.INVISIBLE
                mThumbImageViewLayout.alpha = 1f
            }
            animation.start()
        }
    }

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

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

    override fun startAfterPrepared() {
        super.startAfterPrepared()
        setViewShowState(mStartButton, View.INVISIBLE)
        setViewShowState(mBottomProgressBar, View.VISIBLE)
        setViewShowState(mBottomContainer, View.GONE)
    }

    override fun hideAllWidget() {
        super.hideAllWidget()
        setViewShowState(mBottomProgressBar, View.VISIBLE)
        setViewShowState(mBottomContainer, View.GONE)
    }

    override fun changeUiToNormal() {
        super.changeUiToNormal()
        byStartedClick = false
        setViewShowState(mStartButton, View.INVISIBLE)
        setViewShowState(mBottomProgressBar, View.VISIBLE)
        setViewShowState(mBottomContainer, View.GONE)
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToPreparingShow() {
        super.changeUiToPreparingShow()

        setViewShowState(mLoadingProgressBar, View.GONE)
        setViewShowState(mThumbImageViewLayout, View.VISIBLE)
        setViewShowState(mBottomProgressBar, View.VISIBLE)
        setViewShowState(mBottomContainer, View.GONE)
        mBinding.errorContainer.visibility = View.GONE
        //不提前监听网络，会造成视频一开始加载失败无法重连
        createNetWorkState()
        listenerNetWorkState()

        AppExecutor.uiExecutor.executeWithDelay(Runnable {
            if (mCurrentState == CURRENT_STATE_PREPAREING) {
                setViewShowState(mLoadingProgressBar, View.VISIBLE)
                delay()
            }
        }, 2000)
    }

    private fun delay() {
        AppExecutor.uiExecutor.executeWithDelay(Runnable {
            if (mCurrentState == CURRENT_STATE_PREPAREING) {
                if (!NetworkUtils.isAvailable(mContext)) {
                    changeUiToError()
                }
            }
        }, 10 * 1000)
    }

    override fun changeUiToPlayingShow() {
        super.changeUiToPlayingShow()
        setViewShowState(mStartButton, View.INVISIBLE)
        if (!byStartedClick) {
            setViewShowState(mBottomContainer, View.GONE)
            setViewShowState(mBottomProgressBar, View.VISIBLE)
            hideAllWidget()
        } else {
            setViewShowState(mBottomContainer, View.VISIBLE)
            setViewShowState(mBottomProgressBar, View.GONE)
            if (mScheduledHideDisposable != null && !mScheduledHideDisposable!!.isDisposed) {
                mScheduledHideDisposable!!.dispose()
                mScheduledHideDisposable = null
            }
            mScheduledHideDisposable = rxTimer(1) { times ->
                if (times >= 1500 && currentState == CURRENT_STATE_PLAYING) {
                    mScheduledHideDisposable?.dispose()
                    mScheduledHideDisposable = null
                    hideAllWidget()
                    removeLikeAnimation()
                }
            }
        }
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToPauseShow() {
        super.changeUiToPauseShow()
        setViewShowState(mBottomProgressBar, View.GONE)
        setViewShowState(mBottomContainer, View.VISIBLE)
        mBinding.errorContainer.visibility = View.GONE
        removeLikeAnimation()
        byStartedClick = true
    }

    override fun changeUiToPlayingBufferingShow() {
        super.changeUiToPlayingBufferingShow()
        //setViewShowState(mLoadingProgressBar, View.GONE)
        if (mIsDragSeek) {
            setViewShowState(mBottomProgressBar, View.GONE)
            setViewShowState(mBottomContainer, View.VISIBLE)
        } else {
            setViewShowState(mBottomProgressBar, View.VISIBLE)
            setViewShowState(mBottomContainer, View.GONE)
        }
    }

    override fun changeUiToCompleteShow() {
        super.changeUiToCompleteShow()
        setViewShowState(mBottomProgressBar, View.VISIBLE)
        setViewShowState(mBottomContainer, View.GONE)
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToError() {
        super.changeUiToError()
        setViewShowState(mStartButton, View.INVISIBLE)
        setViewShowState(mBottomContainer, View.GONE)
        mBinding.errorContainer.visibility = View.VISIBLE
    }

    override fun changeUiToPrepareingClear() {
        super.changeUiToPrepareingClear()
        setViewShowState(mBottomContainer, View.GONE)
    }

    override fun changeUiToPlayingBufferingClear() {
        super.changeUiToPlayingBufferingClear()
        setViewShowState(mLoadingProgressBar, View.GONE)
        setViewShowState(mBottomContainer, View.GONE)
    }

    override fun changeUiToClear() {
        super.changeUiToClear()
        setViewShowState(mBottomProgressBar, View.GONE)
        setViewShowState(mBottomContainer, View.GONE)

    }

    override fun changeUiToCompleteClear() {
        super.changeUiToCompleteClear()
        setViewShowState(mBottomContainer, View.GONE)

    }

    public override fun clearFullscreenLayout() {
        super.clearFullscreenLayout()
        updateMuteStatus()
        hideBackBtn()
    }

    override fun onClickUiToggle(e: MotionEvent?) {
        byStartedClick = true
        //在这里触发单击事件，不在onClick中触发防止事件冲突（双击事件会触发单击事件）
        mStartButton.performClick()
    }

    override fun touchDoubleUp(event: MotionEvent?) {
        if (UserManager.getInstance().isLoggedIn) {
            mVideoEntity?.run {
                mBinding.likeView.runLikeAnimation(event)
                if (!me.isVoted && NetworkUtils.isAvailable(mContext)) {
                    like(true)
                }
            }
        } else {
            ToastUtils.showToast("双击点赞，请先登录")
            recordMta("双击点赞-请先登录")
            uploadVideoStreamingPlaying("双击点赞-请先登录")
            MtaHelper.onEvent("视频详情", "双击点赞-请先登录", mCombinedTitleAndId)
        }
    }


    override fun onStartTrackingTouch(seekBar: SeekBar) {
        super.onStartTrackingTouch(seekBar)
        byStartedClick = true
        mIsDragSeek = true
        if (mIfCurrentIsFullscreen) {
            recordMta("全屏播放-拖动进度条")
            MtaHelper.onEvent("视频详情", "全屏播放-拖动进度条", "${mVideoEntity!!.title}（${mVideoEntity!!.id}）")
        }
        uploadVideoStreamingPlaying("开始拖动")
    }

    override fun onStopTrackingTouch(seekBar: SeekBar) {
        super.onStopTrackingTouch(seekBar)
        if (currentPositionWhenPlaying == 0) {
            when (mCurrentState) {
                CURRENT_STATE_PLAYING, CURRENT_STATE_PREPAREING, CURRENT_STATE_PLAYING_BUFFERING_START -> {
                    uploadVideoStreamingPlaying("开始播放-拖回0秒")
                }
                GSYVideoView.CURRENT_STATE_PAUSE -> {
                    uploadVideoStreamingPlaying("暂停-拖回0秒")
                }
            }
        }
        uploadVideoStreamingPlaying("结束拖动", (currentPositionWhenPlaying / 1000).toString())
        //拖动进度条松开手指后，直接从当前具体的秒数开始播放
        if (mCurrentState == GSYVideoView.CURRENT_STATE_PAUSE) {
            onVideoResume(false)
        }
    }

    public override fun resetProgressAndTime() {
        super.resetProgressAndTime()
    }

    override fun getEnlargeImageRes(): Int {
        return R.drawable.ic_video_enter_full_screen
    }

    override fun getShrinkImageRes(): Int {
        return R.drawable.ic_video_exit_full_screen
    }

    override fun netWorkErrorLogic() {
        //super.netWorkErrorLogic()
        gsyVideoManager.pause()
        Utils.toast(context, "网络错误，视频播放失败")
        setViewShowState(mStartButton, View.INVISIBLE)
        setViewShowState(mLoadingProgressBar, View.GONE)
        mBinding.errorContainer.visibility = View.VISIBLE
        if (mPlayRetryCount < 1) {
            seekOnStart = currentPositionWhenPlaying.toLong()
            startPlayLogic()
            mPlayRetryCount++
        }
    }

    //监控播放错误
    override fun onError(what: Int, extra: Int) {
        super.onError(what, extra)
        Utils.toast(context, "网络错误，视频播放失败")
        setViewShowState(mStartButton, View.INVISIBLE)
        mBinding.errorContainer.visibility = View.VISIBLE
        if (mPlayRetryCount < 1) {
            seekOnStart = currentPositionWhenPlaying.toLong()
            startPlayLogic()
            mPlayRetryCount++
        }
    }

    override fun onAutoCompletion() {
        super.onAutoCompletion()
        uploadVideoStreamingPlaying("播放完毕")
        if (repeatPlayCount > 0) {
            uploadVideoStreamingPlaying("重复播放完毕", "${repeatPlayCount}次")
        }
        repeatPlayCount++
        seekOnStart = 0
        startPlayLogic()
        playWechatAnimation()
    }

    override fun onCompletion() {
        // 这个方法在内核被释放时也会被回调，所以可以用来统计播放量和播放时长
        val playedTime = (gsyVideoManager.currentPosition / 1000).toInt()

//        MtaHelper.onEventWithTime("视频播放量_按游戏", playedTime, mGameName, mCombinedTitleAndId)
        MtaHelper.onEventWithTime("视频播放量_按位置", playedTime, mViewModel?.path, mCombinedTitleAndId)
        MtaHelper.onEventWithTime("视频播放量_游戏加位置", playedTime, mGameName, mViewModel?.path)

        super.onCompletion()
    }

    @Deprecated("ijk播放完毕回调，exo无效")
    override fun onSeekComplete() {
        super.onSeekComplete()

        if (mRetry) {
            mRetry = false
            return
        }
        try {
            val clazz = gsyVideoManager::class.java.superclass
            val declaredField = clazz.getDeclaredField("bufferPoint")
            declaredField.isAccessible = true
            val gsyBufferPoint = declaredField.get(gsyVideoManager) as Int
            //播放完成后判断是否已缓冲完毕,没有完成显示播放错误状态
            if (mBufferPoint != 0 && mBufferPoint != 100 && gsyBufferPoint != 0 && gsyBufferPoint != 100) {
                mLastBufferPoint = mBufferPoint
                mDuration = duration
                gsyVideoManager.releaseMediaPlayer()
                changeUiToPreparingShow()
                postDelayed({
                    if (!NetworkUtils.isAvailable(mContext)) {
                        Utils.toast(context, "网络错误，视频播放失败")
                        changeUiToError()
                    }
                }, 10 * 1000)
            } else {
                if (!mIsDragSeek) {
                    uploadVideoStreamingPlaying("播放完毕")
                    if (repeatPlayCount > 0) {
                        uploadVideoStreamingPlaying("重复播放完毕", "${repeatPlayCount}次")
                    }
                    repeatPlayCount++
                    mIsDragSeek = false
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

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

    private fun getKey(): String {
        return "detail_${mViewModel?.uuid}"
    }

    override fun updateStartImage() {
        if (mCurrentState == GSYVideoView.CURRENT_STATE_PLAYING) {
            (startButton as ImageView).setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.ic_video_pause
                )
            )
        } else {
            (startButton as ImageView).setImageDrawable(
                ContextCompat.getDrawable(
                    context,
                    R.drawable.ic_video_detail_play
                )
            )
        }
    }

    override fun onClick(v: View) {
        when (v.id) {
            /*R.id.surface_container,*/ R.id.thumb -> {
            mStartButton.performClick()
        }
            R.id.start -> {
                if (currentState != GSYVideoView.CURRENT_STATE_PLAYING) {
                    recordMta("播放")
                    recordMta(if (mIfCurrentIsFullscreen) "全屏播放-继续播放" else "继续播放")
                    MtaHelper.onEvent("视频详情", "播放", mCombinedTitleAndId)
                    MtaHelper.onEvent(
                        "视频详情",
                        if (mIfCurrentIsFullscreen) "全屏播放-继续播放" else "继续播放",
                        "${mVideoEntity!!.title}（${mVideoEntity!!.id}）"
                    )
                    uploadVideoStreamingPlaying("继续")

                } else {
                    recordMta("暂停")
                    recordMta(if (mIfCurrentIsFullscreen) "全屏播放-点击暂停" else "点击暂停")
                    MtaHelper.onEvent("视频详情", "暂停", mCombinedTitleAndId)
                    MtaHelper.onEvent(
                        "视频详情",
                        if (mIfCurrentIsFullscreen) "全屏播放-点击暂停" else "点击暂停",
                        "${mVideoEntity!!.title}（${mVideoEntity!!.id}）"
                    )
                    uploadVideoStreamingPlaying("暂停")
                }
                super.onClick(v)
            }
            else -> super.onClick(v)
        }
    }

    fun hideAllButton(isHide: Boolean) {
        mBinding.containerRl.goneIf(isHide)
        mBinding.actionLayout.goneIf(isHide)
        if (isHide) {
            mBinding.watchedContainer.visibility = View.GONE
        }
    }

    private fun showBackBtn() {
        mTopContainer.background = ContextCompat.getDrawable(context, com.shuyu.gsyvideoplayer.R.drawable.video_title_bg)
        mBinding.layoutVideoDetailBase.back.visibility = View.VISIBLE
    }

    private fun hideBackBtn() {
        mTopContainer?.setBackgroundResource(0)
        mBinding.layoutVideoDetailBase.back.visibility = View.GONE
    }

    private fun toggleMute() {
        if (mVideoEntity?.videoIsMuted == true) {
            unMute(true)
        } else {
            mute(true)
        }
    }

    fun updateMuteStatus() {
        if (mVideoEntity?.videoIsMuted == true) {
            mute()
        } else {
            unMute()
        }
    }

    private fun mute(isManual: Boolean = false) {
        mVideoEntity?.videoIsMuted = true
        mBinding.volume.setImageResource(R.drawable.ic_video_volume_off)
        (gsyVideoManager as CustomManager).isNeedMute = true

        if (isManual) {
            ToastUtils.showToast("当前处于静音状态")
            recordMta(if (mIfCurrentIsFullscreen) "全屏播放-点击静音" else "点击静音")
            MtaHelper.onEvent(
                "视频详情",
                if (mIfCurrentIsFullscreen) "全屏播放-点击静音" else "点击静音",
                "${mVideoEntity!!.title}（${mVideoEntity!!.id}）"
            )
            uploadVideoStreamingPlaying("静音")
        }
    }

    private fun unMute(isManual: Boolean = false) {
        mVideoEntity?.videoIsMuted = false
        mBinding.volume.setImageResource(R.drawable.ic_video_volume_on)
        (gsyVideoManager as CustomManager).isNeedMute = false
        if (isManual) {
            recordMta(if (mIfCurrentIsFullscreen) "全屏播放-解除静音" else "解除静音")
            MtaHelper.onEvent(
                "视频详情",
                if (mIfCurrentIsFullscreen) "全屏播放-解除静音" else "解除静音",
                "${mVideoEntity!!.title}（${mVideoEntity!!.id}）"
            )
            uploadVideoStreamingPlaying("解除静音")
        }
    }

    fun getVideoAllCallBack(): VideoAllCallBack = mVideoAllCallBack

    fun getCurrentIsFullscreen(): Boolean = mIfCurrentIsFullscreen

    fun uploadVideoStreamingPlaying(action: String, msg: String? = "") {
        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) {
                val newGetContentLengthTime = System.currentTimeMillis()
                if (newGetContentLengthTime - mLastGetContentLengthTime > 5000) {
                    mLastGetContentLengthTime = newGetContentLengthTime
                    mContentLength = ExoCacheManager.getContentLength(mVideoEntity!!.url) / 1024.0 / 1024.0
                }
            }
            //https://exoplayer.dev/hello-world.html#a-note-on-threading
            runOnUiThread {
                LogUtils.uploadVideoStreamingPlaying(
                    action, msg, mViewModel!!.path,
                    mViewModel!!.entranceDetail, mVideoEntity!!.id, mViewModel!!.uuid, mContentLength,
                    videoTotalTime, progress.toInt(), videoPlayStatus()
                )
            }
        }
    }

    private fun videoPlayStatus(): String {
        return when (mCurrentState) {
            CURRENT_STATE_PLAYING, CURRENT_STATE_PREPAREING, CURRENT_STATE_PLAYING_BUFFERING_START -> "play"
            GSYVideoView.CURRENT_STATE_PAUSE -> "pause"
            else -> ""
        }
    }

    fun recordMta(key: String, value: String = "") {
        mViewModel?.let {
            if (it.isHomeVideo) {
                val eventId =
                    if (it.location == VideoDetailContainerViewModel.Location.VIDEO_NEWEST.value) "视频流_最新" else "视频流_推荐"
                MtaHelper.onEvent(eventId, key, if (value.isEmpty()) mCombinedTitleAndId else value)
            }
        }

    }

    fun getGameTitleY(): Int {
        val location = IntArray(2)
        mBinding.gameName.getLocationInWindow(location)
        return location[1]
    }

    override fun onLossAudio() {
        if (!CustomManager.getCustomManager(getKey()).isNeedMute) {
            super.onLossAudio()
        }
    }

    override fun onLossTransientAudio() {
        // transient audio lost 代表的是短暂的 audio focus lost，不暂停播放。不然视频很容易就处于暂停状态
        // onLossAudio 回调的时候再决定是否需要暂停
    }

    fun getCurrentPosition(): Long {
        return mCurrentPosition
    }

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

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        mPlayRetryCount = 0
        unObserveVolume(context as AppCompatActivity)
        mScheduledHideDisposable?.dispose()
        mScheduledHideDisposable = null
    }
}

