package net.pokeranalytics.android.model.realm

import android.content.Context
import io.realm.Realm
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.Criteria
import net.pokeranalytics.android.model.interfaces.Deletable
import net.pokeranalytics.android.model.interfaces.DeleteValidityStatus
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
import net.pokeranalytics.android.util.extensions.findById
import java.util.*


open class ReportSetup : RealmObject(), RowRepresentable, Deletable {

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

    // The name of the report
    var name: String = ""

    // The type of display of the report
    var display: Int = Calculator.Options.Display.TABLE.ordinal

    /**
     * A list of statIds to compute
     * Must contain at least 1
     */
    var statIds: RealmList<Int> = RealmList()

    /**
     * An optional list of criteriaIds to compare statIds
     */
    var criteriaIds: RealmList<Int> = RealmList()

    /**
     * An optional list of custom fields ids to be compared
     */
    var criteriaCustomFieldIds: RealmList<String> = RealmList()

    /**
     * An optional filter to narrow the results
     */
    var filter: Filter? = null

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

    @Ignore
    override val viewType: Int = RowViewType.TITLE_ARROW.ordinal

    /**
     * Returns the Options based on the ReportSetup parameters
     */
    val options: Calculator.Options
        get() {

            val realm = Realm.getDefaultInstance()
            val stats = this.statIds.map { Stat.valueByIdentifier(it) }

            // Comparison criteria
            val criteria = this.criteriaIds.map { Criteria.valueByIdentifier(it) }
            val customFields = this.criteriaCustomFieldIds.mapNotNull { realm.findById<CustomField>(it) }
            val cfCriteria = customFields.map { it.criteria }

            val allCriteria = mutableListOf<Criteria>()
            allCriteria.addAll(criteria)
            allCriteria.addAll(cfCriteria)

            return Calculator.Options(
                display = Calculator.Options.Display.values()[this.display],
                stats = stats,
                criterias = allCriteria,
                filter = this.filter,
                userGenerated = true,
                reportSetupId = this.id
            )
        }

    // Deletable

    override fun isValidForDelete(realm: Realm): Boolean {
        return true
    }

    override fun getFailedDeleteMessage(status: DeleteValidityStatus): Int {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

}
