package net.pokeranalytics.android.model

import io.realm.Realm
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.Sort
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.*
import net.pokeranalytics.android.ui.adapter.components.LiveDataDataSource
import net.pokeranalytics.android.ui.view.Localizable

/**
 * An interface to easily handle the validity of any object we want to save
 */
interface ObjectSavable {
	fun isValidForSave(): Boolean {
		return true
	}
}

/**
 * An enum managing the business objects related to a realm results
 */
enum class LiveData : Localizable {
	BANKROLL,
	GAME,
	LOCATION,
	TOURNAMENT_FEATURE,
	TRANSACTION_TYPE;

	fun items(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): RealmResults<*> {
		return realm.where(this.relatedEntity).findAll()
			.sort(fieldName ?: this.sortingFieldName, sortOrder ?: this.sorting)
	}

	/**
	 * Return a copy of a RealmResults
	 */
	fun itemsArray(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): ArrayList<*> {
		val results: ArrayList<Any> = ArrayList()
		results.addAll(
			realm.copyFromRealm(
				realm.where(this.relatedEntity).findAll().sort(
					fieldName ?: this.sortingFieldName, sortOrder ?: this.sorting
				)
			)
		)

		return results
	}

	private var sortingFieldName: String = "name"
	private var sorting: Sort = Sort.ASCENDING


	private val relatedEntity: Class<out RealmObject>
		get() {
			return when (this) {
				BANKROLL -> Bankroll::class.java
				GAME -> Game::class.java
				LOCATION -> Location::class.java
				TOURNAMENT_FEATURE -> TournamentFeature::class.java
				TRANSACTION_TYPE -> TransactionType::class.java
			}
		}

    fun deleteData(realm:Realm, data:LiveDataDataSource) {
        realm.where(this.relatedEntity).equalTo("id", data.primaryKey).findAll().deleteAllFromRealm()
    }

    fun updateOrCreate(realm:Realm, primaryKey:String?): RealmObject {
		val proxyItem: RealmObject? = this.getData(realm, primaryKey)
		proxyItem?.let {
			return proxyItem
		} ?: run {
			return this.newEntity()
		}
	}

	fun newEntity(): RealmObject {
		return when (this) {
			BANKROLL -> Bankroll()
			GAME -> Game()
			LOCATION -> Location()
			TOURNAMENT_FEATURE -> TournamentFeature()
			TRANSACTION_TYPE -> TransactionType()
		}
	}

	fun getData(realm: Realm, primaryKey: String?): RealmObject? {
		var proxyItem: RealmObject? = null
		primaryKey?.let {
			val t = realm.where(this.relatedEntity).equalTo("id", it).findFirst()
			t?.let {
				proxyItem = t
			}
		}
		return proxyItem
	}

	override val resId: Int?
		get() {
			return when (this) {
				BANKROLL -> R.string.bankroll
				GAME -> R.string.game
				LOCATION -> R.string.location
				TOURNAMENT_FEATURE -> R.string.tournament_type
				TRANSACTION_TYPE -> R.string.operation_types
			}
		}
}

/*
interface ListableDataSource {
    fun items(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): RealmResults<*>
    var sortingFieldName: String
    var sorting: Sort
    var relatedEntity: Class < out RealmObject >
}
*/