package com.gh.gamecenter.home.custom.viewholder

import android.content.Context
import android.view.MotionEvent
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.view.postDelayed
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.divider.PaddingDecoration
import com.gh.gamecenter.databinding.ItemHomeGameTestV2CustomBinding
import com.gh.gamecenter.entity.HomeItemTestV2Entity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.game.vertical.SpanCountPagerSnapHelper
import com.gh.gamecenter.home.custom.CustomNewGameTestUseCase
import com.gh.gamecenter.home.custom.CustomPageViewModel
import com.gh.gamecenter.home.custom.IGameChangedNotifier
import com.gh.gamecenter.home.custom.adapter.CustomHomeGameTestV2GameListRvAdapter
import com.gh.gamecenter.home.custom.adapter.CustomHomeGameTestV2RecommendRvAdapter
import com.gh.gamecenter.home.custom.adapter.CustomHomeGameTestV2TimePointRvAdapter
import com.gh.gamecenter.home.custom.eventlistener.OtherItemEventHelper
import com.gh.gamecenter.home.custom.model.CustomGameTestV2Item
import com.gh.gamecenter.home.custom.model.CustomPageItem
import com.gh.gamecenter.home.test_v2.HomeGameTestV2Decoration
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity
import com.lightgame.utils.Utils
import kotlin.math.abs

/**
 * 新游开测
 */
class CustomHomeItemGameTestV2ViewHolder(
    viewModel: CustomPageViewModel,
    private val lifecycleOwner: LifecycleOwner,
    private val binding: ItemHomeGameTestV2CustomBinding,
) : BaseCustomViewHolder(viewModel, binding.root) {
    private var linkId = "none"
    private var linkText = ""

    private val testUseCase: CustomNewGameTestUseCase
        get() = viewModel.getNewGameTestUserCase(linkId)

    private val context: Context
        get() = itemView.context

    private var mSkeletonView: ViewSkeletonScreen? = null

    private var mLastParseIndex = -1

    private var mLastX: Int = 0
    private var mLastY: Int = 0

    private var mHomePageGameList: List<GameEntity>? = null

    private var _position: Int = 0

    override val childEventHelper by lazy(LazyThreadSafetyMode.NONE) {
        OtherItemEventHelper(viewModel)
    }

    private val layoutManager by lazy {
        GridLayoutManager(context, 3, GridLayoutManager.HORIZONTAL, false)
    }

    private val adapter by lazy {
        CustomHomeGameTestV2GameListRvAdapter(
            itemView.context,
            childEventHelper,
            linkText,
            pageLocation,
            pageConfigure,
            _item.componentPosition,
            createTrackData(_item)
        )
    }

    private val pointAdapter by lazy {
        CustomHomeGameTestV2TimePointRvAdapter(itemView.context, testUseCase, linkText, pageLocation)
    }

    private val recommendAdapter by lazy {
        CustomHomeGameTestV2RecommendRvAdapter(itemView.context, linkText, pageLocation)
    }

    override val gameChangedNotifier: IGameChangedNotifier
        get() = adapter

    init {
        binding.labelRecommendRv.isNestedScrollingEnabled = false
        binding.labelRecommendRv.addItemDecoration(
            PaddingDecoration(leftSide = 16F.dip2px(), rightSide = 16F.dip2px(), rightSpace = 8F.dip2px())
        )
    }

    fun bindView(
        item: CustomPageItem,
        position: Int
    ) {
        super.bindView(item)
        _position = position

        if (item is CustomGameTestV2Item) {
            linkId = item.link.link ?: "none"
            linkText = item.link.text ?: ""
            var isFirstScrollTimePoint = true
            testUseCase.getTimePointLiveData().observe(lifecycleOwner) {
                val index = pointAdapter.dataList.indexOf(it)
                if (index != -1) {
                    if (isFirstScrollTimePoint) {
                        binding.timePointRv.scrollToPosition(index)
                        isFirstScrollTimePoint = false
                    } else {
                        binding.timePointRv.smoothScrollToPosition(index)
                    }
                    pointAdapter.selectPoint(index, false)
                }
            }

            val data = item.data
            // 设置标题
            bindTitle(data)
            //绑定时间轴数据
            bindTimePoint(data)
            //绑定新游开测推荐
            bindRecommend(data)
            //设置holder在父列表的位置
            testUseCase.setParentPosition(position)
            //绑定游戏列表
            bindGameList(testUseCase, data)
        }
    }

    private fun bindTitle(data: HomeItemTestV2Entity) {
        with(binding.layoutTitle) {
            lavRefresh.goneIf(true)
            gUser.goneIf(true)

            if (tvTitle.text.isBlank()) {
                tvTitle.text = R.string.new_game_start_test.toResString()
            }

            val rightText = if (data.rightTop.text == ALL) {
                RIGHT_TEXT_ALL
            } else {
                RIGHT_TEXT_MORE
            }

            tvRight.text = rightText
            tvRight.setOnClickListener {
                if (data.rightTop.text == ALL) {
                    NewFlatLogUtils.logGameTestV2MoreClick(rightText, "自定义页面")
                    //点击进入[新游开测]详情页面
                    itemView.context.startActivity(
                        GameServerTestV2Activity.getIntent(
                            itemView.context,
                            _item.link.link ?: "none",
                            "新游开测"
                        )
                    )
                } else {
                    //点击跳转通用链接
                    val link = data.rightTop.link
                    DirectUtils.directToLinkPage(itemView.context, link, "新游开测", "")
                    NewFlatLogUtils.logGameTestV2MoreClick(
                        rightText,
                        "自定义页面",
                        linkType = link.type ?: "",
                        linkId = link.link ?: "",
                        linkText = link.text ?: ""
                    )
                }
                SensorsBridge.trackColumnTestClick(
                    location = "自定义页面",
                    recommendType = linkText,
                    text = "右上角",
                    bottomTab = pageLocation.bottomTab,
                    multiTabName = pageLocation.severalTabPageName,
                    multiTabId = pageLocation.severalTabPageId,
                    position = pageLocation.tabPosition,
                    tabContent = pageLocation.tabContent,
                    customPageName = pageLocation.pageName,
                    customPageId = pageLocation.pageId,
                    buttonType = rightText,
                    linkType = data.rightTop.link.type,
                    linkId = data.rightTop.link.link,
                    linkText = data.rightTop.link.text
                )
            }
        }
    }

    private fun bindGameList(viewModel: CustomNewGameTestUseCase, data: HomeItemTestV2Entity) {
        val isDarkModeOn = DarkModeUtils.isDarkModeOn(context)
        if (isDarkModeOn) {
            binding.container.background = null
        } else {
            binding.container.setBackgroundResource(R.drawable.bg_test_v2_card_shadow)
        }
        binding.containerLl.background =
            ContextCompat.getDrawable(context, R.drawable.bg_item_game_test_v2)

        if (binding.recyclerView.adapter == null) {
            binding.recyclerView.onFlingListener = null
            binding.recyclerView.isNestedScrollingEnabled = false
            binding.recyclerView.itemAnimator = null
            binding.recyclerView.clearOnScrollListeners()
            binding.recyclerView.addItemDecoration(HomeGameTestV2Decoration())
            val snapHelper = SpanCountPagerSnapHelper(3, false)
            snapHelper.attachToRecyclerView(binding.recyclerView)
            binding.recyclerView.layoutManager = layoutManager
            binding.recyclerView.adapter = adapter

            //列表滑动处理
            binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    Utils.log("onScrollStateChanged: newState = $newState")
                    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                        // 高速滑动时可能触发空指针闪退
                        try {
                            recyclerView.handler.removeCallbacksAndMessages(null)
                        } catch (e: NullPointerException) {
                            e.printStackTrace()
                        }
                        recyclerView.postDelayed(300) { // 解决动画没结束时候条目和时间轴不对应问题
                            onRecyclerViewChanged(true)
                        }
                        recyclerView.post {
                            recyclerView.suppressLayout(false)
                        }
                    } else if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
                        recyclerView.suppressLayout(true)
                    }
                }
            })
            binding.recyclerView.addOnItemTouchListener(object :
                RecyclerView.SimpleOnItemTouchListener() {
                override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                    val x = e.x.toInt()
                    val y = e.y.toInt()

                    when (e.action) {
                        MotionEvent.ACTION_DOWN -> {
                            mLastX = e.x.toInt()
                            mLastY = e.y.toInt()
                            rv.parent.parent.requestDisallowInterceptTouchEvent(true)
                        }

                        MotionEvent.ACTION_UP -> rv.parent.parent.requestDisallowInterceptTouchEvent(
                            false
                        )

                        MotionEvent.ACTION_MOVE -> {
                            val deltaX: Int = x - mLastX
                            val deltaY: Int = y - mLastY
                            val isHorizontalScroll = abs(deltaX) > abs(deltaY)
                            rv.parent.parent.requestDisallowInterceptTouchEvent(isHorizontalScroll)
                        }
                    }
                    return false
                }
            })
        } else {
            //如果是游戏屏蔽列表更新事件，这里比对现有的游戏列表，是否需要更新
            checkData(data)
            return
        }

        viewModel.getDataListLiveData().observe(lifecycleOwner) {
            adapter.setData(it)
        }
        viewModel.getGameListScrollLiveData().observe(lifecycleOwner) { p ->
            layoutManager.scrollToPositionWithOffset(p, 0)
            //优化条目没有居中问题，因为上面没有触发snapHelper
            binding.recyclerView.postDelayed(100) {
                binding.recyclerView.jumpToPositionForSmoothScroller(p)
            }
        }
        viewModel.getLoadStateLiveData().observe(lifecycleOwner) {
            dispatchLoadState(it)
        }

        setData(data)
    }

    //如果是游戏屏蔽列表更新事件，这里比对现有的游戏列表，是否需要更新
    private fun checkData(
        data: HomeItemTestV2Entity
    ) {
        val oldData = mHomePageGameList
        val newData = mutableListOf<GameEntity>()
        data.data.forEach {
            it.games.forEach { game ->
                newData.add(game)
            }
        }
        if (oldData?.size != newData.size) {
            setData(data)
            adapter.notifyDataSetChanged()
            Utils.log("checkData: size not equal")
            return
        }
        for (i in oldData.indices) {
            if (oldData[i].id != newData[i].id) {
                setData(data)
                adapter.notifyDataSetChanged()
                Utils.log("checkData: id not equal")
                return
            }
        }
    }

    /**
     * 设置初始数据
     */
    private fun setData(data: HomeItemTestV2Entity) {
        val defaultTimeType = data.timeType
        val defaultDatePosition = data.startPoint.indexOfFirst { it.timeType == defaultTimeType }
        val dataCount = data.dataCount
        val isDefaultFirstDate = defaultDatePosition == 0

        //设置时间轴数据
        testUseCase.setTimePoint(data.startPoint, defaultDatePosition)
        //设置游戏列表占位数据
        testUseCase.setDataCount(dataCount)
        //绑定游戏列表数据
        testUseCase.addGameList(
            list = data.data,
            timeType = data.timeType,
            pageId = data.pageId,
            action = CustomNewGameTestUseCase.Action.getActionByCommand(data.action),
            isDefaultFirstDate = isDefaultFirstDate,
            isRefresh = true
        )
        //数据填充完毕后滑动到默认时间轴位置
        if (!isDefaultFirstDate) {
            binding.recyclerView.postDelayed(100) {
                val currentData = testUseCase.getDataListLiveData().value ?: arrayListOf()
                val defaultItemPosition = currentData.indexOfFirst { it.timeType == data.timeType && !it.isPlaceHolder }
                if (defaultItemPosition != -1) {
                    val gridLayoutManager = binding.recyclerView.layoutManager as? GridLayoutManager
                    gridLayoutManager?.scrollToPositionWithOffset(defaultItemPosition, 0)
                    binding.recyclerView.postDelayed(100) {
                        binding.recyclerView.jumpToPositionForSmoothScroller(defaultItemPosition)
                    }
                }
            }
        }
        //记录老的首页游戏列表数据
        val oldData = mutableListOf<GameEntity>()
        data.data.forEach {
            it.games.forEach { game ->
                oldData.add(game)
            }
        }
        mHomePageGameList = oldData
    }

    /**
     * 列表滑动或者数据变更，分析第一个条目索引，决定是否加载数据
     */
    private fun onRecyclerViewChanged(isOnScroll: Boolean = true) {
        val recyclerView = binding.recyclerView
        val adapter = recyclerView.adapter as? CustomHomeGameTestV2GameListRvAdapter ?: return
        val layoutManager = recyclerView.layoutManager as GridLayoutManager
        val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
        Utils.log("onScrollStateChanged: firstVisiblePosition = $firstVisiblePosition")
        if (firstVisiblePosition < 0) return
        val firstVisibleItem = adapter.getItem(firstVisiblePosition)
        //第一个完全可见的条目
        val firstCompletelyVisiblePosition = layoutManager.findFirstCompletelyVisibleItemPosition()
        if (firstCompletelyVisiblePosition == -1) {
            return
        }
        val firstCompletelyVisibleItem =
            adapter.getItem(firstCompletelyVisiblePosition)
        firstVisibleItem.let {
            //通知时间轴变化
            val timeType = firstCompletelyVisibleItem.timeType
            if (isOnScroll) {
                testUseCase.onTimePointSelected(timeType)
            }
            val parsePosition = if (firstCompletelyVisiblePosition != -1) {
                firstCompletelyVisiblePosition
            } else {
                firstVisiblePosition
            }
            //分析分页加载动作
            if (parsePosition != mLastParseIndex) {
                testUseCase.parseActionWithPosition(parsePosition)
                mLastParseIndex = parsePosition
                Utils.log("onScrollStateChanged: parseActionWithPosition = $parsePosition")
            }
        }
    }

    private fun dispatchLoadState(it: LoadStatus?) {
        when (it) {
            LoadStatus.LIST_LOADING -> {
                //mBinding.recyclerView.suppressLayout(true)
            }

            LoadStatus.INIT_LOADING -> {
                binding.recyclerView.isVisible = false
                binding.reuseNoConnection.reuseNoConnection.isVisible = false
                showSkeletonView(binding.recyclerView)
            }

            LoadStatus.INIT_LOADED,
            LoadStatus.LIST_OVER,
            LoadStatus.LIST_LOADED -> {
                binding.recyclerView.isVisible = true
                binding.recyclerView.suppressLayout(false)
                binding.reuseNoConnection.reuseNoConnection.isVisible = false
                mSkeletonView?.hide()
                //停顿一下再分析是否加载下一页
                binding.recyclerView.postDelayed(500) {
                    onRecyclerViewChanged(false)
                }
            }

            LoadStatus.LIST_FAILED,
            LoadStatus.INIT_FAILED -> {
                binding.recyclerView.isVisible = false
                binding.recyclerView.suppressLayout(false)
                binding.reuseNoConnection.reuseNoConnection.isVisible = true
                binding.reuseNoConnection.reuseNetworkErrorDescTv.isVisible = false
                binding.reuseNoConnection.connectionReloadTv.isVisible = false
                mSkeletonView?.hide()
            }

            else -> {
                binding.recyclerView.suppressLayout(false)
                if (binding.recyclerView.isVisible) return
                binding.recyclerView.isVisible = true
                binding.reuseNoConnection.reuseNoConnection.isVisible = false
                mSkeletonView?.hide()
            }
        }
    }

    private fun showSkeletonView(view: View) {
        if (mSkeletonView != null) {
            mSkeletonView?.hide()
            mSkeletonView = null
        }
        mSkeletonView = Skeleton.bind(view)
            .shimmer(true)
            .angle(Constants.SHIMMER_ANGLE)
            .color(com.gh.gamecenter.common.R.color.ui_skeleton_highlight)
            .duration(Constants.SHIMMER_DURATION)
            .maskWidth(Constants.MASK_WIDTH)
            .gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
            .apply {
                load(R.layout.item_game_test_v2_list_sheleton)
            }
            .show()
    }

    /**
     * 绑定时间轴数据
     */
    private fun bindTimePoint(data: HomeItemTestV2Entity) {
        if (binding.timePointRv.adapter == null) {
            binding.timePointRv.onFlingListener = null
            binding.timePointRv.isNestedScrollingEnabled = false
            binding.timePointRv.itemAnimator = null
            binding.timePointRv.adapter = pointAdapter
        }
        val timePointList = data.startPoint.map { it.timeType }
        pointAdapter.submitList(timePointList)
    }

    /**
     * 绑定新游开测推荐标签数据
     */
    private fun bindRecommend(data: HomeItemTestV2Entity) {
        val recommendList = data.recommendLabel
        if (recommendList.isEmpty()) {
            binding.labelRecommendRv.isVisible = false
            return
        }
        binding.labelRecommendRv.isVisible = true
        if (binding.labelRecommendRv.adapter == null) {
            binding.labelRecommendRv.adapter = recommendAdapter
        }
        recommendAdapter.submitList(recommendList)
    }

    companion object {
        private const val ALL = "all"
        private const val RIGHT_TEXT_ALL = "全部"
        private const val RIGHT_TEXT_MORE = "更多"
    }
}