using System;
using System.IO;
using OpenCvSharp;

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

        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 не удалось прочитать основное изображение.");
                }
                /*
                 * После ReplaceImage владельцем Mat
                 * становится PipelineContext.
                 */
                context.ReplaceImage(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;
        }
    }
}