package com.gamedog.vididin.main.fragments.home.fragment


import android.graphics.Bitmap
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.view.animation.AnimationSet
import android.view.animation.ScaleAnimation
import android.widget.FrameLayout
import androidx.annotation.NonNull
import androidx.core.view.isVisible
import com.ama.core.architecture.appBase.AppViewsEmptyViewModelFragment
import com.ama.core.architecture.util.AndroidUtil
import com.ama.core.architecture.util.setOnClickBatch
import com.gamedog.statisticreporter.StatisticUtil
import com.viddin.videos.free.R
import com.gamedog.vididin.beans.YoutubeVideo
import com.gamedog.vididin.widget.MyPlayerControlView
import com.gamedog.vididin.youtubestatistic.TickerTimer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.loadOrCueVideo
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
import com.viddin.videos.free.databinding.VididinappFeatureHomeItemLayoutBinding as ViewBinding


class HomeItemFragment : AppViewsEmptyViewModelFragment<ViewBinding>() {
    private var mMaskBitmap: Bitmap? = null
    private var mPlayerView: YouTubePlayerView? = null
    private var mPlayer: YouTubePlayer? = null
    private var mVideoData: YoutubeVideo? = null
    private var mIsPlaying: Boolean = false
    private var mIsIntroExpand: Boolean = false
    private var mCurPlayedSecond: Float = 0F
    private var mTotalDuration: Float = 0F
    private val mTickerTimer = TickerTimer()


    override fun inflateViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?,
    ) = ViewBinding.inflate(inflater, container, false)


    override fun ViewBinding.initViews() {
        playIcon.setOnClickListener {
            if (mIsPlaying) mPlayer?.pause() else mPlayer?.play()
        }

        tvVideoFrom.text = mVideoData?.channel_title
        tvVideoIntro.text = mVideoData?.description
        ivIntroExpand.isVisible = tvVideoIntro.lineCount > 2


        setOnClickBatch(ivIntroExpand, clickMaskView) {
            when (this) {
                clickMaskView ->  {
                    if (mIsPlaying) mPlayer?.pause() else mPlayer?.play()
                }

                ivIntroExpand ->  {
                    mIsIntroExpand = !mIsIntroExpand
                    tvVideoIntro.maxLines = if (mIsIntroExpand) 8 else 2
                    ivIntroExpand.setImageResource(if (mIsIntroExpand) R.mipmap.arrow_down else R.mipmap.arrow_up)
                }
            }
        }

    }


    override fun ViewBinding.initListeners() {


    }

    override fun ViewBinding.initObservers() {

    }

    override fun onDestroy() {
        super.onDestroy()
        mMaskBitmap?.recycle()
    }







    private fun playVideo() {
        if (mPlayer != null && mVideoData != null && !mVideoData?.id.isNullOrEmpty()) {
            mPlayer?.loadOrCueVideo(
                lifecycle,
                mVideoData!!.id,
                0f
            )

            /*mPlayerView?.isVisible?.let {
                if (!it) {
                    mPlayer?.pause()
                }
            }*/
        }
    }

    fun getVideoId(): String? {
        return  mVideoData?.id
    }

    fun loadVideo() {
        if (null == mPlayerView) {
            mPlayerView = YouTubePlayerView(requireContext())
            val layoutParam = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
            layoutParam.gravity = Gravity.BOTTOM
            binding!!.playerContainer.addView(mPlayerView, layoutParam)
            lifecycle.addObserver(mPlayerView!!)
            mPlayerView?.enableAutomaticInitialization = true
        }


        val playerView = mPlayerView
        playerView!!.addYouTubePlayerListener(object : AbstractYouTubePlayerListener() {
            override fun onReady(@NonNull youTubePlayer: YouTubePlayer) {
                mPlayer = youTubePlayer

                val playerUiController = MyPlayerControlView(playerView, youTubePlayer)
                playerView.setCustomPlayerUi(playerUiController.rootView)

                playVideo()
            }

            override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) {
                super.onCurrentSecond(youTubePlayer, second)
                mCurPlayedSecond = second
                updateProgressbar()
            }

            override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) {
                super.onVideoDuration(youTubePlayer, duration)
                mTotalDuration = duration
                mTickerTimer.setVideoInfo(mVideoData!!.id, (1000L * mTotalDuration).toLong())
            }

            override fun onStateChange(
                youTubePlayer: YouTubePlayer,
                state: PlayerConstants.PlayerState
            ) {
                when (state) {
                    PlayerConstants.PlayerState.PLAYING  -> {
                        togglePlayingState(true)
                    }
                    PlayerConstants.PlayerState.PAUSED  -> {
                        togglePlayingState(false)
                    }
                    PlayerConstants.PlayerState.UNKNOWN  -> {
                        togglePlayingState(false)
                    }
                    PlayerConstants.PlayerState.UNSTARTED  -> {
                        togglePlayingState(false)
                    }
                    PlayerConstants.PlayerState.ENDED  -> {
                        togglePlayingState(false)
                        playVideo()
                    }
                    PlayerConstants.PlayerState.BUFFERING  -> {
                        binding?.circlePb?.isVisible = true
                        //showLoading(true)
                    }
                    PlayerConstants.PlayerState.VIDEO_CUED  -> {
                        togglePlayingState(false)
                    }
                }
            }
        })
    }

    private fun sendPlayStopStatistic(isPlayStart: Boolean) {
        mVideoData?.let {
            StatisticUtil.reportEvents(if (isPlayStart) StatisticUtil.KEY_Video_Play_Start else StatisticUtil.KEY_Video_Play_End,
                mapOf(
                    "video_id" to it.id,
                    "watch_duration" to mCurPlayedSecond.toInt(),  //Second
                    "is_completed" to (mCurPlayedSecond>= mTotalDuration || Math.abs(mTotalDuration - mCurPlayedSecond) < 2),
                ))
        }
    }


    private fun generateThumbAndSet() {
        // capturePlayerView And Show as thumb
        mPlayerView?.let {
            mMaskBitmap?.recycle()
            mMaskBitmap = null
            mMaskBitmap = AndroidUtil.getThumbOfView(it)
            mMaskBitmap?.let {
                binding?.ivMask?.setImageBitmap(mMaskBitmap)
            }
        }
    }

    private fun togglePlayingState(isPlaying: Boolean) {
        if (mIsPlaying != isPlaying) {
            mIsPlaying = isPlaying
            if (!mIsPlaying) {
                /*binding?.circlePb?.let {
                    it.postDelayed({
                        generateThumbAndSet()
                    }, 500)
                }*/
            } else {
                binding?.circlePb?.isVisible = false
            }

            binding?.ivMask?.isVisible = !mIsPlaying
            binding?.playerContainer?.isVisible = mIsPlaying

            if (mIsPlaying) {
                hidePlayIconAnim()
            } else {
                showPlayIconAnim()
            }

            if (mIsPlaying) mTickerTimer.start() else mTickerTimer.pause()

            sendPlayStopStatistic(mIsPlaying)
        }
    }

    override fun onResume() {
        super.onResume()
        mPlayer?.play()
    }


    override fun onStop() {
        super.onStop()
    }

    override fun onPause() {
        super.onPause()
        mPlayer?.pause()
    }

    private fun updateProgressbar() {
        with(binding?.progressBarPlayer!!) {
            setMax(100)
            if (mTotalDuration > 0) {
                setProgress((100*mCurPlayedSecond/mTotalDuration).toInt())
            }
        }
    }


    private fun hidePlayIconAnim() {
        if (!binding?.playIcon!!.isVisible) {
            return
        }


        with (binding?.playIcon!!) {
            val animationSet = AnimationSet(true)
            animationSet.duration = 250
            val alphaAnimation = AlphaAnimation(0.6f, 0.3f)
            val scaleAnimation = ScaleAnimation(
                1.0f, 0.5f,
                1.0f, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
            )
            animationSet.addAnimation(alphaAnimation)
            animationSet.addAnimation(scaleAnimation)

            animationSet.setAnimationListener(object : Animation.AnimationListener {
                override fun onAnimationStart(animation: Animation) {
                }

                override fun onAnimationEnd(animation: Animation) {
                    visibility = View.GONE
                }

                override fun onAnimationRepeat(animation: Animation) {
                }
            })

            startAnimation(animationSet)
        }
    }

    private fun showPlayIconAnim() {
        with (binding?.playIcon!!) {
            visibility = View.VISIBLE

            val animationSet = AnimationSet(true)
            animationSet.duration = 250
            val alphaAnimation = AlphaAnimation(0.3f, 0.6f)
            val scaleAnimation = ScaleAnimation(
                0.5f, 1.0f,
                0.5f, 1.0f,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
            )
            animationSet.addAnimation(alphaAnimation)
            animationSet.addAnimation(scaleAnimation)

            animationSet.setAnimationListener(object : Animation.AnimationListener {
                override fun onAnimationStart(animation: Animation) {
                }

                override fun onAnimationEnd(animation: Animation) {

                }

                override fun onAnimationRepeat(animation: Animation) {
                }
            })

            startAnimation(animationSet)
        }
    }




    companion object {
        private const val KEY_ID = "id"
        internal fun newInstance(id: Long, videoData: YoutubeVideo) = HomeItemFragment().apply {
            mVideoData = videoData
            arguments = Bundle().apply {
                putLong(KEY_ID, id)
            }
        }
    }
}