using System;
using OpenCvSharp;

namespace OpenCVStudio_v0
{
    /// <summary>
    /// Масштабирует значения пикселей,
    /// добавляет смещение, вычисляет модуль
    /// и преобразует результат в CV_8U.
    /// </summary>
    public sealed class ConvertScaleAbsExecutor : IImageBlockExecutor
    {
        public string BlockType => "ConvertScaleAbs";

        public Mat Execute(Mat input, ProjectBlock block, ProjectManager projectManager)
        {
            ArgumentNullException.ThrowIfNull(input);
            ArgumentNullException.ThrowIfNull(block);
            ArgumentNullException.ThrowIfNull(projectManager);
            if (input.Empty())
            {
                throw new ArgumentException("В блок масштабирования яркости передано пустое изображение.", nameof(input));
            }
            double alpha = projectManager.GetBlockParameter(block.Id, "Alpha", 1.0);
            double beta = projectManager.GetBlockParameter(block.Id, "Beta", 0.0);
            ValidateParameters(alpha, beta, block);
            Mat output = new Mat();
            try
            {
                Cv2.ConvertScaleAbs(input, output, alpha, beta);
                if (output.Empty())
                {
                    throw new InvalidOperationException($"Блок «{block.Name}» вернул пустое изображение.");
                }
                return output;
            }
            catch
            {
                output.Dispose();
                throw;
            }
        }

        private static void ValidateParameters(double alpha, double beta, ProjectBlock block)
        {
            if (double.IsNaN(alpha) || double.IsInfinity(alpha))
            {
                throw new InvalidOperationException($"Блок «{block.Name}»: коэффициент Alpha должен быть конечным числом.");
            }
            if (double.IsNaN(beta) || double.IsInfinity(beta))
            {
                throw new InvalidOperationException($"Блок «{block.Name}»: смещение Beta должен быть конечным числом.");
            }
            if (alpha < 0.0)
            {
                throw new InvalidOperationException($"Блок «{block.Name}»: коэффициент Alpha не может быть отрицательным.");
            }
        }
    }
}