package net.pokeranalytics.android.ui.fragment

import android.app.Activity
import android.content.Context
import android.content.Intent
import io.realm.RealmResults
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.activity.EditableDataActivity
import net.pokeranalytics.android.ui.activity.FiltersActivity
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetFragment
import net.pokeranalytics.android.ui.interfaces.FilterHandler.Companion.INTENT_FILTER_UPDATE_FILTER_UI
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.Preferences
import timber.log.Timber


open class FiltersListFragment : DataListFragment() {

	private var identifiableClass: Class<out Deletable> = Filter::class.java
	private var dataType: LiveData = LiveData.FILTER
	private lateinit var items: RealmResults<Filter>

	/**
	 * Set fragment data
	 */
	override fun setData(dataType: Int) {
		super.setData(dataType)

		this.dataType = LiveData.FILTER
		this.identifiableClass = Filter::class.java
		setToolbarTitle(this.dataType.pluralLocalizedTitle(requireContext()))
		this.items = this.retrieveItems(getRealm()) as RealmResults<Filter>
	}

	override fun rowRepresentableForPosition(position: Int): RowRepresentable? {
		Timber.d("rowRepresentableForPosition: ${this.items[position] as RowRepresentable}")
		return this.items[position] as RowRepresentable
	}

	override fun numberOfRows(): Int {
		return this.items.size
	}

	override fun adapterRows(): List<RowRepresentable>? {
		return items
	}

	override fun viewTypeForPosition(position: Int): Int {
		val viewType = (this.items[position] as RowRepresentable).viewType
		return if (viewType != -1) viewType else RowViewType.DATA.ordinal
	}

	override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor>? {
		return when (row) {
			is Filter -> row.editingDescriptors(mapOf("defaultValue" to row.name))
			else -> super.editDescriptors(row)
		}
	}

	override fun onRowValueChanged(value: Any?, row: RowRepresentable) {
		when (row) {
			is Filter -> {
				row.updateValue(value, row)
				dataListAdapter.refreshRow(row)
				updateFilterUIIfNecessary(requireContext(), row.id)
			}
			else -> super.onRowValueChanged(value, row)
		}
	}

	override fun onRowDeleted(row: RowRepresentable) {
		when (row) {
			is Filter -> {
				val filterId = row.id
				deleteItem(dataListAdapter, items, filterId)
				if (filterId == Preferences.getActiveFilterId(requireContext())) {
					Preferences.setActiveFilterId("", requireContext())
					updateFilterUIIfNecessary(requireContext(), "")
				}
			}
			else -> super.onRowDeleted(row)
		}
	}

	override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) {
		when (row) {
			is Filter -> {
				if (fromAction) {
					val data = row.editingDescriptors(mapOf("defaultValue" to row.name))
					BottomSheetFragment.create(fragmentManager, row, this, data, false, isDeletable = true, valueHasPlaceholder = false)
				} else {
					val intent = Intent()
					intent.putExtra(FiltersActivity.IntentKey.FILTER_ID.keyName, row.id)
					activity?.setResult(Activity.RESULT_OK, intent)
					activity?.finish()
				}
			}
			else -> {
				val identifier = (row as Identifiable).id
				EditableDataActivity.newInstanceForResult(this, this.dataType, identifier, REQUEST_CODE_DETAILS)
			}
		}
	}

	/**
	 * Update filter UI
	 */
	fun updateFilterUIIfNecessary(context: Context, filterId: String) {
		if (filterId == Preferences.getActiveFilterId(context)) {
			// Send broadcast
			val intent = Intent()
			intent.action = INTENT_FILTER_UPDATE_FILTER_UI
			context.sendBroadcast(intent)
		}
	}

}