package net.pokeranalytics.android.ui.adapter

import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import net.pokeranalytics.android.ui.view.BindableHolder
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType

interface RowRepresentableDelegate {
	fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean = false) {}
	fun onRowValueChanged(value: Any?, row: RowRepresentable) {}
	fun onRowDeleted(row: RowRepresentable) {}
}

/**
 * An adapter capable of displaying a list of RowRepresentables
 * @param dataSource the datasource providing rows
 * @param delegate the delegate, notified of UI actions
 */
class RowRepresentableAdapter(
    var dataSource: RowRepresentableDataSource,
    var delegate: RowRepresentableDelegate? = null
) :
	RecyclerView.Adapter<RecyclerView.ViewHolder>() {

	override fun getItemViewType(position: Int): Int {
		return this.dataSource.viewTypeForPosition(position)
	}

	override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
		val rowViewType: RowViewType = RowViewType.values()[viewType]
		return rowViewType.viewHolder(parent)
	}

	override fun getItemCount(): Int {
		return this.dataSource.numberOfRows()
	}

	override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
		this.dataSource.rowRepresentableForPosition(position)?.let {
			(holder as BindableHolder).bind(position, it, this)
		}
	}

	/**
	 * Refresh the row in the adapter
	 */
	fun refreshRow(row: RowRepresentable) {

		if (row.viewType == RowViewType.TITLE_SWITCH.ordinal ||
				row.viewType == RowViewType.LIST.ordinal) {
			// Avoid to refresh the view because it will refresh itself
			// Caution if we want to update the titleResId for example
			return
		}

		val rows = this.dataSource.adapterRows()
		val index = rows?.indexOf(row) ?: -1
		if (index >= 0) {
			notifyItemChanged(index)
		}

		//notifyDataSetChanged()
	}

	/**
	 * Update UI
	 */
	fun updateRows(diffResult: DiffUtil.DiffResult) {
		diffResult.dispatchUpdatesTo(this)
	}

}