using Avalonia.Controls;

namespace Lumi.Companion.App;

internal static class LumiIconFactory
{
    public static WindowIcon Create(TrayHealth health)
    {
        const int size = 32;
        var color = health switch
        {
            TrayHealth.Operating => (R: (byte)35, G: (byte)132, B: (byte)91),
            TrayHealth.Degraded => (R: (byte)169, G: (byte)102, B: (byte)18),
            TrayHealth.Failed => (R: (byte)189, G: (byte)77, B: (byte)77),
            _ => (R: (byte)79, G: (byte)182, B: (byte)194)
        };
        var pixels = new byte[size * size * 4];
        for (var y = 0; y < size; y++)
        for (var x = 0; x < size; x++)
        {
            var target = ((size - 1 - y) * size + x) * 4;
            var rounded = InsideRoundedSquare(x, y, size, 7);
            var diamond = Math.Abs(x - 15.5) / 11.5 + Math.Abs(y - 15.5) / 11.5 <= 1;
            pixels[target] = diamond && rounded ? (byte)255 : color.B;
            pixels[target + 1] = diamond && rounded ? (byte)255 : color.G;
            pixels[target + 2] = diamond && rounded ? (byte)255 : color.R;
            pixels[target + 3] = rounded ? (byte)255 : (byte)0;
        }

        using var stream = new MemoryStream();
        using var writer = new BinaryWriter(stream, System.Text.Encoding.UTF8, leaveOpen: true);
        writer.Write((ushort)0); writer.Write((ushort)1); writer.Write((ushort)1);
        writer.Write((byte)size); writer.Write((byte)size); writer.Write((byte)0); writer.Write((byte)0);
        writer.Write((ushort)1); writer.Write((ushort)32);
        var imageBytes = 40 + pixels.Length + size * 4;
        writer.Write(imageBytes); writer.Write(22);
        writer.Write(40); writer.Write(size); writer.Write(size * 2); writer.Write((ushort)1); writer.Write((ushort)32);
        writer.Write(0); writer.Write(pixels.Length); writer.Write(0); writer.Write(0); writer.Write(0); writer.Write(0);
        writer.Write(pixels); writer.Write(new byte[size * 4]);
        stream.Position = 0;
        return new WindowIcon(stream);
    }

    private static bool InsideRoundedSquare(int x, int y, int size, int radius)
    {
        if (x >= radius && x < size - radius || y >= radius && y < size - radius) return true;
        var cx = x < radius ? radius : size - radius - 1;
        var cy = y < radius ? radius : size - radius - 1;
        var dx = x - cx; var dy = y - cy;
        return dx * dx + dy * dy <= radius * radius;
    }
}
