using Theriapolis.Core.Data;

namespace Theriapolis.Core.World.Generation.Stages;

/// <summary>
/// Stage 2 — MacroTemplateLoad
/// Reads macro_template.json and Content/Data/biomes.json.
/// Populates ctx.World.MacroGrid and ctx.World.BiomeDefs.
/// Also stamps macro cell coordinates onto every tile.
/// </summary>
public sealed class MacroTemplateLoadStage : IWorldGenStage
{
    public string Name => "MacroTemplateLoad";

    public void Run(WorldGenContext ctx)
    {
        var loader = new ContentLoader(ctx.DataDirectory);

        var template = loader.LoadMacroTemplate();
        ctx.World.MacroGrid = template.Build();

        ctx.World.BiomeDefs   = loader.LoadBiomes();
        ctx.World.FactionDefs = loader.LoadFactions();

        // Stamp macro cell coordinates onto all tiles (used later for constraints)
        int cellW = C.WORLD_WIDTH_TILES  / C.MACRO_GRID_WIDTH;
        int cellH = C.WORLD_HEIGHT_TILES / C.MACRO_GRID_HEIGHT;

        for (int ty = 0; ty < C.WORLD_HEIGHT_TILES; ty++)
        {
            int my = ty / cellH;
            for (int tx = 0; tx < C.WORLD_WIDTH_TILES; tx++)
            {
                int mx = tx / cellW;
                ctx.World.Tiles[tx, ty].MacroX = (byte)Math.Min(mx, C.MACRO_GRID_WIDTH  - 1);
                ctx.World.Tiles[tx, ty].MacroY = (byte)Math.Min(my, C.MACRO_GRID_HEIGHT - 1);
            }
        }

        // Hash: XOR of all biome-type string hashes from the macro grid
        ulong hash = 0;
        for (int y = 0; y < C.MACRO_GRID_HEIGHT; y++)
            for (int x = 0; x < C.MACRO_GRID_WIDTH; x++)
                hash ^= (ulong)ctx.World.MacroGrid[x, y].BiomeType.GetHashCode();

        ctx.World.StageHashes["MacroTemplateLoad"] = hash;
        ctx.LogMessage($"[MacroTemplateLoad] Loaded {C.MACRO_GRID_WIDTH}×{C.MACRO_GRID_HEIGHT} macro cells, {ctx.World.BiomeDefs.Length} biome defs.");
    }
}
