using Theriapolis.Core.World.Generation.Stages;

namespace Theriapolis.Core.World.Generation;

/// <summary>
/// Runs the ordered world-generation pipeline.
/// Stages 1–8 are implemented for Phase 1. The remaining stubs are placeholders
/// that will be filled in Phase 2 onward.
/// </summary>
public static class WorldGenerator
{
    /// <summary>Ordered pipeline. Index matches the spec's stage numbering (0-based list).</summary>
    public static IWorldGenStage[] BuildPipeline() => new IWorldGenStage[]
    {
        new SeedInitStage(),              // 1
        new MacroTemplateLoadStage(),     // 2
        new ElevationGenStage(),          // 3
        new MoistureGenStage(),           // 4
        new TemperatureGenStage(),        // 5
        new CoastalFeatureGenStage(),     // 6
        new BorderDistortionGenStage(),   // 7
        new WaterBodyClampStage(),        // 8
        new BiomeAssignStage(),           // 9
        new HydrologyGenStage(),          // 10
        new RiverMeanderGenStage(),       // 11
        new HabitabilityScoreStage(),     // 12
        new NarrativeAnchorPlaceStage(),  // 13
        new SettlementPlaceStage(),       // 14
        new SettlementAttributesStage(),  // 15
        new RailNetworkGenStage(),        // 16
        new RoadNetworkGenStage(),        // 17
        new PolylineCleanupStage(),       // 18
        new TradeRouteGenStage(),         // 19
        new FactionInfluenceGenStage(),   // 20
        new PoIPlacementStage(),          // 21
        new EncounterDensityGenStage(),   // 22
        new ValidationPassStage(),        // 23
    };

    /// <summary>
    /// Run all pipeline stages, reporting progress via ctx.ProgressCallback.
    /// </summary>
    public static void RunAll(WorldGenContext ctx)
    {
        var stages = BuildPipeline();
        for (int i = 0; i < stages.Length; i++)
        {
            ctx.LogMessage($"[WorldGen] Stage {i + 1}/{stages.Length}: {stages[i].Name}");
            stages[i].Run(ctx);
            ctx.ReportProgress(stages[i].Name, (i + 1f) / stages.Length);
        }
        ctx.LogMessage("[WorldGen] Pipeline complete.");
    }

    /// <summary>
    /// Run only stages 1–N (0-based index), used by tools and tests.
    /// </summary>
    public static void RunThrough(WorldGenContext ctx, int lastStageIndex)
    {
        var stages = BuildPipeline();
        int limit = Math.Min(lastStageIndex + 1, stages.Length);
        for (int i = 0; i < limit; i++)
        {
            stages[i].Run(ctx);
            ctx.ReportProgress(stages[i].Name, (i + 1f) / limit);
        }
    }
}
