package com.test.bijihoudaun.util;

import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 图片压缩工具类
 * 用于压缩上传的图片，减少存储和带宽
 */
@Slf4j
public class ImageCompressor {

    // 最大宽度（像素）
    private static final int MAX_WIDTH = 1920;
    // 最大高度（像素）
    private static final int MAX_HEIGHT = 1080;
    // 压缩质量（0.0 - 1.0）
    private static final float COMPRESS_QUALITY = 0.85f;
    // 需要压缩的最小文件大小（字节）
    private static final long COMPRESS_THRESHOLD = 500 * 1024; // 500KB

    /**
     * 压缩图片
     * @param inputStream 原始图片输入流
     * @param contentType 图片类型
     * @param originalSize 原始文件大小
     * @return 压缩后的输入流，如果不需要压缩则返回null
     */
    public static InputStream compressIfNeeded(InputStream inputStream, String contentType, long originalSize) {
        // 小于阈值的图片不压缩
        if (originalSize < COMPRESS_THRESHOLD) {
            return null;
        }

        // 只压缩 JPG 和 PNG
        if (!contentType.equals("image/jpeg") && !contentType.equals("image/png")) {
            return null;
        }

        try {
            BufferedImage originalImage = ImageIO.read(inputStream);
            if (originalImage == null) {
                return null;
            }

            // 计算新的尺寸
            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();

            // 如果图片尺寸小于限制，只进行质量压缩
            int newWidth = originalWidth;
            int newHeight = originalHeight;

            // 如果图片尺寸超过限制，等比例缩放
            if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT) {
                double scale = Math.min(
                        (double) MAX_WIDTH / originalWidth,
                        (double) MAX_HEIGHT / originalHeight
                );
                newWidth = (int) (originalWidth * scale);
                newHeight = (int) (originalHeight * scale);
            }

            // 创建压缩后的图片
            BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = compressedImage.createGraphics();

            // 设置高质量渲染
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 绘制图片
            g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
            g2d.dispose();

            // 输出为字节流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            String formatName = contentType.equals("image/png") ? "png" : "jpg";
            ImageIO.write(compressedImage, formatName, baos);

            byte[] compressedBytes = baos.toByteArray();

            // 如果压缩后更大，返回null使用原图
            if (compressedBytes.length >= originalSize) {
                return null;
            }

            log.debug("图片压缩成功：{} -> {} ({}%)",
                    formatSize(originalSize),
                    formatSize(compressedBytes.length),
                    (compressedBytes.length * 100 / originalSize));

            return new ByteArrayInputStream(compressedBytes);

        } catch (IOException e) {
            log.warn("图片压缩失败，使用原图", e);
            return null;
        }
    }

    /**
     * 格式化文件大小
     */
    private static String formatSize(long size) {
        if (size < 1024) {
            return size + "B";
        } else if (size < 1024 * 1024) {
            return String.format("%.2fKB", size / 1024.0);
        } else {
            return String.format("%.2fMB", size / (1024.0 * 1024));
        }
    }
}
