package uz.mobiuz.mobiservice.dev.ui.sdk.card

import androidx.recyclerview.widget.DiffUtil
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
import uz.agr.mobiuz.ui.card.select.CardDelegate
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.coreui.ui.list.ProgressAdapterDelegate
import uz.agr.sdk.coreui.ui.list.ProgressItem
import uz.mobiuz.mobiservice.dev.utils.extensions.MultiBlock
import uz.mobiuz.mobiservice.dev.utils.extensions.SingleBlock


class CardsListAdapter(
    hideSettingsIcon: (Boolean),
    clickListener: (CardInfo, Int) -> Unit
) : ListDelegationAdapter<MutableList<Any>>() {
//    private var listener: MultiBlock<CardInfo,Int>? = null
//
//    fun setOnClickListener(block: MultiBlock<CardInfo,Int>){
//        listener = block
//    }

    init {
        items = mutableListOf()
        delegatesManager.addDelegate(CardDelegate(hideSettingsIcon, clickListener))
        delegatesManager.addDelegate(ProgressAdapterDelegate())
    }

    fun setData(cardsList: List<CardInfo>) {
        val oldData = items.toList()
        val progress = isProgress()

        items.clear()
        items.addAll(cardsList)
        if (progress) items.add(ProgressItem())

        //yes, on main thread...
        DiffUtil
            .calculateDiff(DiffCallback(items, oldData), false)
            .dispatchUpdatesTo(this)
    }

    fun showProgress(isVisible: Boolean) {
        val oldData = items.toList()
        val currentProgress = isProgress()

        if (isVisible && !currentProgress) {
            items.add(ProgressItem())
            notifyItemInserted(items.lastIndex)
        } else if (!isVisible && currentProgress) {
            items.remove(items.last())
            notifyItemRemoved(oldData.lastIndex)
        }
    }

    private fun isProgress() = items.isNotEmpty() && items.last() is ProgressItem

    private inner class DiffCallback(
        private val newItems: List<Any>,
        private val oldItems: List<Any>
    ) : DiffUtil.Callback() {

        override fun getOldListSize() = oldItems.size
        override fun getNewListSize() = newItems.size

        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val oldItem = oldItems[oldItemPosition]
            val newItem = newItems[newItemPosition]

            return if (newItem is CardInfo && oldItem is CardInfo) {
                newItem.id == oldItem.id
            } else {
                newItem is ProgressItem && oldItem is ProgressItem
            }
        }

        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val oldItem = oldItems[oldItemPosition]
            val newItem = newItems[newItemPosition]

            return if (newItem is CardInfo && oldItem is CardInfo) {
                newItem.status == oldItem.status
                        && newItem.balance == oldItem.balance
            } else {
                true
            }
        }
    }
}