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

namespace Minint.Tests;

public class ImageEffectsTests
{
    private readonly ImageEffectsService _effects = new();

    [Fact]
    public void ApplyGrayscale_ConvertsColors()
    {
        var doc = new MinintDocument("test");
        var red = new RgbaColor(255, 0, 0, 255);
        doc.EnsureColorCached(red);

        _effects.ApplyGrayscale(doc);

        var gray = doc.Palette[1];
        Assert.Equal(gray.R, gray.G);
        Assert.Equal(gray.G, gray.B);
        Assert.Equal(255, gray.A);
        // BT.601: 0.299*255 ≈ 76
        Assert.InRange(gray.R, 74, 78);
    }

    [Fact]
    public void ApplyGrayscale_PreservesTransparentIndex()
    {
        var doc = new MinintDocument("test");
        doc.EnsureColorCached(new RgbaColor(100, 200, 50, 255));

        _effects.ApplyGrayscale(doc);

        Assert.Equal(RgbaColor.Transparent, doc.Palette[0]);
    }

    [Fact]
    public void ApplyContrast_IncreasesContrast()
    {
        var doc = new MinintDocument("test");
        var midGray = new RgbaColor(128, 128, 128, 255);
        var lightGray = new RgbaColor(192, 192, 192, 255);
        doc.EnsureColorCached(midGray);
        doc.EnsureColorCached(lightGray);

        _effects.ApplyContrast(doc, 2.0);

        // midGray (128) stays ~128: factor*(128-128)+128 = 128
        Assert.InRange(doc.Palette[1].R, 126, 130);
        // lightGray (192): factor*(192-128)+128 = 2*64+128 = 256 → clamped to 255
        Assert.Equal(255, doc.Palette[2].R);
    }

    [Fact]
    public void ApplyContrast_PreservesAlpha()
    {
        var doc = new MinintDocument("test");
        doc.EnsureColorCached(new RgbaColor(100, 100, 100, 200));

        _effects.ApplyContrast(doc, 1.5);

        Assert.Equal(200, doc.Palette[1].A);
    }
}
