using System.ComponentModel.DataAnnotations;
using NodePipeline.Abstractions.Attributes;
using NodePipeline.Abstractions.Interfaces.Nodes;
using NodePipeline.Abstractions.Models;

namespace NodePipeline.Application.Nodes;

public class MaskApplyNode : INode
{
    [NodeField(FieldDirection.Input)]
    [Required]
    public NodeField<ImageBuffer> InputImage { get; set; } = null!;

    [NodeField(FieldDirection.Input)]
    [Required]
    public NodeField<ImageBuffer> Mask { get; set; } = null!;

    [NodeField(FieldDirection.Input)]
    [DisallowNullableOutput]
    [Required]
    public NodeField<bool> HasMask { get; set; } = null!;

    [NodeField(FieldDirection.Parameter)]
    public NodeField<MaskMode> Mode { get; set; } = null!; // "Subtract" или "Overlay"

    [NodeField(FieldDirection.Output)] public NodeField<ImageBuffer> OutputImage { get; set; } = null!;

    public void Execute()
    {
        var img = InputImage.Value;
        if (!HasMask.Value)
        {
            OutputImage.Value = InputImage.Value;
            return;
        }

        var mask = Mask.Value;
        var result = new ImageBuffer(img.Width, img.Height);

        for (var i = 0; i < img.Pixels.Length; i++)
        {
            var v = Mode.Value == MaskMode.Subtract
                ? (byte)Math.Max(0, img.Pixels[i] - mask.Pixels[i])
                : (byte)Math.Min(255, img.Pixels[i] + mask.Pixels[i]);
            result.Pixels[i] = v;
        }

        OutputImage.Value = result;
    }
}

public enum MaskMode
{
    Subtract,
    Overlay
}