using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Media.Imaging;

namespace RevitAddinApplicationSample
{
    public static class Extension
    {
        // アセンブリのマニフェストリソース名から BitmapSource を作成する
        public static BitmapSource GetImageSourceFromManifest(Assembly assembly, string manifestResourceName)
        {
            if (assembly == null) throw new ArgumentNullException(nameof(assembly));
            if (string.IsNullOrWhiteSpace(manifestResourceName)) throw new ArgumentNullException(nameof(manifestResourceName));

            using Stream? s = assembly.GetManifestResourceStream(manifestResourceName);
            if (s == null)
            {
                // デバッグ用に利用可能なリソース名を列挙することで間違いを特定しやすくする
                var names = string.Join(", ", assembly.GetManifestResourceNames().Take(20));
                throw new InvalidOperationException($"マニフェストリソース '{manifestResourceName}' が見つかりません。利用可能なリソースの一部: {names}");
            }

            return CreateBitmapFromStream(s);
        }

        // Stream から BitmapSource を作成する（OnLoad + Freeze）
        public static BitmapSource GetImageSource(Stream stream)
        {
            if (stream == null) throw new ArgumentNullException(nameof(stream));
            return CreateBitmapFromStream(stream);
        }

        // byte[] から BitmapSource を作成する
        public static BitmapSource GetImageSource(byte[] imageData)
        {
            if (imageData == null) throw new ArgumentNullException(nameof(imageData));
            using var ms = new MemoryStream(imageData);
            return CreateBitmapFromStream(ms);
        }

        // 内部ユーティリティ: MemoryStream にコピーして BitmapImage を作成（using ブロック内で EndInit を完了させる）
        private static BitmapSource CreateBitmapFromStream(Stream input)
        {
            using var ms = new MemoryStream();
            if (input.CanSeek) input.Position = 0;
            input.CopyTo(ms);
            ms.Position = 0;

            var bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.CacheOption = BitmapCacheOption.OnLoad;
            bmp.StreamSource = ms;
            bmp.UriSource = null;
            bmp.EndInit();
            bmp.Freeze();
            return bmp;
        }
    }
}
