package com.gh.gamecenter.wrapper

import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.widget.Checkable
import android.widget.LinearLayout
import androidx.viewbinding.ViewBinding
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.databinding.PieceBottomTabBinding
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.feature.utils.SentryHelper

/**
 * 底部Tab 基类
 */
abstract class BaseBottomTabFragment<T : ViewBinding> : ToolbarFragment() {

    protected var mViewPager: ViewPager2? = null
    protected var mBottomTabContainer: LinearLayout? = null
    protected val mBottomTabBindingList = ArrayList<T>()

    protected var mCheckedIndex = 0

    protected open fun provideBottomTabContainer(): LinearLayout? = mCachedView.findViewById(R.id.bottomTabContainer)
    protected open fun provideViewPager(): ViewPager2? = mCachedView.findViewById(R.id.viewPager)
    protected abstract fun provideAdapter(): FragmentStateAdapter
    protected open fun isSmoothScroll() = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewPager = provideViewPager()
        mBottomTabContainer = provideBottomTabContainer()

        initViewPager()
    }

    protected fun initBottomTab(bottomTabList: List<BottomTab>) {
        mBottomTabBindingList.clear()
        mBottomTabContainer?.run {
            visibility = View.VISIBLE
            removeAllViews()
            bottomTabList.forEachIndexed { index, bottomTab ->
                addView(
                    provideBottomTabView(index, bottomTab),
                    LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
                        weight = 1F
                        setMargins(0, 2F.dip2px(), 0, 0)
                    })
            }
        }
    }

    protected open fun provideBottomTabView(position: Int, bottomTab: BottomTab): View =
        PieceBottomTabBinding.bind(LayoutInflater.from(requireContext()).inflate(R.layout.piece_bottom_tab, null))
            .apply {
                tabTv.text = bottomTab.name
                if (!TextUtils.isEmpty(bottomTab.jsCode)) {
                    tabLottie.setFailureListener {
                        SentryHelper.onEvent(
                            SENTRY_ID_BOTTOM_TAB_LOTTIE_LOAD_FAILED,
                            BOTTOM_TAB_ID, bottomTab.id,
                            BOTTOM_TAB_NAME, bottomTab.name
                        )
                    }
                    tabLottie.setAnimationFromJson(bottomTab.jsCode, bottomTab.id + bottomTab.name)
                }
                if (bottomTab.iconSelector != 0) {
                    tabIv.setImageResource(bottomTab.iconSelector)
                } else {
                    ImageUtils.picasso
                        .load(Uri.parse(if (bottomTab.default) bottomTab.iconSelect else bottomTab.iconUnselect))
                        .placeholder(com.gh.gamecenter.common.R.drawable.occupy)
                        .into(tabIv)
                }
                root.isChecked = bottomTab.default
                mBottomTabBindingList.add(this as T)
                root.setOnClickListener(this@BaseBottomTabFragment)
            }.root

    protected fun initViewPager() {
        mViewPager?.run {
            isUserInputEnabled = false
            // 去掉默认动画
            setPageTransformer { page, _ ->
                page.translationX = 0F
                page.alpha = 1F
            }
            adapter = provideAdapter()
            registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                    super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                    this@BaseBottomTabFragment.onPageScrolled(position, positionOffset, positionOffsetPixels)
                }

                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                    this@BaseBottomTabFragment.onPageSelected(position)
                }

                override fun onPageScrollStateChanged(state: Int) {
                    super.onPageScrollStateChanged(state)
                    this@BaseBottomTabFragment.onPageScrollStateChanged(state)
                }
            })
        }
    }

    override fun handleOnClick(view: View?): Boolean {
        val toCheck = mBottomTabContainer?.indexOfChild(view) ?: -1
        if (toCheck != -1) {
            mViewPager?.setCurrentItem(toCheck, isSmoothScroll())
            return true
        }
        return super.handleOnClick(view)
    }

    protected open fun checkIndex(index: Int) {
        if (index < mBottomTabBindingList.size && mCheckedIndex < mBottomTabBindingList.size) {
            val binding = mBottomTabBindingList[index]
            (binding.root as? Checkable)?.isChecked = true
            if (index != mCheckedIndex) {
                val checkedBinding = mBottomTabBindingList[mCheckedIndex]
                (checkedBinding.root as? Checkable)?.isChecked = false
            }
            mCheckedIndex = index
        }
    }

    protected open fun onPageSelected(position: Int) {
        checkIndex(position)
    }

    protected open fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
    protected open fun onPageScrollStateChanged(state: Int) {}

    companion object {
        private const val SENTRY_ID_BOTTOM_TAB_LOTTIE_LOAD_FAILED = "bottom_tab_lottie_load_failed"
        private const val BOTTOM_TAB_ID = "bottom_tab_id"
        private const val BOTTOM_TAB_NAME = "bottom_tab_name"
    }
}