using RioJoy.Core.Overlay;
using RioJoy.Overlay;
using SkiaSharp;
using Xunit;

namespace RioJoy.Core.Tests.Overlay;

public class SkiaOverlayRendererTests
{
    private static SKBitmap SolidBase(int w, int h, SKColor color)
    {
        var bmp = new SKBitmap(w, h);
        using var canvas = new SKCanvas(bmp);
        canvas.Clear(color);
        canvas.Flush();
        return bmp;
    }

    private static bool HasLightPixel(SKBitmap bmp, int x, int y, int w, int h)
    {
        for (int yy = y; yy < y + h; yy++)
        for (int xx = x; xx < x + w; xx++)
        {
            SKColor p = bmp.GetPixel(xx, yy);
            if (p.Red > 40 || p.Green > 40 || p.Blue > 40)
                return true;
        }
        return false;
    }

    private static OverlayRegion Region(string name, int x, int y, int w, int h) =>
        new() { Name = name, X = x, Y = y, Width = w, Height = h, FontFamily = "Arial", FontSizePx = 20, ColorHex = "#FFFFFF" };

    [Fact]
    public void Render_DrawsLabel_AndPreservesDimensions()
    {
        using SKBitmap baseImg = SolidBase(200, 100, SKColors.Black);
        var template = new OverlayTemplate { Width = 200, Height = 100, Regions = { Region("b-00", 10, 10, 150, 50) } };
        var labels = new Dictionary<string, string> { ["b-00"] = "FIRE" };

        using SKBitmap output = new SkiaOverlayRenderer().Render(template, labels, baseImg);

        Assert.Equal(200, output.Width);
        Assert.Equal(100, output.Height);
        Assert.True(HasLightPixel(output, 10, 10, 150, 50), "white label text should appear inside the region");
    }

    [Fact]
    public void Render_DoesNotMutateBaseImage()
    {
        using SKBitmap baseImg = SolidBase(120, 60, SKColors.Black);
        var template = new OverlayTemplate { Regions = { Region("x", 5, 5, 100, 40) } };

        using SKBitmap _ = new SkiaOverlayRenderer().Render(template, new Dictionary<string, string> { ["x"] = "HI" }, baseImg);

        Assert.False(HasLightPixel(baseImg, 0, 0, 120, 60), "the source bitmap must be left untouched");
    }

    [Fact]
    public void Render_RegionWithoutLabel_StaysBackground()
    {
        using SKBitmap baseImg = SolidBase(120, 60, SKColors.Black);
        var template = new OverlayTemplate { Regions = { Region("x", 5, 5, 100, 40) } };

        // No entry for "x" -> nothing drawn.
        using SKBitmap output = new SkiaOverlayRenderer().Render(template, new Dictionary<string, string>(), baseImg);

        Assert.False(HasLightPixel(output, 0, 0, 120, 60));
    }

    [Fact]
    public void RenderToPng_ProducesValidPngSignature()
    {
        using SKBitmap baseImg = SolidBase(64, 64, SKColors.Black);
        var template = new OverlayTemplate { Regions = { Region("x", 2, 2, 60, 30) } };

        byte[] png = new SkiaOverlayRenderer().RenderToPng(template, new Dictionary<string, string> { ["x"] = "HI" }, baseImg);

        Assert.True(png.Length > 8);
        Assert.Equal(new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, png.AsSpan(0, 8).ToArray());
    }
}
