package mtp.polymer.com.autowidget.adapter

import android.content.Context
import android.view.ViewGroup
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.entity.MultiItemEntity
import org.jetbrains.anko.matchParent
import org.jetbrains.anko.wrapContent


interface BaseAdapterDelegate<DATA> {

    fun notifyDataChange(data: DATA, equalsFunc: ((origin: DATA, replace: DATA) -> Boolean))

    fun getDataCount(): Int

}

interface MultiItem : MultiItemEntity

open class BaseAdapter<DATA, VIEW_HOLDER : BaseViewHolder<DATA>?>(
        protected open val onCreateViewHolder: ((context: Context, itemType: Int) -> VIEW_HOLDER)? = null
) : BaseQuickAdapter<DATA, VIEW_HOLDER>(mutableListOf()), BaseAdapterDelegate<DATA> {

    override fun getDataCount(): Int = data.size

    override fun convert(helper: VIEW_HOLDER, item: DATA) {
        helper?.dataCount = getDataCount()
        helper?.dataIndex = data.indexOf(item)
        helper?.data?.value = item
    }

    final override fun onCreateDefViewHolder(parent: ViewGroup, viewType: Int): VIEW_HOLDER {
        return (onCreateViewHolder?.invoke(parent.context, viewType) ?: super.onCreateDefViewHolder(parent, viewType)).apply {
            this!!.createContent()
            itemView.layoutParams = ViewGroup.LayoutParams(itemSize.getOrNull(0) ?: matchParent, itemSize.getOrNull(1) ?: wrapContent)
        }
    }

    final override fun notifyDataChange(data: DATA, equalsFunc: (origin: DATA, replace: DATA) -> Boolean) {
        notify(data, equalsFunc)
    }

}

open class BaseMultiAdapter<DATA : MultiItemEntity, VIEW_HOLDER : BaseViewHolder<DATA>?>(
        protected open val createVHBlock: ((context: Context, itemType: Int) -> VIEW_HOLDER)? = null
) : BaseMultiItemQuickAdapter<DATA, VIEW_HOLDER>(mutableListOf()), BaseAdapterDelegate<DATA> {

    override fun getDataCount(): Int = data.size

    override fun convert(helper: VIEW_HOLDER, item: DATA) {
        helper?.dataCount = getDataCount()
        helper?.dataIndex = data.indexOf(item)
        helper?.data?.value = item
    }

    final override fun onCreateDefViewHolder(parent: ViewGroup, viewType: Int): VIEW_HOLDER {
        return (createVHBlock?.invoke(parent.context, viewType) ?: super.onCreateDefViewHolder(parent, viewType)).apply {
            this!!.createContent()
            itemView.layoutParams = ViewGroup.LayoutParams(itemSize.getOrNull(0) ?: matchParent, itemSize.getOrNull(1) ?: wrapContent)
        }
    }

    final override fun notifyDataChange(data: DATA, equalsFunc: (origin: DATA, replace: DATA) -> Boolean) {
        notify(data, equalsFunc)
    }

}

private fun <DATA> BaseQuickAdapter<DATA, *>.notify(data: DATA, equalsFunc: (origin: DATA, replace: DATA) -> Boolean) {
    getData().indexOfFirst { equalsFunc.invoke(it, data) }
            .takeIf { it >= 0 && it < getData().size }
            ?.apply { getData().removeAt(this) }
            ?.apply { getData().add(this, data) }
            ?.let { notifyItemChanged(it) }
}