using ReactorMaintenance.Simulation;

namespace ReactorMaintenance.Simulation.Effects;

public sealed class SmokeSpreadEffect : IAreaSimulationEffect
{
    public CellState[] Apply(LevelState level, CellState[] cells)
    {
        var next = cells.ToArray();
        for (var y = Balancing.Current.FirstGridCoordinate; y < level.Height; y++)
        {
            for (var x = Balancing.Current.FirstGridCoordinate; x < level.Width; x++)
            {
                var position = new GridPosition(x, y);
                var cell = cells[level.Index(position)];
                if (cell.Hazards.Smoke < Balancing.Current.SmokeSpreadThreshold)
                    continue;

                SpreadToNeighbors(level, next, position);
            }
        }

        return next;
    }

    private static void SpreadToNeighbors(LevelState level, CellState[] next, GridPosition position)
    {
        foreach (var neighbor in position.Neighbors().Where(level.InBounds))
        {
            var neighborCell = next[level.Index(neighbor)];
            if (!neighborCell.IsWalkable || neighborCell.DoorLocked)
                continue;

            next[level.Index(neighbor)] = neighborCell with { Hazards = neighborCell.Hazards with { Smoke = Rules.Clamp(neighborCell.Hazards.Smoke + Balancing.Current.SmokeSpreadIncrease) } };
        }
    }
}