package theorycrafter.fitting

import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue


/**
 * A fit affecting another fit.
 *
 * This basically just groups the affecting fit, affected fit, and an `enabled` state.
 */
@Stable
open class RemoteEffect internal constructor(


    /**
    * The affected fit on which the effects are applied.
     */
    val target: Fit,


    /**
     * The affecting fit.
     */
    val source: Fit


): FitItemWithEnabledState {


    override val fit: Fit
        get() = target


    override val enabledState = EnabledState()


    /**
     * The modules of the [source] fit that are affecting the [target] fit.
     */
    var affectingModules: Set<Module> by mutableStateOf(emptySet())
        internal set


    /**
     * The drones of the [source] fit that are affecting the [target] fit.
     */
    var affectingDrones: Set<DroneGroup> by mutableStateOf(emptySet())
        internal set


    override fun toString() = "Affecting fit of $source on $target"


    // Implement equals like this so that we don't accidentally implement it differently later.
    // It must be based on identity because two different remote effects can exist between the same two fits. For
    // example, one can be an offensive effect and the other an assistive effect. FittingEngine uses RemoteEffects as
    // keys in a map, so we must not say two remote effects like that are equal.
    override fun equals(other: Any?): Boolean {
        return this === other
    }


    override fun hashCode(): Int {
        return System.identityHashCode(this)
    }


}


/**
 * The effect of a module on a fit.
 */
@Stable
class ModuleEffect(
    val target: Fit,
    val module: Module,
)


/**
 * The effect of a drone group on a fit.
 */
@Stable
class DroneEffect(
    val target: Fit,
    val droneGroup: DroneGroup,
)