package com.gh.gamecenter.forum.home.follow.adapter

import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.consume
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.databinding.RecyclerAllFollowMyFollowHeaderBinding
import com.gh.gamecenter.databinding.RecyclerAllFollowedBinding
import com.gh.gamecenter.databinding.RecyclerAllFollowedNoTopBinding
import com.gh.gamecenter.entity.FollowOperateTopRequest
import com.gh.gamecenter.forum.home.follow.AllFollowedItem
import com.gh.gamecenter.forum.home.follow.AllFollowedItem.Companion.ALL_FOLLOWED_ITEM_TYPE_MY_FOLLOW_HEADER
import com.gh.gamecenter.forum.home.follow.AllFollowedItem.Companion.ALL_FOLLOWED_ITEM_TYPE_NORMAL
import com.gh.gamecenter.forum.home.follow.AllFollowedItem.Companion.ALL_FOLLOWED_ITEM_TYPE_NO_TOP
import com.gh.gamecenter.forum.home.follow.AllFollowedMyFollowedHeaderItem
import com.gh.gamecenter.forum.home.follow.AllFollowedNoTopItem
import com.gh.gamecenter.forum.home.follow.AllFollowedNormalItem
import com.gh.gamecenter.forum.home.follow.viewholder.FollowInvalidViewHolder
import com.gh.gamecenter.forum.home.follow.viewmodel.AllFollowedViewModel

class AllFollowedAdapter(
    private val viewModel: AllFollowedViewModel,
    private val startDrag: (ViewHolder) -> Unit,
) : ListAdapter<AllFollowedItem, ViewHolder>(createDiffItemCallBack()) {

    private var _isEdit = false
    val isEdit: Boolean
        get() = _isEdit

    // 置顶需要移动到的位置
    private var _topItemCount = 0
    val topItemCount: Int
        get() = _topItemCount

    // 已关注用户的数量（排除header footer等其它类型的item）
    private var _followedCount = 0
    val followedCount: Int
        get() = _followedCount

    private val _dataList = arrayListOf<AllFollowedNormalItem>()
    val dataList: List<AllFollowedNormalItem>
        get() = _dataList

    fun setData(data: List<AllFollowedItem>) {
        _dataList.clear()
        _dataList.addAll(data.filterIsInstance<AllFollowedNormalItem>())
        _followedCount = dataList.size
        _topItemCount = dataList.count(AllFollowedNormalItem::isTop)

        val dataWithHeader = arrayListOf<AllFollowedItem>()
        data.forEachIndexed { index, item ->
            if (index == 0) {
                dataWithHeader.add(AllFollowedMyFollowedHeaderItem(true))
            }
            if (topItemCount == 0 && index == 0) {
                // 暂时没有置顶的关注，需要显示提示
                dataWithHeader.add(AllFollowedNoTopItem())
                dataWithHeader.add(AllFollowedMyFollowedHeaderItem(false))
            } else if (topItemCount == index) {
                dataWithHeader.add(AllFollowedMyFollowedHeaderItem(false))
            }
            dataWithHeader.add(item)
        }
        super.submitList(dataWithHeader)
    }

    public override fun getItem(position: Int): AllFollowedItem {
        return super.getItem(position)
    }

    override fun getItemViewType(position: Int): Int = currentList[position].itemType

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
        when (viewType) {
            ALL_FOLLOWED_ITEM_TYPE_NO_TOP -> NoTopViewHolder(parent.toBinding())
            ALL_FOLLOWED_ITEM_TYPE_NORMAL -> AllFollowedViewHolder(parent.toBinding())
            ALL_FOLLOWED_ITEM_TYPE_MY_FOLLOW_HEADER -> MyFollowerHeaderViewHolder(parent.toBinding())
            else -> FollowInvalidViewHolder(parent.toBinding())
        }

    @SuppressLint("ClickableViewAccessibility")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (holder is AllFollowedViewHolder) {
            val itemBinding = holder.binding
            val item = getItem(position) as AllFollowedNormalItem
            val data = item.data
            if (isEdit) {
                itemBinding.ivUpOrDown.goneIf(false)
                itemBinding.ivDrag.goneIf(!item.isTop)
                itemBinding.vNewTips.goneIf(true)
            } else {
                itemBinding.ivUpOrDown.goneIf(true)
                itemBinding.ivDrag.goneIf(true)
                itemBinding.vNewTips.goneIf(!data.isShowTip)
            }
            val editResourceId = if (item.isTop) R.drawable.ic_all_followed_down else R.drawable.ic_all_followed_up
            itemBinding.ivUpOrDown.setImageResource(editResourceId)
            itemBinding.tvName.text = data.name
            if (data.isUser) {
                itemBinding.ivUserIcon.goneIf(false) {
                    itemBinding.ivUserIcon.displayGameIcon(data.icon, null)
                }
                itemBinding.ivGameIcon.goneIf(true)
            } else {
                itemBinding.ivUserIcon.goneIf(true)
                itemBinding.ivGameIcon.goneIf(false) {
                    itemBinding.ivGameIcon.displayGameIcon(data.icon, null)
                }
            }

            itemBinding.ivUpOrDown.setOnClickListener {
                if (item.isTop) {
                    cancelToTop(data.id)
                } else {
                    toTop(data.id)
                }
            }

            itemBinding.ivDrag.setOnTouchListener { _, event ->
                consume {
                    if (event.action == MotionEvent.ACTION_DOWN) {
                        startDrag(holder)
                    }
                }
            }

            arrayOf(itemBinding.ivGameIcon, itemBinding.ivUserIcon, itemBinding.tvName)
                .forEach {
                    it.setOnClickListener {
                        viewModel.navigateToDetailPage(item)
                    }
                }
        }
    }

    private fun toTop(id: String) {
        if (topItemCount >= itemCount) {
            return
        }

        val newList = arrayListOf<AllFollowedNormalItem>()
        val targetItem = dataList.find { it.data.id == id }
        dataList.forEach {
            if (newList.size == topItemCount && targetItem != null) {
                newList.add(targetItem.copy(isTop = true))
            }
            if (it.data.id != id) {
                newList.add(AllFollowedNormalItem(it.data, it.isTop))
            }
        }
        setData(newList)
    }

    private fun cancelToTop(id: String) {
        if (topItemCount == 0) {
            return
        }
        val newList = arrayListOf<AllFollowedNormalItem>()
        val targetItem = dataList.find { it.data.id == id }
        dataList.forEach {
            if (topItemCount == newList.size && targetItem != null) {
                newList.add(targetItem.copy(isTop = false))
            }
            if (it.data.id != id) {
                newList.add(it.copy())
            }
        }
        setData(newList)
    }

    fun changeToEditable() {
        _isEdit = !isEdit
        notifyItemRangeChanged(0, itemCount, "")
    }

    fun getTopItem() =
        dataList.filter {
            it.isTop
        }.mapIndexed { index, item ->
            FollowOperateTopRequest(item.data.id, index + 1)
        }


    companion object {

        fun createDiffItemCallBack() = object : ItemCallback<AllFollowedItem>() {
            override fun areItemsTheSame(oldItem: AllFollowedItem, newItem: AllFollowedItem): Boolean {
                return oldItem.areItemsTheSame(newItem)
            }

            override fun areContentsTheSame(oldItem: AllFollowedItem, newItem: AllFollowedItem): Boolean {
                return oldItem.areContentsTheSame(newItem)
            }

        }
    }

    class NoTopViewHolder(val binding: RecyclerAllFollowedNoTopBinding) : ViewHolder(binding.root)

    class MyFollowerHeaderViewHolder(val binding: RecyclerAllFollowMyFollowHeaderBinding) : ViewHolder(binding.root)

    class AllFollowedViewHolder(val binding: RecyclerAllFollowedBinding) : ViewHolder(binding.root)
}