package net.pokeranalytics.android.model.realm

import android.content.Context
import io.realm.Realm
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import java.util.*

open class Bankroll : RealmObject(), NameManageable, RowRepresentable {

	@PrimaryKey
	override var id = UUID.randomUUID().toString()

	override var name: String = ""

	// Indicates whether the bankroll is live or online
	var live: Boolean = true

	/**
	 * The list of transactions of the bankroll
	 */
	@LinkingObjects("bankroll")
	val transactions: RealmResults<Transaction>? = null

	// The currency of the bankroll
	var currency: Currency? = null

	// The initial value of the bankroll
	var initialValue: Double = 0.0

	val rate: Double
		get() {
			return this.currency?.rate ?: 1.0
		}

	override fun getDisplayName(context: Context): String {
		return this.name
	}

	override fun updateValue(value: Any?, row: RowRepresentable) {
		when (row) {
			SimpleRow.NAME -> this.name = value as String? ?: ""
			BankrollRow.LIVE -> {
				this.live = if (value is Boolean) !value else false
			}
			BankrollRow.INITIAL_VALUE -> {
				this.initialValue = value as Double? ?: 0.0
			}
			BankrollRow.CURRENCY -> {
				//TODO handle a use default currency option
				this.currency?.code = value as String?
			}
			BankrollRow.RATE -> {
				this.currency?.rate = value as Double?
			}
		}
	}

	override fun isValidForDelete(realm: Realm): Boolean {
		return realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()
				&& realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()
	}

	override fun getDeleteStatus(context: Context, realm: Realm): DeleteValidityStatus {
		return if (!realm.where<Session>().equalTo("bankroll.id", id).findAll().isEmpty()) {
			DeleteValidityStatus.SESSIONS_LINKED
		} else if (!realm.where<Transaction>().equalTo("bankroll.id", id).findAll().isEmpty()) {
			DeleteValidityStatus.TRANSACTIONS_LINKED
		} else {
			DeleteValidityStatus.VALID
		}
	}

	override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
		return when (status) {
			DeleteValidityStatus.SESSIONS_LINKED -> R.string.bankroll_relationship_error
			DeleteValidityStatus.TRANSACTIONS_LINKED -> R.string.bankroll_relationship_error_transactions
			else -> super.getFailedDeleteMessage(status)
		}
	}

	override fun getFailedSaveMessage(status: SaveValidityStatus): Int {
		return when (status) {
			SaveValidityStatus.DATA_INVALID -> R.string.empty_name_for_br_error
			SaveValidityStatus.ALREADY_EXISTS -> R.string.duplicate_bankroll_name_error
			else -> super.getFailedSaveMessage(status)
		}
	}

	companion object {

		fun getOrCreate(realm: Realm, name: String, live: Boolean = true, currencyCode: String? = null, currencyRate: Double? = null) : Bankroll {

			val br = realm.where<Bankroll>().equalTo("name", name).findFirst()
			return if (br != null) {
				br
			} else {
				val bankroll = Bankroll()
				bankroll.name = name
				bankroll.live = live
				val currency = Currency()
				currency.code = currencyCode
				currency.rate = currencyRate
				bankroll.currency = currency
				realm.copyToRealm(bankroll)
			}
		}

	}

}