package com.livingworld.modules.recovery;

/**
 * Ecological succession stages that a region can progress through or regress from.
 *
 * <p>Stages are ordered from most degraded ({@link #BARREN}) to most developed
 * ({@link #MATURE_FOREST}). Advancement requires conditions to meet each stage's
 * thresholds; sustained damage can cause regression.
 */
public enum SuccessionStage {

    /** No significant vegetation; exposed or contaminated soil. */
    BARREN(
            /* minSoilQuality */      0.0,
            /* maxPollutionScore */  100.0,
            /* minVegetationPressure */ 0.0),

    /** Patchy grass cover starting to establish. */
    SPARSE_GRASS(
            10.0,
            80.0,
            10.0),

    /** Continuous grass cover with scattered herbs. */
    GRASSLAND(
            25.0,
            70.0,
            20.0),

    /** Shrubs and mixed vegetation; beginning of structural complexity. */
    SCRUBLAND(
            40.0,
            60.0,
            35.0),

    /** Young trees intermixed with shrubs; canopy forming. */
    YOUNG_WOODLAND(
            50.0,
            50.0,
            45.0),

    /** Established tree canopy; full ecological complexity. */
    MATURE_FOREST(
            60.0,
            40.0,
            55.0);

    // ------------------------------------------------------------------
    // Stage thresholds
    // ------------------------------------------------------------------

    /** Minimum soilQuality metric required to enter (and stay in) this stage. */
    public final double minSoilQuality;

    /** Maximum pollutionScore metric allowed to enter (and stay in) this stage. */
    public final double maxPollutionScore;

    /** Minimum vegetationPressure metric required to enter (and stay in) this stage. */
    public final double minVegetationPressure;

    SuccessionStage(double minSoilQuality, double maxPollutionScore, double minVegetationPressure) {
        this.minSoilQuality        = minSoilQuality;
        this.maxPollutionScore     = maxPollutionScore;
        this.minVegetationPressure = minVegetationPressure;
    }

    // ------------------------------------------------------------------
    // Navigation
    // ------------------------------------------------------------------

    /** Returns {@code true} if this stage is not {@link #MATURE_FOREST}. */
    public boolean hasNext() {
        return ordinal() < MATURE_FOREST.ordinal();
    }

    /** Returns {@code true} if this stage is not {@link #BARREN}. */
    public boolean hasPrev() {
        return ordinal() > BARREN.ordinal();
    }

    /** Returns the next stage, or this stage if already {@link #MATURE_FOREST}. */
    public SuccessionStage next() {
        return hasNext() ? values()[ordinal() + 1] : this;
    }

    /** Returns the previous stage, or this stage if already {@link #BARREN}. */
    public SuccessionStage prev() {
        return hasPrev() ? values()[ordinal() - 1] : this;
    }

    // ------------------------------------------------------------------
    // Condition checks (based on RegionMetrics)
    // ------------------------------------------------------------------

    /**
     * Returns {@code true} when current ecosystem metrics are good enough for this
     * region to <em>advance</em> to the next succession stage.
     */
    public boolean conditionsMetForAdvancement(
            double soilQuality, double pollutionScore, double vegetationPressure) {
        if (!hasNext()) return false;
        SuccessionStage target = next();
        return soilQuality        >= target.minSoilQuality
            && pollutionScore     <= target.maxPollutionScore
            && vegetationPressure >= target.minVegetationPressure;
    }

    /**
     * Returns {@code true} when current metrics have deteriorated enough to
     * <em>regress</em> to the previous succession stage.
     *
     * <p>Regression threshold is set tighter than advancement (conditions must be
     * significantly worse than the current stage's minimums).
     */
    public boolean conditionsMissedForRegression(
            double soilQuality, double pollutionScore, double vegetationPressure) {
        if (!hasPrev()) return false;
        return soilQuality        < minSoilQuality * 0.5
            || pollutionScore     > maxPollutionScore * 1.2
            || vegetationPressure < minVegetationPressure * 0.5;
    }
}
