using Minint.Core.Models;
using Minint.Core.Services.Impl;

namespace Minint.Tests;

public class DrawingTests
{
    private readonly DrawingService _drawing = new();

    [Fact]
    public void ApplyBrush_Radius0_SetsSinglePixel()
    {
        var layer = new MinintLayer("L1", 9);
        _drawing.ApplyBrush(layer, 1, 1, 0, 1, 3, 3);

        Assert.Equal(1, layer.Pixels[1 * 3 + 1]);
        Assert.Equal(0, layer.Pixels[0]); // (0,0) untouched
    }

    [Fact]
    public void ApplyBrush_Radius1_SetsCircle()
    {
        var layer = new MinintLayer("L1", 25);
        _drawing.ApplyBrush(layer, 2, 2, 1, 1, 5, 5);

        // Center + 4 neighbors should be set
        Assert.Equal(1, layer.Pixels[2 * 5 + 2]); // center
        Assert.Equal(1, layer.Pixels[1 * 5 + 2]); // top
        Assert.Equal(1, layer.Pixels[3 * 5 + 2]); // bottom
        Assert.Equal(1, layer.Pixels[2 * 5 + 1]); // left
        Assert.Equal(1, layer.Pixels[2 * 5 + 3]); // right
    }

    [Fact]
    public void ApplyEraser_SetsToZero()
    {
        var layer = new MinintLayer("L1", 9);
        Array.Fill(layer.Pixels, 5);
        _drawing.ApplyEraser(layer, 1, 1, 0, 3, 3);

        Assert.Equal(0, layer.Pixels[1 * 3 + 1]);
        Assert.Equal(5, layer.Pixels[0]); // untouched
    }

    [Fact]
    public void GetBrushMask_Radius0_SinglePixel()
    {
        var mask = _drawing.GetBrushMask(2, 2, 0, 5, 5);
        Assert.Single(mask);
        Assert.Equal((2, 2), mask[0]);
    }

    [Fact]
    public void GetBrushMask_OutOfBounds_Clamped()
    {
        var mask = _drawing.GetBrushMask(0, 0, 2, 3, 3);
        Assert.All(mask, p =>
        {
            Assert.InRange(p.X, 0, 2);
            Assert.InRange(p.Y, 0, 2);
        });
    }
}
