package com.gh.gamecenter.forum.home

import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.Surface
import android.view.View
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.video.detail.CustomManager
import com.lightgame.utils.Utils
import com.shuyu.gsyvideoplayer.utils.CommonUtil
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 ArticleItemVideoView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
    StandardGSYVideoPlayer(context, attrs) {

    var data: ArticleVideoData? = null

    private var mMuteDisposable: Disposable? = null
    private var mIsAutoPlay = false
    var uuid = UUID.randomUUID().toString()

    var thumbImage: SimpleDraweeView = findViewById(R.id.thumbImage)
    var durationTv: TextView = findViewById(R.id.durationTv)
    var completeContainer: View = findViewById(R.id.completeContainer)
    var replayTv: TextView = findViewById(R.id.replayTv)
    var shareTv: TextView = findViewById(R.id.shareTv)
    var volume: ImageView = findViewById(R.id.volume)
    var remainingTv: TextView = findViewById(R.id.remainingTv)
    var back: ImageView = findViewById(R.id.back)
    var pendingView: TextView = findViewById(R.id.pendingView)
    var titleTv: TextView = findViewById(R.id.title)

    private var mMaxPlayedProgress: Int = 0
    private var mStartTrackRunnable: Runnable? = null
    private var mStopTrackRunnable: Runnable? = null

    private val mTrackHandler = Handler(Looper.getMainLooper())

    private var onEventListener: OnArticleItemVideoViewEventListener? = null

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

    init {
        post {
            volume.setOnClickListener { toggleMute() }
        }

        if (mIfCurrentIsFullscreen) {
            showBackBtn()
        } else {
            hideBackBtn()
        }

        setBackFromFullScreenListener {
            clearFullscreenLayout()
        }
    }

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

    fun startPlayLogic(isAutoPlay: Boolean) {
        mIsAutoPlay = isAutoPlay
        if (mIsAutoPlay) {
            val seekTime = ForumScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(data?.url))
            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()
        }
    }

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

    override fun updateStartImage() {
        if (mStartButton is ImageView) {
            val imageView = mStartButton as ImageView
            when (mCurrentState) {
                GSYVideoView.CURRENT_STATE_PLAYING -> imageView.setImageResource(com.gh.gamecenter.feature.R.drawable.icon_preview_video_pause)
                GSYVideoView.CURRENT_STATE_ERROR -> imageView.setImageResource(com.gh.gamecenter.feature.R.drawable.icon_preview_video_play)
                else -> imageView.setImageResource(com.gh.gamecenter.feature.R.drawable.icon_preview_video_play)
            }
        }
    }

    override fun onClickUiToggle(e: MotionEvent?) {
        if (data?.status != "pending" && data?.status != "fail") {
            if (mCurrentState == CURRENT_STATE_PLAYING) {
                if (mStartButton.visibility == View.VISIBLE) {
                    changeUiToPlayingClear()
                } else {
                    changeUiToPlayingShow()
                }
            } else {
                super.onClickUiToggle(e)
            }
        }
    }

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

    override fun onSurfaceUpdated(surface: Surface) {
        super.onSurfaceUpdated(surface)
        if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
            mThumbImageViewLayout.visibility = View.INVISIBLE
        }
    }

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

        // 部分设备由于MediaCodec实例达到上限导致 CodecException: Error 0xfffffff4，在此处尝试释放所有视频
        CustomManager.clearAllVideo()
    }

    override fun releaseVideos() {
        CustomManager.releaseAllVideos(getKey())
    }


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

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

    override fun setProgressAndTime(
        progress: Int,
        secProgress: Int,
        currentTime: Int,
        totalTime: Int,
        forceChange: Boolean
    ) {
        super.setProgressAndTime(progress, secProgress, currentTime, totalTime, forceChange)
        if (remainingTv.visibility == View.VISIBLE) {
            remainingTv.text = CommonUtil.stringForTime(totalTime - currentTime)
        }
    }

    private fun showBackBtn() {
        mTopContainer.background = ContextCompat.getDrawable(context, com.shuyu.gsyvideoplayer.R.drawable.video_title_bg)
        back.visibility = View.VISIBLE
        data?.title?.let(titleTv::setText)
    }

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

    fun updateVideoData(video: ArticleVideoData, listener: OnArticleItemVideoViewEventListener) {
        this.onEventListener = listener
        this.mStopTrackRunnable = null

        data = video
        titleTv.text = if (mIfCurrentIsFullscreen) video.title else ""

        ImageUtils.display(thumbImage, video.poster)

        if (!mIfCurrentIsFullscreen) {
            durationTv.text = video.duration
            setVideoStatus(video.status)
            fullscreenButton.setOnClickListener {
                val horizontalVideoView =
                    startWindowFullscreen(context, true, true) as? ArticleItemVideoView
                if (horizontalVideoView == null) {
                    toastInInternalRelease("全屏失败，请向技术人员提供具体的操作步骤")
                    return@setOnClickListener
                }
                onEventListener?.onStartWindowFullscreen()
                horizontalVideoView.uuid = uuid
                horizontalVideoView.updateVideoData(video, listener)
                horizontalVideoView.violenceUpdateMuteStatus()
                horizontalVideoView.setFullViewStatus()
            }
        }
    }

    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?) {
        // we do not need double click to play or pause
    }

    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        super.onProgressChanged(seekBar, progress, fromUser)
        // 记录播放进度的最大值，用于埋点上报
        if (mMaxPlayedProgress < progress) {
            mMaxPlayedProgress = progress
        }
    }

    override fun setStateAndUi(state: Int) {
        if (state != currentState
            && state == CURRENT_STATE_PLAYING
            && currentState != CURRENT_STATE_PLAYING_BUFFERING_START
        ) {// 上报开始视频播放埋点
            // 视频停止播放后再恢复播放的间隔时间未超过3秒，则取消上报结束视频播放埋点
            mStopTrackRunnable?.let { runnable ->
                mTrackHandler.removeCallbacks(runnable)
            }

            data?.let {
                val startTrackRunnable = Runnable {
                    onEventListener?.onTrackVideoStartPlaying()
                    mStartTrackRunnable = null
                }.also {
                    mStartTrackRunnable = it
                }
                // 埋点要求视频播放3秒后再上报埋点
                mTrackHandler.postDelayed(startTrackRunnable, 3000)
            }
        } else if (currentState != state
            && (state == CURRENT_STATE_AUTO_COMPLETE
                    || state == CURRENT_STATE_ERROR
                    || state == CURRENT_STATE_PAUSE
                    || (currentState == CURRENT_STATE_PLAYING && state == CURRENT_STATE_NORMAL))
        ) {// 上报结束视频播放埋点
            // 从开始播放视频到停止播放视频的间隔时间没有超过3秒，则取消上报开始视频播放埋点
            this.mStartTrackRunnable?.let {
                mTrackHandler.removeCallbacks(it)
                mStartTrackRunnable = null
            } ?: let {
                data?.let {
                    val stopTrackRunnable = Runnable {
                        onEventListener?.onTrackVideoEndPlaying(mMaxPlayedProgress)
                    }.also {
                        this.mStopTrackRunnable = it
                    }
                    // 埋点要求停止视频播放3秒后再上报埋点
                    mTrackHandler.postDelayed(stopTrackRunnable, 3000)
                }
            }
        }

        super.setStateAndUi(state)
        if (currentState == GSYVideoView.CURRENT_STATE_PREPAREING) {
            setViewShowState(durationTv, View.GONE)
        }

//        if (currentState == GSYVideoView.CURRENT_STATE_PLAYING) {
//            setViewShowState(mBottomProgressBar, View.VISIBLE)
//        }

        if (currentState == GSYVideoView.CURRENT_STATE_AUTO_COMPLETE) {
            hideAllWidget()
            setViewShowState(completeContainer, View.VISIBLE)
            mTopContainer.visibility = View.VISIBLE
            replayTv.setOnClickListener {
                startButton.performClick()
                violenceUpdateMuteStatus()
            }
            shareTv.setOnClickListener {
                onEventListener?.onShare(this)
            }
        } else {
            setViewShowState(completeContainer, View.GONE)
        }
    }

    override fun changeUiToPlayingShow() {
        super.changeUiToPlayingShow()
        if (!mIfCurrentIsFullscreen) setViewShowState(mBottomProgressBar, View.VISIBLE)
    }

    override fun changeUiToPlayingClear() {
        super.changeUiToPlayingClear()
        if (mIfCurrentIsFullscreen) setViewShowState(mBottomProgressBar, View.GONE)
    }

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

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

    private fun mute() {
        onEventListener?.onMutedChanged(true)
        data?.videoIsMuted = true
        volume.setImageResource(R.drawable.ic_article_video_volume_off)
        CustomManager.getCustomManager(getKey()).isNeedMute = true
    }

    private fun unMute() {
        onEventListener?.onMutedChanged(false)
        data?.videoIsMuted = false
        volume.setImageResource(R.drawable.ic_article_video_volume_on)
        CustomManager.getCustomManager(getKey()).isNeedMute = false
    }

    fun setFullViewStatus() {
        mProgressBar.visibility = View.VISIBLE
        mCurrentTimeTextView.visibility = View.VISIBLE
        mTotalTimeTextView.visibility = View.VISIBLE
        mBottomProgressBar.visibility = View.GONE
        remainingTv.visibility = View.GONE
        durationTv.visibility = View.GONE
    }

    private fun setVideoStatus(status: String) {
        if (status == "pending" || status == "fail") {
            pendingView.text = if (status == "pending") "审核中...请耐心等待" else "审核不通过"
            pendingView.visibility = View.VISIBLE
            mBottomContainer?.visibility = View.GONE
            mStartButton?.visibility = View.GONE
            mBottomProgressBar?.visibility = View.GONE
        } else {
            pendingView.visibility = View.GONE
//            mBottomContainer.visibility = View.VISIBLE
            mStartButton?.visibility = View.VISIBLE
            mBottomProgressBar?.visibility = View.VISIBLE
        }
    }

    fun getKey(): String {
        return uuid
    }

    fun getCurrentPosition(): Long {
        return mCurrentPosition
    }

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

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

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        mMuteDisposable?.dispose()
    }

    companion object {

        fun ForumVideoEntity.toArticleVideoData() =
            ArticleVideoData(url, title, status, poster, duration, videoIsMuted)
    }

    data class ArticleVideoData(
        val url: String,
        val title: String,
        val status: String,
        val poster: String,
        val duration: String,
        var videoIsMuted: Boolean
    )

    interface OnArticleItemVideoViewEventListener {

        fun onTrackVideoStartPlaying()

        fun onTrackVideoEndPlaying(maxPlayedProgress: Int)

        fun onShare(videoView: ArticleItemVideoView)

        fun onMutedChanged(isMuted: Boolean)

        fun onStartWindowFullscreen()
    }
}