package net.pokeranalytics.android.model.realm

import android.content.Context
import io.realm.Realm
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.kotlin.where
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.interfaces.CountableUsage
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.SaveValidityStatus
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.rowrepresentable.GameRow
import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow
import net.pokeranalytics.android.util.NULL_TEXT
import java.util.*
import kotlin.collections.ArrayList

open class Game : RealmObject(), NameManageable, StaticRowRepresentableDataSource, RowRepresentable, CountableUsage {

	companion object {
		val rowRepresentation : List<RowRepresentable> by lazy {
			val rows = ArrayList<RowRepresentable>()
			rows.add(SimpleRow.NAME)
//			rows.addAll(GameRow.values())
			rows
		}
	}

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

	// The name of the game
	override var name: String = ""

	// A shorter name for the game
	var shortName: String? = null

	// CountableUsage
	override var useCount: Int = 0

	fun getNotNullShortName() : String {
		this.shortName?.let {
			return it
		}
		return this.name
	}

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

	override fun adapterRows(): List<RowRepresentable>? {
		return Game.rowRepresentation
	}

	override fun stringForRow(row: RowRepresentable): String {
		return when (row) {
			SimpleRow.NAME -> if (this.name.isNotEmpty()) this.name else NULL_TEXT
			GameRow.SHORT_NAME -> this.shortName ?: NULL_TEXT
			else -> return super.stringForRow(row)
		}
	}

	override fun editDescriptors(row: RowRepresentable): ArrayList<RowRepresentableEditDescriptor>? {
		return when (row) {
			SimpleRow.NAME -> row.editingDescriptors(mapOf("defaultValue" to this.name))
			GameRow.SHORT_NAME -> row.editingDescriptors(mapOf("defaultValue" to this.shortName))
			else -> null
		}
	}

	override fun updateValue(value: Any?, row: RowRepresentable) {
		when (row) {
			SimpleRow.NAME -> this.name = value as String? ?: ""
			GameRow.SHORT_NAME -> this.shortName = value as String? ?: ""
		}
	}

	override fun isValidForSave(): Boolean {
		return name.isNotEmpty()
	}

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

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