namespace ReactorMaintenance.Simulation;

public static class LevelStateFactory
{
    public static LevelState Create(string name, int width, int height)
    {
        if (width < Balancing.Current.MinimumLevelSize || height < Balancing.Current.MinimumLevelSize)
            throw new ArgumentOutOfRangeException(nameof(width), $"Levels must be at least {Balancing.Current.MinimumLevelSize}x{Balancing.Current.MinimumLevelSize}.");

        return new() {
            Name = name,
            Width = width,
            Height = height,
            Terrain = CreateTerrain(width, height),
            Fuel = CreateUnderground(width, height),
            Coolant = CreateUnderground(width, height),
            Electricity = CreateUnderground(width, height),
            Surface = CreateSurface(width, height),
            Props = CreateProps(width, height),
            Robot = new() { Position = new(1, 1) },
            Forecasts = Array.Empty<Forecast>()
        };
    }

    public static ECellTerrain[] CreateTerrain(int width, int height)
    {
        var terrain = Enumerable.Repeat(ECellTerrain.Floor, width * height).ToArray();
        for (var y = 0; y < height; y++)
        {
            for (var x = 0; x < width; x++)
            {
                if (x == 0 || y == 0 || x == width - 1 || y == height - 1)
                    terrain[(y * width) + x] = ECellTerrain.Wall;
            }
        }

        return terrain;
    }

    public static UndergroundCell[] CreateUnderground(int width, int height)
    {
        return Enumerable.Range(0, width * height).Select(_ => new UndergroundCell()).ToArray();
    }

    public static SurfaceState[] CreateSurface(int width, int height)
    {
        return Enumerable.Range(0, width * height).Select(_ => new SurfaceState()).ToArray();
    }

    public static PropState[] CreateProps(int width, int height)
    {
        return Enumerable.Range(0, width * height).Select(_ => new PropState()).ToArray();
    }
}