package com.njzscloud.common.core.utils;

import com.njzscloud.common.core.ex.Exceptions;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class ImgUtil {

    // 默认字体（可根据需求调整）
    private static final Font DEFAULT_FONT = new Font("SansSerif", Font.PLAIN, 24);
    // 默认水印颜色（半透明黑色）
    private static final Color DEFAULT_COLOR = Color.WHITE;
    // 行间距（字体大小的1.2倍）
    private static final float LINE_SPACING_RATIO = 1.2f;
    // 左右边距（避免文本贴边）
    private static final int PADDING_HORIZONTAL = 10;
    // 上下边距
    private static final int PADDING_VERTICAL = 10;

    /**
     * 在左上角添加文字水印
     *
     * @param sourceImageIn 图片
     * @param type          jpg 或 png
     * @param txt           文字
     */
    public static byte[] addTxtWatermark(InputStream sourceImageIn, String type, String txt) {
        try {
            BufferedImage sourceImage = ImageIO.read(sourceImageIn);
            if (sourceImage == null) {
                throw Exceptions.error("图片读取失败");
            }

            BufferedImage targetImage = new BufferedImage(
                sourceImage.getWidth(),
                sourceImage.getHeight(),
                type.equalsIgnoreCase("png") ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB
            );
            Graphics2D g2d = targetImage.createGraphics();

            g2d.drawImage(sourceImage, 0, 0, null);

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
            g2d.setFont(DEFAULT_FONT);
            g2d.setColor(DEFAULT_COLOR);

            int maxWatermarkWidth = (sourceImage.getWidth() / 2) - 2 * PADDING_HORIZONTAL;
            if (maxWatermarkWidth <= 0) {
                throw Exceptions.error("图片宽度过小，无法添加水印");
            }
            int lineHeight = g2d.getFontMetrics().getHeight();

            String[] txts = txt.split("\n");
            int currentY = PADDING_VERTICAL + g2d.getFontMetrics().getAscent();
            int maxHeight = targetImage.getHeight();

            for (String s : txts) {
                List<String> lines = wrapText(s, DEFAULT_FONT, maxWatermarkWidth);
                for (String line : lines) {
                    g2d.drawString(line, PADDING_HORIZONTAL, currentY);
                    currentY += (int) (lineHeight * LINE_SPACING_RATIO);
                    if (currentY >= maxHeight) {
                        throw Exceptions.error("图片高度不足，无法添加水印");
                    }
                }
            }

            g2d.dispose();

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            boolean write = ImageIO.write(targetImage, type, outputStream);
            if (write) {
                return outputStream.toByteArray();
            } else {
                return new byte[0];
            }
        } catch (Exception e) {
            throw Exceptions.error(e, "水印添加失败");
        }
    }

    /**
     * 文本自动换行处理
     *
     * @param text     待换行文本
     * @param font     字体
     * @param maxWidth 最大宽度（像素）
     * @return 换行后的文本行列表
     */
    private static List<String> wrapText(String text, Font font, int maxWidth) {
        List<String> lines = new ArrayList<>();
        if (text == null || text.isBlank()) {
            return lines;
        }

        Graphics2D g2d = (Graphics2D) new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getGraphics();
        g2d.setFont(font);
        FontMetrics metrics = g2d.getFontMetrics();
        g2d.dispose();

        String[] words = text.split(" ");
        StringBuilder currentLine = new StringBuilder();

        for (String word : words) {
            String tempLine = currentLine.isEmpty() ? word : currentLine + " " + word;
            Rectangle2D bounds = metrics.getStringBounds(tempLine, null);

            if (bounds.getWidth() <= maxWidth) {
                // 当前行加上单词后未超过最大宽度，继续添加
                currentLine = new StringBuilder(tempLine);
            } else {
                // 超过最大宽度，保存当前行，开始新行
                if (!currentLine.isEmpty()) {
                    lines.add(currentLine.toString());
                    currentLine = new StringBuilder(word);
                } else {
                    // 单个单词超过最大宽度，强制截断（特殊情况处理）
                    lines.add(truncateWord(word, metrics, maxWidth));
                    currentLine = new StringBuilder();
                }
            }
        }

        // 添加最后一行
        if (!currentLine.isEmpty()) {
            lines.add(currentLine.toString());
        }

        return lines;
    }

    /**
     * 单个单词超长时的强制截断（按字符分割）
     *
     * @param word     超长单词
     * @param metrics  字体度量
     * @param maxWidth 最大宽度
     * @return 截断后的单词片段
     */
    private static String truncateWord(String word, FontMetrics metrics, int maxWidth) {
        StringBuilder truncated = new StringBuilder();
        for (char c : word.toCharArray()) {
            String temp = truncated + String.valueOf(c);
            if (metrics.getStringBounds(temp, null).getWidth() <= maxWidth) {
                truncated.append(c);
            } else {
                break;
            }
        }
        return truncated.toString();
    }

}
