package com.ycwl.basic.image.watermark.operator;

import com.ycwl.basic.image.watermark.entity.WatermarkInfo;
import com.ycwl.basic.image.watermark.exception.ImageWatermarkException;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * 徕卡水印
 */
@Slf4j
public class LeicaWatermarkOperator implements IOperator {
    private static final String FONT_PATH = "/PingFang_SC.ttf";
    public static String defaultFontName;
    public static float FONT_GLOBAL_OFFSET_PERCENT = 0;
    static {
        try {
            // 加载字体文件流
            InputStream fontStream = LeicaWatermarkOperator.class.getResourceAsStream(FONT_PATH);
            if (fontStream == null) {
                throw new RuntimeException("字体文件未找到！路径：" + FONT_PATH);
            }

            // 创建字体对象
            Font customFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);

            // 注册字体到系统
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(customFont);

            // 更新默认字体名称为新字体的逻辑名称
            defaultFontName = customFont.getName(); // 如 "PingFang SC"
            FONT_GLOBAL_OFFSET_PERCENT = -0.3f;
        } catch (FontFormatException | IOException e) {
            log.error("加载字体文件失败", e);
            defaultFontName = "宋体";
        }
    }
    public static int EXTRA_BOTTOM_PX = 140;
    public static int EXTRA_BORDER_PX = 0;
    public static Color BG_COLOR = Color.WHITE;
    public static int LOGO_SIZE = 50;
    public static int LOGO_EXTRA_BORDER = 20;
    public static int LOGO_FONT_SIZE = 38;
    public static Color logoTextColor = new Color(0x33, 0x33, 0x33);
    public static int QRCODE_SIZE = 80;
    public static int QRCODE_OFFSET_X = 5;
    public static int OFFSET_X = 80;
    public static int OFFSET_Y = 30;
    public static int SCENIC_FONT_SIZE = 32;
    public static Color scenicColor = new Color(0x33, 0x33, 0x33);
    public static int DATETIME_FONT_SIZE = 28;
    public static Color datetimeColor = new Color(0x99, 0x99, 0x99);

    @Override
    public File process(WatermarkInfo info) throws ImageWatermarkException {
        BufferedImage baseImage;
        BufferedImage qrcodeImage;
        BufferedImage logoImage;
        // 从类路径加载 zt-logo.png
        InputStream logoInputStream = getClass().getResourceAsStream("/zt-logo.png");
        if (logoInputStream == null) {
            throw new ImageWatermarkException("无法找到 zt-logo.png 资源文件");
        }
        try {
            baseImage = ImageIO.read(info.getOriginalFile());
            qrcodeImage = ImageIO.read(info.getQrcodeFile());
            logoImage = ImageIO.read(logoInputStream);
            logoInputStream.close();
        } catch (IOException e) {
            throw new ImageWatermarkException("图片打开失败");
        }
        // 新图像画布
        BufferedImage newImage = new BufferedImage(baseImage.getWidth() + 2 * EXTRA_BORDER_PX, baseImage.getHeight() + 2 * EXTRA_BORDER_PX + EXTRA_BOTTOM_PX, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = newImage.createGraphics();
        g2d.setColor(BG_COLOR);
        g2d.fillRect(0, 0, newImage.getWidth(), newImage.getHeight());
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.drawImage(baseImage, EXTRA_BORDER_PX, EXTRA_BORDER_PX, null);
        int logoHeight = LOGO_SIZE;
        int logoWidth = (int) (logoHeight * 1.0 / logoImage.getHeight() * logoImage.getWidth());
        g2d.drawImage(logoImage, EXTRA_BORDER_PX + OFFSET_X, EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + LOGO_EXTRA_BORDER, logoWidth, logoHeight, null);
        Font logoTextFont = new Font(defaultFontName, Font.PLAIN, LOGO_FONT_SIZE);
        g2d.setFont(logoTextFont);
        g2d.setColor(logoTextColor);
        FontMetrics logoFontMetrics = g2d.getFontMetrics(logoTextFont);
        int logoTextHeight = logoFontMetrics.getHeight();
        int logoTextOffsetY = (LOGO_SIZE - logoHeight) / 2;
        g2d.drawString("帧途", EXTRA_BORDER_PX + OFFSET_X + logoWidth + 5, EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + logoTextHeight + LOGO_EXTRA_BORDER + logoTextOffsetY + logoTextHeight * FONT_GLOBAL_OFFSET_PERCENT);
        int newQrcodeHeight = QRCODE_SIZE;
        int newQrcodeWidth = (int) (newQrcodeHeight * 1.0 / qrcodeImage.getHeight() * qrcodeImage.getWidth());
        Font scenicFont = new Font(defaultFontName, Font.PLAIN, SCENIC_FONT_SIZE);
        Font datetimeFont = new Font(defaultFontName, Font.PLAIN, DATETIME_FONT_SIZE);
        FontMetrics scenicFontMetrics = g2d.getFontMetrics(scenicFont);
        FontMetrics datetimeFontMetrics = g2d.getFontMetrics(datetimeFont);
        int scenicLineHeight = scenicFontMetrics.getHeight();
        int dtLineHeight = datetimeFontMetrics.getHeight();
        int scenicLineWidth = scenicFontMetrics.stringWidth(info.getScenicLine());
        int datetimeLineWidth = scenicFontMetrics.stringWidth(info.getDatetimeLine());
        g2d.drawImage(qrcodeImage, newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - newQrcodeWidth - QRCODE_OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y, newQrcodeWidth, newQrcodeHeight, null);
        g2d.setFont(scenicFont);
        g2d.setColor(scenicColor);
        g2d.drawString(info.getScenicLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + scenicLineHeight + scenicLineHeight * FONT_GLOBAL_OFFSET_PERCENT);
        g2d.setFont(datetimeFont);
        g2d.setColor(datetimeColor);
        g2d.drawString(info.getDatetimeLine(), newImage.getWidth() + EXTRA_BORDER_PX - OFFSET_X - Math.max(scenicLineWidth, datetimeLineWidth), EXTRA_BORDER_PX + baseImage.getHeight() + OFFSET_Y + scenicLineHeight + dtLineHeight + dtLineHeight * FONT_GLOBAL_OFFSET_PERCENT);
        String fileName = info.getWatermarkedFile().getName();
        String formatName = "jpg"; // 默认格式为 jpg
        if (fileName.endsWith(".png")) {
            formatName = "png";
        } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
            formatName = "jpg";
        }
        ImageWriter writer = ImageIO.getImageWritersByFormatName(formatName).next();
        ImageOutputStream ios;
        try {
            ios = ImageIO.createImageOutputStream(info.getWatermarkedFile());
        } catch (IOException e) {
            throw new ImageWatermarkException("图片保存失败，目标文件无法写入");
        }
        writer.setOutput(ios);
        try {
            // 使用 ImageWriter 设置写入质量
            ImageWriteParam writeParam = writer.getDefaultWriteParam();
            if (writeParam.canWriteCompressed()) {
                writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                writeParam.setCompressionQuality(0.95f); // 设置写入质量为 95%
            }
            writer.write(null, new javax.imageio.IIOImage(newImage, null, null), writeParam);
        } catch (IOException e) {
            throw new ImageWatermarkException("图片保存失败");
        }
        finally {
            g2d.dispose();
            try {
                ios.close();
            } catch (IOException ignore) {
            }
            writer.dispose();
        }
        return info.getWatermarkedFile();
    }
}
