package com.gh.gamecenter.qa.editor

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Context
import android.graphics.Typeface
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.AttributeSet
import android.view.*
import android.widget.*
import androidx.core.content.ContextCompat
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.observer.MuteCallback
import com.gh.gamecenter.common.observer.VolumeObserver
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.LayoutFullScreenDetailVideoPortraitBinding
import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.video.detail.CustomManager
import com.lightgame.utils.Utils
import com.shuyu.gsyvideoplayer.utils.CommonUtil
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 java.util.*

class FullScreenVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    StandardGSYVideoPlayer(context, attrs) {
    private var mMuteCallback: MuteCallback
    private var mVolumeObserver: VolumeObserver
    private var mMuteDisposable: Disposable? = null
    var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
    private var mSpeedPopupWindow: PopupWindow? = null
    private lateinit var mBinding: LayoutFullScreenDetailVideoPortraitBinding
    val backBtn: View = findViewById(R.id.back)
    var uuid = UUID.randomUUID().toString()
    var logCallback: ((String) -> Unit)? = null

    init {
        post {
            gestureDetector =
                GestureDetector(getContext().applicationContext, object : GestureDetector.SimpleOnGestureListener() {
                    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
                        if (!mChangePosition && !mChangeVolume && !mBrightness) {
                            onClickUiToggle(e)
                        }
                        return super.onSingleTapConfirmed(e)
                    }
                })

            showBackBtn()

            mBinding.layoutBottom.volume.setOnClickListener { toggleMute() }
            mBinding.layoutBottom.speedTv.visibility = View.VISIBLE
            mBinding.layoutBottom.speedTv.setOnClickListener {
                cancelDismissControlViewTimer()
                mSpeedPopupWindow = showPlaySpeedPopupWindow(mContext, speed, mBinding.layoutBottom.root)
                mSpeedPopupWindow?.setOnDismissListener {
                    startDismissControlViewTimer()
                }
            }
        }
        mFullscreenButton.visibility = View.GONE

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

        mVolumeObserver = VolumeObserver(mMuteCallback)

        setBackFromFullScreenListener {
            clearFullscreenLayout()
        }

        mBinding.errorBtn.setOnClickListener {
            debounceActionWithInterval(mBinding.errorBtn.id, 1000) {
                if (!NetworkUtils.isAvailable(mContext)) {
                    Utils.toast(context, "网络异常，请检查手机网络状态")
                    setViewShowState(mStartButton, INVISIBLE)
                    mBinding.errorContainer.visibility = VISIBLE
                    return@debounceActionWithInterval
                }
                startPlayLogic(false)
            }
        }

        // 处理全面屏手势与进度条冲突导致无法拖动进度条，使用全面屏手势时进度条上移
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && ScreenUtils.isNavBarHide(context) > 0) {
            mBinding.layoutBottom.navigationView.visibility = View.VISIBLE
        }
    }

    //这个必须配置最上面的构造才能生效
    override fun getLayoutId(): Int {
        return R.layout.layout_full_screen_detail_video_portrait
    }

    override fun init(context: Context?) {
        super.init(context)
        mBinding = LayoutFullScreenDetailVideoPortraitBinding.bind(this.getChildAt(0))
    }

    fun observeVolume(activity: Activity?) {
        tryWithDefaultCatch {
            activity?.applicationContext?.contentResolver?.registerContentObserver(
                Settings.System.CONTENT_URI, true, mVolumeObserver
            )

            activity?.application?.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
                override fun onActivityPaused(activity: Activity) {
                    activity.applicationContext?.contentResolver?.unregisterContentObserver(mVolumeObserver)
                    activity.application?.unregisterActivityLifecycleCallbacks(this)
                }

                override fun onActivityStarted(activity: Activity) {}
                override fun onActivityDestroyed(activity: Activity) {}
                override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
                override fun onActivityStopped(activity: Activity) {}
                override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
                override fun onActivityResumed(activity: Activity) {}
            })
        }
    }

    fun startPlayLogic(seekToSavedPosition: Boolean) {
        if (seekToSavedPosition) {
            val seekTime = ForumScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(mOriginUrl))
            seekOnStart = seekTime
        }
        startPlayLogic()
    }

    override fun prepareVideo() {
        super.prepareVideo()
        violenceUpdateMuteStatus()
    }

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

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

    private fun toggleMute() {
        if (videoIsMuted) {
            unMute(true)
        } else {
            mute(true)
        }
    }

    fun updateMuteStatus() {
        if (videoIsMuted) {
            mute()
        } else {
            unMute()
        }
    }

    private fun mute(isManual: Boolean = false) {
        videoIsMuted = true
        mBinding.layoutBottom.volume.setImageResource(R.drawable.ic_video_volume_off)
        CustomManager.getCustomManager(getKey()).isNeedMute = true
        if (isManual) {
            Utils.toast(context, "当前处于静音状态")
            uploadVideoStreamingPlaying("点击静音")
        }
    }

    private fun unMute(isManual: Boolean = false) {
        videoIsMuted = false
        mBinding.layoutBottom.volume.setImageResource(R.drawable.ic_video_volume_on)
        CustomManager.getCustomManager(getKey()).isNeedMute = false
        if (isManual) {
            uploadVideoStreamingPlaying("取消静音")
        }
    }

    // 重载以减少横竖屏切换的时间
    override fun checkoutState() {
        removeCallbacks(mCheckoutTask)
        postDelayed(mCheckoutTask, 300)
    }

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

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

    override fun touchDoubleUp(e: MotionEvent?) {
        // we do not need double click to play or pause
    }

    // 不需要弹弹窗，直接播放
    override fun showWifiDialog() {
        startPlayLogic(false)
        //val trafficVideo = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SettingsFragment.TRAFFIC_VIDEO_SP_KEY, false)
        //if (trafficVideo) {
        // 不延迟的话 isCacheFile 可能直接返回 false
        postDelayed({
            // 这个库的 NetworkUtils.isWifiConnected 可能会触发空指针，这里换为我们自己的
            if (!com.shuyu.gsyvideoplayer.utils.NetworkUtils.isAvailable(mContext) && !gsyVideoManager.isCacheFile) {
                Utils.toast(context, "网络异常，请检查手机网络状态")
            } else if (!com.gh.gamecenter.common.utils.NetworkUtils.isWifiConnected(mContext) && !gsyVideoManager.isCacheFile) {
                Utils.toast(context, "当前为非Wi-Fi环境，请注意流量消耗")
            }
        }, 100)
        // }
    }

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

    override fun hideAllWidget() {
        super.hideAllWidget()

        mSpeedPopupWindow?.dismiss()
    }

    fun getKey(): String {
        return uuid
    }

    override fun onAutoCompletion() {

        //播放完成后判断是否已缓冲完毕,没有完成显示播放错误状态
        if (mBufferPoint != 0 && mBufferPoint != 100 && isShown) {
            gsyVideoManager.releaseMediaPlayer()
            changeUiToPreparingShow()
            postDelayed({
                if (!com.shuyu.gsyvideoplayer.utils.NetworkUtils.isAvailable(mContext)) {
                    Utils.toast(context, "网络错误，视频播放失败")
                    changeUiToError()
                }
            }, 10 * 1000)
        }
        uploadVideoStreamingPlaying("播放完毕")
        super.onAutoCompletion()
    }

    override fun onStopTrackingTouch(seekBar: SeekBar?) {
        super.onStopTrackingTouch(seekBar)
        uploadVideoStreamingPlaying("拖动")
    }

    override fun isShowNetConfirm(): Boolean {
        return (!mOriginUrl.startsWith("file") && !mOriginUrl.startsWith("android.resource") && !CommonUtil.isWifiConnected(
            context
        )
                && mNeedShowWifiTip)
    }

    override fun updateStartImage() {
        if (mStartButton is ImageView) {
            val imageView = mStartButton as ImageView
            when (mCurrentState) {
                GSYVideoView.CURRENT_STATE_PLAYING -> imageView.setImageResource(R.drawable.ic_video_pause)
                GSYVideoView.CURRENT_STATE_ERROR -> imageView.setImageResource(R.drawable.ic_video_play)
                else -> imageView.setImageResource(R.drawable.ic_video_play)
            }
        }
    }

    override fun setStateAndUi(state: Int) {
        super.setStateAndUi(state)

        if (state == CURRENT_STATE_AUTO_COMPLETE) {
            hideAllWidget()
            mBinding.replayContainer.root.visibility = View.VISIBLE
            mTopContainer.visibility = View.VISIBLE
            mBinding.replayContainer.replayIv.setOnClickListener {
                startButton.performClick()
                violenceUpdateMuteStatus()
                uploadVideoStreamingPlaying("重新播放")
            }
        } else {
            mBinding.replayContainer.root.visibility = View.GONE
        }
    }

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

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

    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 onInterceptTouchEvent(ev: MotionEvent): Boolean {
        if (!isIfCurrentIsFullscreen) {
            parent.requestDisallowInterceptTouchEvent(true)
        }
        return super.onInterceptTouchEvent(ev)
    }

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

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

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

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

    override fun changeUiToNormal() {
        super.changeUiToNormal()
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToPreparingShow() {
        super.changeUiToPreparingShow()
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToPlayingShow() {
        super.changeUiToPlayingShow()
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToPauseShow() {
        super.changeUiToPauseShow()
        mBinding.errorContainer.visibility = View.GONE
    }

    override fun changeUiToCompleteShow() {
        super.changeUiToCompleteShow()
        mBinding.errorContainer.visibility = View.GONE
    }

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

    override fun netWorkErrorLogic() {
        super.netWorkErrorLogic()
        Utils.toast(context, "网络错误，视频播放失败")
        setViewShowState(mStartButton, View.INVISIBLE)
        mBinding.errorContainer.visibility = View.VISIBLE
    }

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

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

    override fun onVideoPause() {
        super.onVideoPause()
        uploadVideoStreamingPlaying("暂停播放")
    }

    fun getCurrentPosition(): Long {
        return mCurrentPosition
    }

    fun uploadVideoStreamingPlaying(action: String) {
        logCallback?.invoke(action)
        /*if (video == null || video?.url.isNullOrEmpty()) return
        runOnIoThread {
            val isLandscape = mOrientationUtils != null
            val videoPlayModel = if (!isLandscape) {
                if (mIsAutoPlay) "自动播放" else "点击播放"
            } else "全屏播放"
            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(video!!.url) / 1024.0 / 1024.0
            }

            //https://exoplayer.dev/hello-world.html#a-note-on-threading
            runOnUiThread {
                LogUtils.uploadTopVideoStreamingPlaying(action, video?.videoId, video?.title, viewModel?.game?.id, viewModel?.game?.name,
                        videoPlayModel, videoPlayStatus(), mContentLength, videoTotalTime, videoPlayTs, progress.toInt())
            }
        }*/
    }

    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 -> ""
        }
    }

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

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

    @SuppressLint("SetTextI18n")
    private fun showPlaySpeedPopupWindow(context: Context,
                                         currentSpeed: Float,
                                         anchorView: View): PopupWindow {
        val availableVideoSpeed = arrayListOf(2.0F, 1.5F, 1.0F, 0.75F, 0.5F)

        val inflater = LayoutInflater.from(context)
        val layout = inflater.inflate(R.layout.popup_video_play_speed, null)
        val popupWindow = BugFixedPopupWindow(
            layout,
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        )

        val container = layout.findViewById<LinearLayout>(R.id.container)
        for (videoSpeed in availableVideoSpeed) {
            val item = inflater.inflate(R.layout.item_video_play_speed, container, false)
            container.addView(item)

            val tv = item.findViewById<TextView>(R.id.titleTv)
            tv.text = "${videoSpeed}X"
            if (videoSpeed == currentSpeed) {
                tv.setTextColor(com.gh.gamecenter.common.R.color.text_aw_primary.toColor(context))
                tv.setTypeface(Typeface.DEFAULT, Typeface.BOLD)
            } else {
                tv.setTextColor(com.gh.gamecenter.common.R.color.text_aw_secondary.toColor(context))
                tv.setTypeface(Typeface.DEFAULT, Typeface.NORMAL)
            }

            item.setOnClickListener {
                speed = videoSpeed
                if (videoSpeed != 1.0F) {
                    mBinding.layoutBottom.speedTv.text = tv.text
                    mBinding.layoutBottom.speedTv.setTypeface(Typeface.DEFAULT, Typeface.BOLD)
                } else {
                    mBinding.layoutBottom.speedTv.text = resources.getString(R.string.video_speed)
                    mBinding.layoutBottom.speedTv.setTypeface(Typeface.DEFAULT, Typeface.NORMAL)
                }
                popupWindow.dismiss()
            }
        }

        popupWindow.run {
            isTouchable = true
            isFocusable = true
            showAutoOrientation(anchorView = anchorView)
        }

        return popupWindow
    }

}