package com.livingworld.platform.neoforge;

import com.livingworld.config.EcosystemTuning;
import net.neoforged.neoforge.common.ModConfigSpec;

/**
 * NeoForge server-side TOML configuration for the Living World ecosystem simulation.
 *
 * <p>Registered via {@link net.neoforged.fml.ModContainer#registerConfig} with type
 * {@link net.neoforged.fml.config.ModConfig.Type#SERVER}. The resulting file is written to
 * {@code saves/<world>/serverconfig/livingworld-server.toml} and can be edited by
 * server admins to tune all ecosystem rates without recompiling.
 *
 * <p>Call {@link #createTuning()} after the server config has loaded (i.e. from
 * {@link net.neoforged.neoforge.event.server.ServerStartingEvent}) to obtain an
 * {@link EcosystemTuning} populated with the current config values.
 */
public final class NeoForgeModConfig {

    public static final ModConfigSpec SPEC;

    // -- pollution --
    private static final ModConfigSpec.DoubleValue POLLUTION_DECAY_RATE;
    private static final ModConfigSpec.DoubleValue GROUND_TO_WATER_LEACH;
    private static final ModConfigSpec.DoubleValue POLLUTION_SPREAD_RATE;
    private static final ModConfigSpec.DoubleValue WIND_BOOST;

    // -- vegetation growth --
    private static final ModConfigSpec.DoubleValue GRASS_GROWTH_RATE;
    private static final ModConfigSpec.DoubleValue FLOWER_GROWTH_RATE;
    private static final ModConfigSpec.DoubleValue SHRUB_GROWTH_RATE;
    private static final ModConfigSpec.DoubleValue TREE_GROWTH_RATE;

    // -- vegetation die-off --
    private static final ModConfigSpec.DoubleValue GRASS_DIEOFF_RATE;
    private static final ModConfigSpec.DoubleValue FLOWER_DIEOFF_RATE;
    private static final ModConfigSpec.DoubleValue SHRUB_DIEOFF_RATE;
    private static final ModConfigSpec.DoubleValue TREE_DIEOFF_RATE;

    // -- recovery succession --
    private static final ModConfigSpec.DoubleValue BASE_PROGRESS_PER_TICK;
    private static final ModConfigSpec.DoubleValue DAMAGE_PER_BAD_TICK;
    private static final ModConfigSpec.DoubleValue DAMAGE_DECAY_RATE;

    // -- seed dispersal --
    private static final ModConfigSpec.DoubleValue SEED_EMISSION_RATE;
    private static final ModConfigSpec.DoubleValue CORRIDOR_BOOST_MULTIPLIER;
    private static final ModConfigSpec.DoubleValue SEED_POLLUTION_BLOCK;

    static {
        ModConfigSpec.Builder b = new ModConfigSpec.Builder();

        b.comment("Pollution dynamics").push("pollution");
        POLLUTION_DECAY_RATE = b
            .comment("Fraction of pollution removed per tick. Lower = stickier pollution. Default: 0.002")
            .defineInRange("decay_rate", 0.002, 0.0001, 0.5);
        GROUND_TO_WATER_LEACH = b
            .comment("Fraction of ground pollution that leaches into water each tick. Default: 0.005")
            .defineInRange("ground_to_water_leach", 0.005, 0.0, 0.1);
        POLLUTION_SPREAD_RATE = b
            .comment("Base rate at which air pollution diffuses to adjacent regions. Default: 0.02")
            .defineInRange("spread_rate", 0.02, 0.0, 0.5);
        WIND_BOOST = b
            .comment("Downwind spread multiplier (0 = no wind bias, 2 = strong directional drift). Default: 0.5")
            .defineInRange("wind_boost", 0.5, 0.0, 2.0);
        b.pop();

        b.comment("Vegetation growth rates (per soil-quality unit above threshold per tick)").push("vegetation");
        GRASS_GROWTH_RATE  = b.comment("Grass growth rate. Default: 0.06")
                              .defineInRange("grass_growth",  0.06,  0.001, 2.0);
        FLOWER_GROWTH_RATE = b.comment("Flower growth rate. Default: 0.03")
                              .defineInRange("flower_growth", 0.03,  0.001, 2.0);
        SHRUB_GROWTH_RATE  = b.comment("Shrub growth rate. Default: 0.02")
                              .defineInRange("shrub_growth",  0.02,  0.001, 2.0);
        TREE_GROWTH_RATE   = b.comment("Tree growth rate. Default: 0.008")
                              .defineInRange("tree_growth",   0.008, 0.001, 2.0);
        GRASS_DIEOFF_RATE  = b.comment("Grass die-off flat reduction per bad tick. Default: 1.0")
                              .defineInRange("grass_dieoff",  1.0,  0.0, 20.0);
        FLOWER_DIEOFF_RATE = b.comment("Flower die-off per bad tick. Default: 0.5")
                              .defineInRange("flower_dieoff", 0.5,  0.0, 20.0);
        SHRUB_DIEOFF_RATE  = b.comment("Shrub die-off per bad tick. Default: 0.25")
                              .defineInRange("shrub_dieoff",  0.25, 0.0, 20.0);
        TREE_DIEOFF_RATE   = b.comment("Tree die-off per bad tick (only under severe conditions). Default: 0.1")
                              .defineInRange("tree_dieoff",   0.1,  0.0, 20.0);
        b.pop();

        b.comment("Ecological succession and recovery").push("recovery");
        BASE_PROGRESS_PER_TICK = b
            .comment("Recovery progress added per tick under good conditions. Default: 2.0")
            .defineInRange("base_progress_per_tick", 2.0, 0.1, 50.0);
        DAMAGE_PER_BAD_TICK = b
            .comment("Ecological damage accumulated per tick under bad conditions. Default: 5.0")
            .defineInRange("damage_per_bad_tick", 5.0, 0.1, 100.0);
        DAMAGE_DECAY_RATE = b
            .comment("Fraction of accumulated damage that decays per tick when conditions are OK. Default: 0.03")
            .defineInRange("damage_decay_rate", 0.03, 0.001, 0.5);
        b.pop();

        b.comment("Seed dispersal and ecological corridors").push("seed_dispersal");
        SEED_EMISSION_RATE = b
            .comment("Fraction of vegetation pressure emitted as seeds to each neighbour per tick (requires YOUNG_WOODLAND+). Default: 0.01")
            .defineInRange("emission_rate", 0.01, 0.0, 0.5);
        CORRIDOR_BOOST_MULTIPLIER = b
            .comment("Seed strength multiplier when the target region has 2+ healthy neighbours — the corridor effect. Default: 3.5")
            .defineInRange("corridor_boost", 3.5, 1.0, 20.0);
        SEED_POLLUTION_BLOCK = b
            .comment("Fraction of incoming seeds blocked per unit of pollution score in the target region. Default: 0.015")
            .defineInRange("pollution_block", 0.015, 0.0, 0.1);
        b.pop();

        SPEC = b.build();
    }

    private NeoForgeModConfig() {}

    /** Creates an {@link EcosystemTuning} populated from the currently loaded config values. */
    public static EcosystemTuning createTuning() {
        EcosystemTuning t = new EcosystemTuning();
        t.setPollutionDecayRate(POLLUTION_DECAY_RATE.get());
        t.setGroundToWaterLeach(GROUND_TO_WATER_LEACH.get());
        t.setPollutionSpreadRate(POLLUTION_SPREAD_RATE.get());
        t.setWindBoost(WIND_BOOST.get());
        t.setGrassGrowthRate(GRASS_GROWTH_RATE.get());
        t.setFlowerGrowthRate(FLOWER_GROWTH_RATE.get());
        t.setShrubGrowthRate(SHRUB_GROWTH_RATE.get());
        t.setTreeGrowthRate(TREE_GROWTH_RATE.get());
        t.setGrassDieoffRate(GRASS_DIEOFF_RATE.get());
        t.setFlowerDieoffRate(FLOWER_DIEOFF_RATE.get());
        t.setShrubDieoffRate(SHRUB_DIEOFF_RATE.get());
        t.setTreeDieoffRate(TREE_DIEOFF_RATE.get());
        t.setBaseProgressPerTick(BASE_PROGRESS_PER_TICK.get());
        t.setDamagePerBadTick(DAMAGE_PER_BAD_TICK.get());
        t.setDamageDecayRate(DAMAGE_DECAY_RATE.get());
        t.setSeedEmissionRate(SEED_EMISSION_RATE.get());
        t.setCorridorBoostMultiplier(CORRIDOR_BOOST_MULTIPLIER.get());
        t.setSeedPollutionBlock(SEED_POLLUTION_BLOCK.get());
        return t;
    }
}
