using System;
using System.IO;
using OpenCvSharp;

namespace OpenCVStudio_v0
{
    /// <summary>
    /// Загружает второе изображение проекта
    /// во второй слот PipelineContext.
    ///
    /// Текущее основное изображение при этом
    /// не изменяется.
    /// </summary>
    internal sealed class SecondImageSourceExecutor : IPipelineBlockExecutor
    {
        public string BlockType => "SecondImageSource";

        public void Execute(PipelineContext context, ProjectBlock block, ProjectManager projectManager)
        {
            ArgumentNullException.ThrowIfNull(context);
            ArgumentNullException.ThrowIfNull(block);
            ArgumentNullException.ThrowIfNull(projectManager);
            string imagePath = GetImagePath(block, projectManager);
            Mat? loadedImage = null;
            try
            {
                loadedImage = Cv2.ImRead(imagePath, ImreadModes.Color);
                if (loadedImage.Empty())
                {
                    throw new InvalidDataException("OpenCV не удалось прочитать второе изображение.");
                }
                /*
                 * Основное context.Image не меняется.
                 * Заполняется только второй слот.
                 */
                context.ReplaceSecondImage(loadedImage);
                loadedImage = null;
                context.ResultText = $"Загружено второе изображение: {Path.GetFileName(imagePath)}";
            }
            finally
            {
                loadedImage?.Dispose();
            }
        }

        private static string GetImagePath(ProjectBlock block, ProjectManager projectManager)
        {
            string? imagePath = projectManager.GetBlockImageFullPath(block.Id);
            if (string.IsNullOrWhiteSpace(imagePath))
            {
                throw new InvalidOperationException($"Для блока «{block.Name}» не выбрано второе изображение.\n\nНажмите кнопку 📁 и выберите файл.");
            }
            if (!File.Exists(imagePath))
            {
                throw new FileNotFoundException("Файл второго изображения не найден.", imagePath);
            }
            return imagePath;
        }
    }
}