package theorycrafter.fitting

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import eve.data.Attribute
import eve.data.Attributes
import eve.data.EffectReferences
import eve.data.EveItemType

/**
 * An instance of an eve item, based on an [EveItemType].
 */
sealed class EveItem<out T: EveItemType>(


    /**
     * The context [Attributes].
     */
    protected val attributes: Attributes,


    /**
     * The type of which this item is an instance of.
     */
    val type: T


) {


    /**
     * The item's name.
     */
    val name: String by type::name


    /**
     * The item's properties.
     */
    @Suppress("LeakingThis")
    internal val properties = Properties(this, attributes, type.attributeValues)


    /**
     * Returns the [AttributeProperty] of this item corresponding to the given attribute.
     * The property must exist.
     */
    fun <T: Any> property(attribute: Attribute<T>): AttributeProperty<T> = properties.get(attribute)


    /**
     * Returns the [AttributeProperty] of this item corresponding to the given attribute, or `null` if it has no such
     * property.
     */
    fun <T: Any> propertyOrNull(attribute: Attribute<T>): AttributeProperty<T>? =
        properties.getOrNull(attribute)


    /**
     * The item's effects.
     */
    internal val effectReferences: EffectReferences by type::effectReferences


    /**
     * A short explanation of the reason this item is not legally fitted.
     * `null` if the item is legally fitted.
     */
    var illegalFittingReason: String? by mutableStateOf(null)
        internal set


    /**
     * Whether the item is legally fit on its [Fit].
     */
    val isLegallyFitted: Boolean
        get() = illegalFittingReason == null


    /**
     * The effects this item has on other items.
     */
    var appliedEffects: List<AppliedEffect> by mutableStateOf(emptyList())
        internal set


    override fun toString() = "$name (${this.javaClass.simpleName})"


}