using Minint.Core.Models;

namespace Minint.Core.Services.Impl;

public sealed class FloodFillService : IFloodFillService
{
    public void Fill(MinintLayer layer, int x, int y, int newColorIndex, int width, int height)
    {
        if (x < 0 || x >= width || y < 0 || y >= height)
            return;

        var pixels = layer.Pixels;
        int targetIndex = pixels[y * width + x];

        if (targetIndex == newColorIndex)
            return;

        var queue = new Queue<(int X, int Y)>();
        var visited = new bool[width * height];

        queue.Enqueue((x, y));
        visited[y * width + x] = true;

        while (queue.Count > 0)
        {
            var (cx, cy) = queue.Dequeue();
            pixels[cy * width + cx] = newColorIndex;

            Span<(int, int)> neighbors =
            [
                (cx - 1, cy), (cx + 1, cy),
                (cx, cy - 1), (cx, cy + 1)
            ];

            foreach (var (nx, ny) in neighbors)
            {
                if (nx < 0 || nx >= width || ny < 0 || ny >= height)
                    continue;
                int ni = ny * width + nx;
                if (visited[ni] || pixels[ni] != targetIndex)
                    continue;
                visited[ni] = true;
                queue.Enqueue((nx, ny));
            }
        }
    }
}
