using System.Drawing;
using System.Drawing.Imaging;

namespace IWS5.Server.Utils.Converter.TiffConverter;

internal static class TiffUtilities
{
    /// <summary>
    /// Creates a multi-page TIFF from an array of bitmaps
    /// </summary>
    /// <param name="bitmaps">Array of bitmap images</param>
    /// <param name="dpi">DPI setting for the TIFF</param>
    /// <returns>Multi-page TIFF as byte array</returns>
    public static async Task<byte[]> CreateMultiPageTiffAsync(Bitmap[] bitmaps, int dpi = 200)
    {
        if (bitmaps == null || bitmaps.Length == 0)
            throw new ArgumentException("Bitmaps array cannot be null or empty.");

        using var outputStream = new MemoryStream();
        
        var tiffCodec = ImageCodecInfo.GetImageDecoders()
            .FirstOrDefault(codec => codec.FormatID == ImageFormat.Tiff.Guid);
            
        if (tiffCodec == null)
            throw new InvalidOperationException("TIFF codec not found.");

        if (bitmaps.Length == 1)
        {
            bitmaps[0].SetResolution(dpi, dpi);
            bitmaps[0].Save(outputStream, ImageFormat.Tiff);
        }
        else
        {
            var encoderParams = new EncoderParameters(2);
            encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
            encoderParams.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionLZW);

            bitmaps[0].SetResolution(dpi, dpi);
            bitmaps[0].Save(outputStream, tiffCodec, encoderParams);

            // Add remaining pages
            for (int i = 1; i < bitmaps.Length; i++)
            {
                bitmaps[i].SetResolution(dpi, dpi);
                
                encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
                bitmaps[0].SaveAdd(bitmaps[i], encoderParams);
            }

            encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.Flush);
            bitmaps[0].SaveAdd(encoderParams);
            
            encoderParams.Dispose();
        }

        var result = outputStream.ToArray();

        if (result.Length == 0)
            throw new InvalidOperationException("TIFF conversion resulted in empty file.");

        return await Task.FromResult(result);
    }
}