package com.gh.vspace

import android.animation.*
import android.app.Activity
import android.content.Context
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.get
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.core.utils.ClickUtils
import com.gh.gamecenter.core.utils.doOnEnd
import com.gh.gamecenter.databinding.ItemFloatGameLoadCompleteBinding
import com.gh.gamecenter.databinding.LayoutFloatLoadCompleteBinding
import com.gh.gamecenter.entity.GameEntity
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lzf.easyfloat.EasyFloat
import com.lzf.easyfloat.enums.SidePattern
import com.lzf.easyfloat.interfaces.OnFloatAnimator
import java.lang.ref.WeakReference

object VLoadCompleteWindowHelper {
    private const val LOAD_COMPLETE_WINDOW = "load_complete_window"
    private const val LOOP_TIME = 2000L
    private const val LOOP_DURATION = 200L
    private const val AUTO_DISMISS_TIME = 3000L

    private val mDismissTask = Runnable { EasyFloat.dismiss(LOAD_COMPLETE_WINDOW) }

    fun showFloatingWindow(activity: Activity, gameEntity: GameEntity) {
        showFloatingWindow(activity, listOf(gameEntity))
    }

    fun showFloatingWindow(activity: Activity, gameEntityList: List<GameEntity> = emptyList()) {
        val floatingView = EasyFloat.getFloatView(LOAD_COMPLETE_WINDOW)
        if (floatingView != null) {
            if (!EasyFloat.isShow(LOAD_COMPLETE_WINDOW)) EasyFloat.show(LOAD_COMPLETE_WINDOW)
            floatingView.findViewById<ConstraintLayout>(R.id.container)?.let {
                val binding = LayoutFloatLoadCompleteBinding.bind(it)
                binding.viewPager.run {
                    val adapter = adapter
                    var isLastItem = false
                    if (adapter is GameLoadCompleteAdapter) {
                        if (currentItem == adapter.gameEntityList.size - 1) isLastItem = true
                        adapter.submitList(gameEntityList)
                    }
                    removeCallbacks(mDismissTask)
                    if (isLastItem) {
                        val mLoopTask = object : Runnable {
                            private val reference: WeakReference<ViewPager2> = WeakReference(binding.viewPager)

                            override fun run() {
                                val vp: ViewPager2? = reference.get()
                                if (vp != null) {
                                    val count = binding.viewPager.adapter?.itemCount ?: 0
                                    if (count == 0) return
                                    val next = vp.currentItem + 1
                                    if (next < count) {
                                        vp.setCurrentItem(next, LOOP_DURATION)
                                        vp.postDelayed(this, LOOP_TIME)
                                    } else {
                                        vp.postDelayed(mDismissTask, AUTO_DISMISS_TIME)
                                    }
                                }
                            }
                        }
                        post(mLoopTask)
                    }
                }
            }
            return
        }

        EasyFloat.with(activity)
            .setLayout(R.layout.layout_float_load_complete)
            .setTag(LOAD_COMPLETE_WINDOW)
            .setDragEnable(false)
            .setMatchParent(widthMatch = true, heightMatch = false)
            .setGravity(Gravity.BOTTOM, 0, (-62F).dip2px())
            .setAnimator(LoadCompleteFloatAnimator())
            .registerCallback {
                createResult { _, _, view ->
                    view?.findViewById<ConstraintLayout>(R.id.container)?.let {
                        initFloatingView(it, activity, gameEntityList)
                    }
                }
            }
            .show()
    }

    private fun initFloatingView(view: ConstraintLayout, activity: Activity, entityList: List<GameEntity>) {
        val mBinding = LayoutFloatLoadCompleteBinding.bind(view)
        val mAdapter = GameLoadCompleteAdapter(activity, entityList)
        val mLoopTask = object : Runnable {
            private val reference: WeakReference<ViewPager2> = WeakReference(mBinding.viewPager)

            override fun run() {
                val vp: ViewPager2? = reference.get()
                if (vp != null) {
                    val count = mBinding.viewPager.adapter?.itemCount ?: 0
                    if (count == 0) return
                    val next = vp.currentItem + 1
                    if (next < count) {
                        vp.setCurrentItem(next, LOOP_DURATION)
                        vp.postDelayed(this, LOOP_TIME)
                    } else {
                        vp.postDelayed(mDismissTask, AUTO_DISMISS_TIME)
                    }
                }
            }
        }
        mBinding.viewPager.run {
            adapter = mAdapter
            isUserInputEnabled = false
            orientation = ViewPager2.ORIENTATION_VERTICAL
            offscreenPageLimit = entityList.size
            registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                    super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                    val layoutManager = (get(0) as RecyclerView).layoutManager as LinearLayoutManager
                    layoutManager.findViewByPosition(position)?.alpha = 1 - positionOffset
                    layoutManager.findViewByPosition(position + 1)?.alpha = positionOffset
                }
            })
            if (entityList.size > 1) {
                postDelayed(mLoopTask, LOOP_TIME)
            } else {
                postDelayed(mDismissTask, AUTO_DISMISS_TIME)
            }
        }
        mBinding.closeIv.setOnClickListener {
            if (!ClickUtils.isFastDoubleClick(it.id)) {
                NewFlatLogUtils.logHaloFunDownloadCompleteTipClick(
                    "关闭",
                    mAdapter.gameEntityList[mBinding.viewPager.currentItem].id
                )
                mBinding.viewPager.removeCallbacks(mLoopTask)
                mBinding.viewPager.removeCallbacks(mDismissTask)
                EasyFloat.dismiss(LOAD_COMPLETE_WINDOW)
            }
        }
        mBinding.launchTv.setOnClickListener {
            NewFlatLogUtils.logHaloFunDownloadCompleteTipClick(
                "启动",
                mAdapter.gameEntityList[mBinding.viewPager.currentItem].id
            )
            VHelper.installOrLaunch(
                activity,
                mAdapter.gameEntityList[mBinding.viewPager.currentItem].getApk()[0].packageName
            )
        }
    }
}

class LoadCompleteFloatAnimator : OnFloatAnimator {
    override fun enterAnim(
        view: View,
        params: WindowManager.LayoutParams,
        windowManager: WindowManager,
        sidePattern: SidePattern
    ): Animator = getEnterAnimator(view)

    override fun exitAnim(
        view: View,
        params: WindowManager.LayoutParams,
        windowManager: WindowManager,
        sidePattern: SidePattern
    ): Animator = getExitAnimator(view)

    private fun getEnterAnimator(view: View): Animator {
        val alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 0F, 1F).apply {
            duration = DURATION
            interpolator = AccelerateDecelerateInterpolator()
        }
        val scaleXAnimator = ObjectAnimator.ofFloat(view, "scaleX", 0.8F, 1F).apply {
            duration = DURATION
            interpolator = AccelerateDecelerateInterpolator()
        }
        val scaleYAnimator = ObjectAnimator.ofFloat(view, "scaleY", 0.8F, 1F).apply {
            duration = DURATION
            interpolator = AccelerateDecelerateInterpolator()
        }
        view.pivotX = view.width / 2F
        view.pivotY = view.height / 2F
        return AnimatorSet().apply { playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator) }
    }

    private fun getExitAnimator(view: View): Animator {
        val alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 1F, 0F).apply {
            duration = DURATION
            interpolator = AccelerateDecelerateInterpolator()
        }
        val scaleXAnimator = ObjectAnimator.ofFloat(view, "scaleX", 1F, 0.8F).apply {
            duration = DURATION
            interpolator = AccelerateDecelerateInterpolator()
        }
        val scaleYAnimator = ObjectAnimator.ofFloat(view, "scaleY", 1F, 0.8F).apply {
            duration = DURATION
            interpolator = AccelerateDecelerateInterpolator()
        }
        view.pivotX = view.width / 2F
        view.pivotY = view.height / 2F
        return AnimatorSet().apply {
            playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator)
            doOnEnd {
                view.visibility = View.GONE
            }
        }
    }

    companion object {
        const val DURATION = 200L
    }
}

class GameLoadCompleteAdapter(context: Context, var gameEntityList: List<GameEntity> = emptyList()) :
    BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {

    fun submitList(entityList: List<GameEntity>) {
        if (entityList.isNotEmpty()) {
            gameEntityList = arrayListOf<GameEntity>().apply {
                addAll(gameEntityList)
                addAll(entityList)
            }
            notifyDataSetChanged()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GameLoadCompleteViewHolder(parent.toBinding())

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is GameLoadCompleteViewHolder) {
            val gameEntity = gameEntityList[position]
            holder.binding.gameIconIv.displayGameIcon(gameEntity)
            holder.binding.gameNameTv.text = gameEntity.name
        }
    }

    override fun getItemCount() = gameEntityList.size

    class GameLoadCompleteViewHolder(val binding: ItemFloatGameLoadCompleteBinding) :
        RecyclerView.ViewHolder(binding.root)

}

private fun ViewPager2.setCurrentItem(
    item: Int,
    duration: Long,
    interpolator: TimeInterpolator = AccelerateDecelerateInterpolator(),
    pagePxHeight: Int = height
) {
    val pxToDrag: Int = pagePxHeight * (item - currentItem)
    val animator = ValueAnimator.ofInt(0, pxToDrag)
    var previousValue = 0
    animator.addUpdateListener { valueAnimator ->
        val currentValue = valueAnimator.animatedValue as Int
        val currentPxToDrag = (currentValue - previousValue).toFloat()
        fakeDragBy(-currentPxToDrag)
        previousValue = currentValue
    }
    animator.addListener(object : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator) {
            beginFakeDrag()
        }

        override fun onAnimationEnd(animation: Animator) {
            endFakeDrag()
        }

        override fun onAnimationCancel(animation: Animator) {}
        override fun onAnimationRepeat(animation: Animator) {}
    })
    animator.interpolator = interpolator
    animator.duration = duration
    animator.start()
}