using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Png;

namespace DramaLing.Api.Services;

public class ImageProcessingService : IImageProcessingService
{
    private readonly ILogger<ImageProcessingService> _logger;

    public ImageProcessingService(ILogger<ImageProcessingService> logger)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<byte[]> ResizeImageAsync(byte[] originalBytes, int targetWidth, int targetHeight)
    {
        try
        {
            _logger.LogInformation("Resizing image from {OriginalSize}KB to {TargetWidth}x{TargetHeight}",
                originalBytes.Length / 1024, targetWidth, targetHeight);

            using var image = Image.Load(originalBytes);

            _logger.LogDebug("Original image size: {Width}x{Height}", image.Width, image.Height);

            // 使用高品質的 Lanczos3 重採樣算法
            image.Mutate(x => x.Resize(targetWidth, targetHeight, KnownResamplers.Lanczos3));

            using var output = new MemoryStream();

            // 使用 PNG 格式儲存，保持品質
            await image.SaveAsPngAsync(output, new PngEncoder
            {
                CompressionLevel = PngCompressionLevel.Level6, // 平衡壓縮和品質
                ColorType = PngColorType.Rgb
            });

            var resizedBytes = output.ToArray();

            _logger.LogInformation("Image resized successfully. New size: {NewSize}KB (reduction: {Reduction:P})",
                resizedBytes.Length / 1024,
                1.0 - (double)resizedBytes.Length / originalBytes.Length);

            return resizedBytes;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to resize image");
            throw;
        }
    }

    public async Task<byte[]> OptimizeImageAsync(byte[] originalBytes, int quality = 85)
    {
        try
        {
            _logger.LogInformation("Optimizing image, original size: {OriginalSize}KB",
                originalBytes.Length / 1024);

            using var image = Image.Load(originalBytes);
            using var output = new MemoryStream();

            // 針對例句圖的優化設定
            await image.SaveAsPngAsync(output, new PngEncoder
            {
                CompressionLevel = PngCompressionLevel.Level9, // 最高壓縮
                ColorType = PngColorType.Rgb,
                BitDepth = PngBitDepth.Bit8
            });

            var optimizedBytes = output.ToArray();

            _logger.LogInformation("Image optimized successfully. New size: {NewSize}KB (reduction: {Reduction:P})",
                optimizedBytes.Length / 1024,
                1.0 - (double)optimizedBytes.Length / originalBytes.Length);

            return optimizedBytes;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to optimize image");
            throw;
        }
    }
}