package com.gh.gamecenter.energy.view

import android.graphics.Typeface
import android.os.Build
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentStatePagerAdapter
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.provider.IDirectProvider
import com.gh.gamecenter.energy.HaloApp
import com.gh.gamecenter.energy.R
import com.gh.gamecenter.energy.databinding.FragmentEnergyHouseBinding
import com.gh.gamecenter.energy.databinding.TabItemCommodityBinding
import com.gh.gamecenter.energy.entity.CommodityCategoryEntity
import com.gh.gamecenter.energy.entity.Size
import com.gh.gamecenter.energy.utils.IntegralLogHelper
import com.gh.gamecenter.login.entity.UserInfoEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.tabs.TabLayout
import kotlin.math.abs

class EnergyHouseFragment : BaseLazyFragment() {

    private var mBinding: FragmentEnergyHouseBinding? = null
    private var mUserViewModel: UserViewModel? = null
    private var mEnergyUserViewModel: EnergyUserViewModel? = null
    private var mEnergyHouseViewModel: EnergyHouseViewModel? = null
    private var mCommodityCategories: List<CommodityCategoryEntity>? = null
    private var mUserInfo: UserInfoEntity? = null
    private val mTitleList = ArrayList<String>()
    private var mTabList = arrayListOf<TextView>()
    private val mFragments = ArrayList<Fragment>()
    private val mRollNotices = ArrayList<String>()
    private var mCurrentSizeIndex = 0
    private var mCurrentSize = Size()
    private var mEnergy = 0L
    private var mCategoryId = ""
    private var mInitIndex = 0
    private var mBehavior: BottomSheetBehavior<RelativeLayout>? = null

    override fun getLayoutId() = 0

    override fun getInflatedLayout() = FragmentEnergyHouseBinding.inflate(layoutInflater).apply { mBinding = this }.root

    override fun onFragmentResume() {
        super.onFragmentResume()

        if (NetworkUtils.isNetworkConnected(requireContext())) {
            if (UserManager.getInstance().isLoggedIn) {
                mEnergyUserViewModel?.getUserEnergy()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mCategoryId = arguments?.getString(EntranceConsts.KEY_CATEGORY_ID) ?: ""
        mEnergyHouseViewModel = viewModelProvider()
        mUserViewModel = viewModelProvider(UserViewModel.Factory(HaloApp.getInstance()))
        mEnergyUserViewModel =
            viewModelProvider(EnergyUserViewModel.Factory(HaloApp.getInstance(), UserManager.getInstance().userId))

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        arrayListOf(
            mBinding?.backIv,
            mBinding?.userIcon,
            mBinding?.loginTipTv,
            mBinding?.userEnergyContainer,
            mBinding?.exchangeRuleTv,
            mBinding?.exchangeCommodity,
            mBinding?.lotteryParadise,
            mBinding?.rollNotice,
            mBinding?.earnEnergy
        ).forEach {
            it?.setOnClickListener(this)
        }

        mUserViewModel?.loginObsUserinfo?.observeNonNull(viewLifecycleOwner) {
            if (it.data != null) {
                mBinding?.run {
                    mUserInfo = it.data
                    userIcon.display(mUserInfo?.iconBorder?.url, mUserInfo?.icon ?: "")
                    loginTipTv.visibility = View.GONE
                    mEnergyUserViewModel?.userId = UserManager.getInstance().userId
                    mEnergyUserViewModel?.getUserEnergy()
                }
            }
        }

        mEnergyUserViewModel?.energy?.observeNonNull(viewLifecycleOwner) {
            mEnergy = it
            mBinding?.run {
                userEnergyContainer.visibility = View.VISIBLE
                userEnergy.text = it.toString()
            }
        }

        mEnergyHouseViewModel?.rollNotices?.observeNonNull(viewLifecycleOwner) { list ->
            if (list.isEmpty()) return@observeNonNull
            mRollNotices.clear()
            list.forEach {
                mRollNotices.add("恭喜<font color=\"#1383EB\">${it.user.name}</font>兑换了<font color=\"#1383EB\">${it.commodity.name}")
            }
            initRollNotice()
        }

        mEnergyHouseViewModel?.commodityCategories?.observeNonNull(viewLifecycleOwner) {
            if (it.isEmpty()) return@observeNonNull
            mCommodityCategories = it
            initViewPager()
        }

        mBinding?.run {
//            background.layoutParams = background.layoutParams.apply {
//                val screenWidth = resources.displayMetrics.widthPixels
//                height = screenWidth * 400 / 360
//            }

            val screenHeight = when {
                Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 -> {
                    resources.displayMetrics.heightPixels
                }

                Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
                    DisplayMetrics()
                        .apply { requireActivity().display?.getRealMetrics(this) }
                        .heightPixels
                }

                else -> {
                    @Suppress("DEPRECATION")
                    DisplayMetrics()
                        .apply { requireActivity().windowManager.defaultDisplay.getRealMetrics(this) }
                        .heightPixels
                }
            }

            mBehavior = BottomSheetBehavior.from(bottomSheet)
            mBehavior?.peekHeight = screenHeight - 288F.dip2px()

            val layoutParams = bottomSheet.layoutParams
            layoutParams.height = screenHeight - 40F.dip2px()
            bottomSheet.layoutParams = layoutParams

            mBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                        mBehavior?.state = BottomSheetBehavior.STATE_COLLAPSED
                    }
                }

                override fun onSlide(bottomSheet: View, slideOffset: Float) {
                }
            })
        }
    }

    private fun initRollNotice() {
        mBinding?.run {
            rollNotice.visibility = View.VISIBLE
            rollNoticeMV.startWithListForHtmlText(mRollNotices)
        }
    }

    private fun initViewPager() {
        mBinding?.run {
            mTitleList.clear()
            mFragments.clear()
            val tag = "android:switcher:${viewpager.id}:"
            mCommodityCategories?.forEachIndexed { index, entity ->
                if (mCategoryId.isNotBlank() && mCategoryId == entity.id) {
                    mInitIndex = index
                }

                mTitleList.add(entity.name)
                val commodityListFragment = childFragmentManager.findFragmentByTag("$tag$index")
                    ?: CommodityFragment().with(
                        bundleOf(
                            EntranceConsts.KEY_ENTRANCE to "光能屋",
                            EntranceConsts.KEY_CATEGORY to entity
                        )
                    )
                mFragments.add(commodityListFragment)
            }

            viewpager.offscreenPageLimit = mFragments.size
            viewpager.adapter =
                object : FragmentStatePagerAdapter(childFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
                    override fun getItem(position: Int) = mFragments[position]

                    override fun getCount() = mFragments.size

                    override fun getPageTitle(position: Int): CharSequence? {
                        return if (mTitleList.size > position) {
                            mTitleList[position]
                        } else super.getPageTitle(position)
                    }
                }

            viewpager.doOnScroll(
                onPageSelected = { position ->
                    updateTabTextStyle(position, 0F)
                },
                onPageScrolled = { position, positionOffset, _ ->
                    if (position + 1 != mTabList.size) {
                        mTabList[position].run {
                            textSize = (DEFAULT_TAB_TEXT_SIZE + ((1 - positionOffset) * 4)).roundTo(1)
//                                setTextColor(ColorUtils.blendARGB(TAB_DEFAULT_COLOR, TAB_SELECTED_COLOR, 1 - positionOffset))
                        }
                        mTabList[position + 1].run {
                            textSize = (DEFAULT_TAB_TEXT_SIZE + ((positionOffset) * 4)).roundTo(1)
//                                setTextColor(ColorUtils.blendARGB(TAB_DEFAULT_COLOR, TAB_SELECTED_COLOR, positionOffset))
                        }

                        // 多 tab 切换的时候可能会出现某些 tab 的文字没有回归到原始大小的问题的问题 (positionOffset 不保证连续)
                        for ((index, tabTv) in mTabList.withIndex()) {
                            if (abs(index - position) >= 2) {
                                if (tabTv.textSize != DEFAULT_TAB_TEXT_SIZE) {
                                    tabTv.textSize = DEFAULT_TAB_TEXT_SIZE
//                                        tabTv.setTextColor(TAB_DEFAULT_COLOR)
                                }
                            }
                        }
                    }

                    updateTabTextStyle(position, positionOffset)
                }
            )

            tabLayout.setupWithViewPager(viewpager)
            indicatorView.run {
                setupWithTabLayout(tabLayout)
                setupWithViewPager(viewpager)
                setIndicatorWidth(18)
            }

            for (i in 0 until tabLayout.tabCount) {
                val tab = tabLayout.getTabAt(i) ?: continue
                val tabTitle = if (tab.text != null) tab.text.toString() else ""
                val tabViewBinding = generateTabView(
                    tabTitle,
                    i == 0,
                    i == tabLayout.tabCount - 1
                )
                mTabList.add(tabViewBinding.tabTitle)
                tab.customView = tabViewBinding.root
                tab.view.setPadding(0, 0, 0, 0)
            }

            viewpager.currentItem = mInitIndex
            tabLayout.getTabAt(mInitIndex)?.let { updateTabTextStyle(mInitIndex, 0F) }
            setNestedScrollingEnabledForIndex(mInitIndex)

            tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                override fun onTabReselected(tab: TabLayout.Tab?) {
                }

                override fun onTabUnselected(tab: TabLayout.Tab?) {
                }

                override fun onTabSelected(tab: TabLayout.Tab?) {
                    tab?.run {
                        mCommodityCategories?.get(position)?.run {
                            IntegralLogHelper.logCommodityCategory(
                                "click_tab_goods_catalog",
                                "光能屋",
                                "光能屋-商品分类",
                                id,
                                name
                            )
                        }
                    }
                }
            })

            viewpager.addOnPageChangeListener {
                setNestedScrollingEnabledForIndex(it)
            }
        }

        initSize()
    }

    private fun setNestedScrollingEnabledForIndex(currentIndex: Int) {
        mFragments.forEachIndexed { index, fragment ->
            (fragment as CommodityFragment).setNestedScrollingEnabled(currentIndex == index)
        }

        mBinding?.bottomSheet?.requestLayout()
    }

    private fun updateTabTextStyle(selectedPosition: Int, positionOffset: Float) {
        for ((index, titleTv) in mTabList.withIndex()) {
            if (index == selectedPosition) {
//                titleTv.setTextColor(TAB_SELECTED_COLOR)
                if (positionOffset == 0F) {
                    titleTv.setTypeface(null, Typeface.NORMAL)
                    titleTv.setTypeface(titleTv.typeface, Typeface.BOLD)
                }
            } else {
//                titleTv.setTextColor(TAB_DEFAULT_COLOR)
                if (positionOffset == 0F) {
                    titleTv.setTypeface(null, Typeface.NORMAL)
                }
            }
        }
    }

    private fun generateTabView(title: String, isFirst: Boolean, isLast: Boolean): TabItemCommodityBinding {
        val binding = TabItemCommodityBinding.inflate(LayoutInflater.from(requireContext()))
        binding.tabTitle.run {
            val padLeft = if (isFirst) 16F.dip2px() else 8F.dip2px()
            val padRight = if (isLast) 16F.dip2px() else 8F.dip2px()
            setPadding(padLeft, 0, padRight, 0)
            text = title
            textSize = DEFAULT_TAB_TEXT_SIZE
            setTextColor(TAB_TEXT_COLOR)
        }
        return binding
    }

    private fun getDefaultSizeFilterArray(): ArrayList<Size> {
        return arrayListOf<Size>().apply {
            add(Size(min = -1, max = -1, text = "全部"))
            add(Size(min = 1, max = 100, text = "1-100"))
            add(Size(min = 101, max = 500, text = "101-500"))
            add(Size(min = 501, max = 2000, text = "501-2000"))
            add(Size(min = 2000, max = -1, text = "2000以上"))
        }
    }


    private fun initSize() {
        mBinding?.run {
            getDefaultSizeFilterArray().forEachIndexed { index, size ->
                val item = layoutInflater.inflate(R.layout.item_filter_commodity_size, sizeContainer, false)
                sizeContainer.addView(item)
                val tv = item.findViewById<TextView>(R.id.size_tv)
                tv.text = size.text
                item.setOnClickListener {
                    if (mCurrentSizeIndex != index) {
                        IntegralLogHelper.logEnergyRange("click_energy_number_filter", LOCATION, size.text ?: "")
                        changeSizeBg(index)
                        (mFragments[viewpager.currentItem] as CommodityFragment).refreshPage(size)
                        mCurrentSizeIndex = index
                        mCurrentSize = size
                    }
                }
            }
            changeSizeBg(0)
        }
    }

    private fun changeSizeBg(position: Int) {
        mBinding?.run {
            getDefaultSizeFilterArray().forEachIndexed { index, _ ->
                val item = sizeContainer.getChildAt(index)
                val tv = item.findViewById<TextView>(R.id.size_tv)
                if (position == index) {
                    tv.setTextColor(R.color.white.toColor())
                    tv.setBackgroundResource(R.drawable.button_round_00dba4)
                } else {
                    tv.setTextColor(R.color.text_title.toColor())
                    tv.setBackgroundResource(R.drawable.button_round_ebf9fa)
                }
            }
        }
    }

    fun getCurrentSize() = mCurrentSize

    override fun onClick(v: View) {
        super.onClick(v)
        when (v.id) {
            R.id.backIv -> requireActivity().finish()

            R.id.userIcon -> ifLogin("光能屋-头像")

            R.id.loginTipTv -> ifLogin("光能屋-登录兑大奖")

            R.id.earnEnergy -> {
                IntegralLogHelper.run {
                    log("click_energy_center", LOCATION, "光能屋-更多")
                    log("view_energy_center", "光能中心")
                    log("click_more", LOCATION)
                }

                startActivity(EnergyCenterActivity.getIntent(requireContext()))
            }

            R.id.userEnergyContainer -> {
                IntegralLogHelper.run {
                    log("click_energy_record", LOCATION, "光能屋-光能值")
                    log("view_energy_record", "光能明细")
                    log("click_energy", LOCATION)
                }

                ifLogin("光能屋-光能值") {
                    val directUtils =
                        ARouter.getInstance().build(RouteConsts.provider.directUtils).navigation() as? IDirectProvider
                    directUtils?.directToEnergyRecord(requireContext())
                }
            }

            R.id.exchangeRuleTv -> {
                IntegralLogHelper.run {
                    log("click_exchange_rule", LOCATION)
                    log("view_exchange_rule", "兑换规则")
                }
                val directUtils =
                    ARouter.getInstance().build(RouteConsts.provider.directUtils).navigation() as? IDirectProvider
                directUtils?.directToExchangeRulePage(requireContext())
            }

            R.id.exchangeCommodity -> {
                IntegralLogHelper.run {
                    log("click_exchange_record", LOCATION)
                    log("view_exchange_record", "兑换商品")
                }

                ifLogin("光能屋-兑换商品") {
                    val directUtils =
                        ARouter.getInstance().build(RouteConsts.provider.directUtils).navigation() as? IDirectProvider
                    directUtils?.directToExchangeCommodityPage(requireContext())
                }
            }

            R.id.lotteryParadise -> {
                IntegralLogHelper.run {
                    log("click_draw_center", LOCATION)
                    log("view_raffle_center", "抽奖乐园页")
                }

                ifLogin("光能屋-抽奖乐园") {
                    val directUtils =
                        ARouter.getInstance().build(RouteConsts.provider.directUtils).navigation() as? IDirectProvider
                    directUtils?.directToLotteryParadisePage(requireContext())
                }
            }

            R.id.rollNotice -> {
                IntegralLogHelper.log("click_store_scroll_bar", LOCATION)
            }
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding?.root?.setBackgroundColor(R.color.background_white.toColor(requireContext()))
    }

    companion object {
        const val LOCATION = "光能屋"
        var TAB_TEXT_COLOR: Int = R.color.text_00DBA4.toColor()
        var DEFAULT_TAB_TEXT_SIZE = 14F
    }
}