package com.livingworld.modules.ecosystem;

/**
 * Per-region ecosystem summary state tracked by {@link EcosystemModule}.
 *
 * <p>These values integrate signals from all other ecosystem modules to represent
 * the overall ecological condition of a region. All values are clamped to [0, 100].
 *
 * <ul>
 *   <li><b>ecosystemHealth</b> – weighted composite of soil, water, pollution and vegetation
 *   <li><b>stress</b>          – accumulated ecological stress; rises when multiple metrics
 *                                are in danger zones, recovers slowly in good conditions
 *   <li><b>resilience</b>      – long-term stability; high resilience means the region
 *                                resists and recovers from damage more quickly
 *   <li><b>recoveryRate</b>    – current rate of ecological self-repair per tick
 * </ul>
 */
public final class EcosystemRegionData {

    private static final double MIN = 0.0;
    private static final double MAX = 100.0;

    private double ecosystemHealth;
    private double stress;
    private double resilience;
    private double recoveryRate;

    public EcosystemRegionData(
            double ecosystemHealth,
            double stress,
            double resilience,
            double recoveryRate) {
        this.ecosystemHealth = clamp(ecosystemHealth);
        this.stress          = clamp(stress);
        this.resilience      = clamp(resilience);
        this.recoveryRate    = clamp(recoveryRate);
    }

    /** Returns a default moderate-health ecosystem state. */
    public static EcosystemRegionData defaults() {
        return new EcosystemRegionData(60.0, 20.0, 50.0, 5.0);
    }

    // ------------------------------------------------------------------
    // Getters
    // ------------------------------------------------------------------

    public double getEcosystemHealth() { return ecosystemHealth; }
    public double getStress()          { return stress; }
    public double getResilience()      { return resilience; }
    public double getRecoveryRate()    { return recoveryRate; }

    // ------------------------------------------------------------------
    // Mutation
    // ------------------------------------------------------------------

    /**
     * Records an ecological stress event of the given magnitude.
     *
     * <p>Stress accumulates and slowly erodes resilience.
     *
     * @param amount positive stress magnitude
     */
    public void applyStress(double amount) {
        if (amount < 0) throw new IllegalArgumentException("amount must be >= 0");
        stress     = clamp(stress     + amount);
        resilience = clamp(resilience - amount * 0.1);
    }

    /**
     * Records an ecological recovery event of the given magnitude.
     *
     * <p>Reduces stress and gradually rebuilds resilience.
     *
     * @param amount positive recovery magnitude
     */
    public void applyRecovery(double amount) {
        if (amount < 0) throw new IllegalArgumentException("amount must be >= 0");
        stress     = clamp(stress     - amount);
        resilience = clamp(resilience + amount * 0.05);
    }

    public void setEcosystemHealth(double v) { ecosystemHealth = clamp(v); }
    public void setStress(double v)          { stress          = clamp(v); }
    public void setResilience(double v)      { resilience      = clamp(v); }
    public void setRecoveryRate(double v)    { recoveryRate    = clamp(v); }

    /** Clamps all fields to [0, 100]. */
    public void normalize() {
        ecosystemHealth = clamp(ecosystemHealth);
        stress          = clamp(stress);
        resilience      = clamp(resilience);
        recoveryRate    = clamp(recoveryRate);
    }

    /** Returns an independent copy. */
    public EcosystemRegionData copy() {
        return new EcosystemRegionData(ecosystemHealth, stress, resilience, recoveryRate);
    }

    // ------------------------------------------------------------------

    private static double clamp(double v) {
        return Math.min(MAX, Math.max(MIN, v));
    }

    @Override
    public String toString() {
        return "EcosystemRegionData{"
                + "health=" + ecosystemHealth
                + ", stress=" + stress
                + ", resilience=" + resilience
                + ", recoveryRate=" + recoveryRate + "}";
    }
}
