package com.fuyuanshen.common.core.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

public class ImageWithTextGenerate {

    /**
     * 生成160*80画布，嵌入背景图片并居中显示文字（支持自动换行），输出RGB565格式数据
     *
     * @param text 要显示的文字
     * @param fixedLength 固定输出长度（字节数）
     * @return RGB565格式的图像数据
     */
    public static byte[] generate160x80ImageWithText2(String text, InputStream backgroundImageInputStream,  int fixedLength) throws IOException {
        // 创建160*80的图像
        BufferedImage image = new BufferedImage(160, 80, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // 绘制白色背景
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 160, 80);

        // 如果提供了背景图片，则绘制背景
        if (backgroundImageInputStream != null ) {
            BufferedImage backgroundImage = ImageIO.read(backgroundImageInputStream);
            // 缩放并绘制背景图片以适应160*80画布
            g.drawImage(backgroundImage, 0, 0, 160, 80, null);
        }

        // 设置文字属性
        Font font = new Font("宋体", Font.PLAIN, 12); // 可根据需要调整字体大小
        g.setFont(font);
        g.setColor(new Color(255, 255, 255, (int)(0.6 * 255)));

        // 关闭抗锯齿以获得清晰的点阵效果
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        // 获取字体度量信息
        FontMetrics metrics = g.getFontMetrics();
        int lineHeight = metrics.getHeight();

        // 文本换行处理
        ArrayList<String> lines = wrapText(text, metrics, 120); // 160为画布宽度

        // 计算垂直居中起始位置
        int totalTextHeight = lines.size() * lineHeight;
        int startY = (80 - totalTextHeight) / 2 + metrics.getAscent();

        // 绘制每一行文字
        for (int i = 0; i < lines.size(); i++) {
            String line = lines.get(i);
            int lineWidth = metrics.stringWidth(line);
            int x = (160 - lineWidth) / 2; // 水平居中
            int y = startY + i * lineHeight;
            g.drawString(line, x, y);
        }

        g.dispose();

        // 转换像素数据为RGB565格式（高位在前）
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        for (int yCoord = 0; yCoord < 80; yCoord++) {
            for (int xCoord = 0; xCoord < 160; xCoord++) {
                int rgb = image.getRGB(xCoord, yCoord);

                // 提取RGB分量
                int r = (rgb >> 16) & 0xFF;
                int g1 = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;

                // 转换为RGB565（5位红，6位绿，5位蓝）
                int r5 = (r >> 3) & 0x1F;
                int g6 = (g1 >> 2) & 0x3F;
                int b5 = (b >> 3) & 0x1F;

                // 组合为16位值
                int rgb565 = (r5 << 11) | (g6 << 5) | b5;

                // 高位在前（大端序）写入字节
                byteStream.write((rgb565 >> 8) & 0xFF); // 高字节
                byteStream.write(rgb565 & 0xFF);        // 低字节
            }
        }

        // 调整到固定长度
        byte[] rawData = byteStream.toByteArray();
        byte[] result = new byte[fixedLength];
        int copyLength = Math.min(rawData.length, fixedLength);
        System.arraycopy(rawData, 0, result, 0, copyLength);
        return result;
    }
    /**
     * 生成160*80画布，嵌入背景图片并居中显示文字（支持自动换行），输出RGB565格式数据
     *
     * @param text 要显示的文字
     * @param backgroundImagePath 背景图片路径
     * @param fixedLength 固定输出长度（字节数）
     * @return RGB565格式的图像数据
     */
    public static byte[] generate160x80ImageWithText(String text, String backgroundImagePath, int fixedLength) throws IOException {
        // 创建160*80的图像
        BufferedImage image = new BufferedImage(160, 80, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // 绘制白色背景
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 160, 80);

        // 如果提供了背景图片，则绘制背景
        if (backgroundImagePath != null && !backgroundImagePath.isEmpty()) {
            File backgroundFile = new File(backgroundImagePath);
            if (backgroundFile.exists()) {
                BufferedImage backgroundImage = ImageIO.read(backgroundFile);
                // 缩放并绘制背景图片以适应160*80画布
                g.drawImage(backgroundImage, 0, 0, 160, 80, null);
            }
        }

        // 设置文字属性
        Font font = new Font("宋体", Font.PLAIN, 12); // 可根据需要调整字体大小
        g.setFont(font);
        g.setColor(new Color(255, 255, 255, (int)(0.6 * 255)));

        // 关闭抗锯齿以获得清晰的点阵效果
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        // 获取字体度量信息
        FontMetrics metrics = g.getFontMetrics();
        int lineHeight = metrics.getHeight();

        // 文本换行处理
        ArrayList<String> lines = wrapText(text, metrics, 120); // 160为画布宽度

        // 计算垂直居中起始位置
        int totalTextHeight = lines.size() * lineHeight;
        int startY = (80 - totalTextHeight) / 2 + metrics.getAscent();

        // 绘制每一行文字
        for (int i = 0; i < lines.size(); i++) {
            String line = lines.get(i);
            int lineWidth = metrics.stringWidth(line);
            int x = (160 - lineWidth) / 2; // 水平居中
            int y = startY + i * lineHeight;
            g.drawString(line, x, y);
        }

        g.dispose();

        // 转换像素数据为RGB565格式（高位在前）
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        for (int yCoord = 0; yCoord < 80; yCoord++) {
            for (int xCoord = 0; xCoord < 160; xCoord++) {
                int rgb = image.getRGB(xCoord, yCoord);

                // 提取RGB分量
                int r = (rgb >> 16) & 0xFF;
                int g1 = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;

                // 转换为RGB565（5位红，6位绿，5位蓝）
                int r5 = (r >> 3) & 0x1F;
                int g6 = (g1 >> 2) & 0x3F;
                int b5 = (b >> 3) & 0x1F;

                // 组合为16位值
                int rgb565 = (r5 << 11) | (g6 << 5) | b5;

                // 高位在前（大端序）写入字节
                byteStream.write((rgb565 >> 8) & 0xFF); // 高字节
                byteStream.write(rgb565 & 0xFF);        // 低字节
            }
        }

        // 调整到固定长度
        byte[] rawData = byteStream.toByteArray();
        byte[] result = new byte[fixedLength];
        int copyLength = Math.min(rawData.length, fixedLength);
        System.arraycopy(rawData, 0, result, 0, copyLength);
        return result;
    }

    /**
     * 文本换行处理
     *
     * @param text 原始文本
     * @param metrics 字体度量信息
     * @param maxWidth 最大宽度
     * @return 换行后的文本行列表
     */
    private static ArrayList<String> wrapText(String text, FontMetrics metrics, int maxWidth) {
        ArrayList<String> lines = new ArrayList<>();
        String[] paragraphs = text.split("\n");

        for (String paragraph : paragraphs) {
            String[] words = paragraph.split("(?<=\\S)(?=\\s)|(?<=\\s)(?=\\S)");
            StringBuilder line = new StringBuilder();

            for (String word : words) {
                String testLine = line.toString() + word;
                int lineWidth = metrics.stringWidth(testLine);

                if (lineWidth <= maxWidth) {
                    line.append(word);
                } else {
                    if (line.length() > 0) {
                        lines.add(line.toString());
                        line = new StringBuilder(word);
                    } else {
                        // 单个词就超过宽度，需要进一步拆分
                        lines.addAll(wrapWord(word, metrics, maxWidth));
                    }
                }
            }

            if (line.length() > 0) {
                lines.add(line.toString());
            }
        }

        // 限制最大行数以适应80像素高度
        if (lines.size() > 6) { // 假设每行最多13像素高，80/13约等于6
            return (ArrayList<String>) lines.subList(0, 6);
        }

        return lines;
    }

    /**
     * 对单个超长词进行拆分
     *
     * @param word 单词
     * @param metrics 字体度量信息
     * @param maxWidth 最大宽度
     * @return 拆分后的词列表
     */
    private static ArrayList<String> wrapWord(String word, FontMetrics metrics, int maxWidth) {
        ArrayList<String> result = new ArrayList<>();
        StringBuilder current = new StringBuilder();

        for (char c : word.toCharArray()) {
            String testStr = current.toString() + c;
            if (metrics.stringWidth(testStr) <= maxWidth) {
                current.append(c);
            } else {
                if (current.length() > 0) {
                    result.add(current.toString());
                }
                current = new StringBuilder(String.valueOf(c));
            }
        }

        if (current.length() > 0) {
            result.add(current.toString());
        }

        return result;
    }

    /**
     * 生成160*80画布，嵌入背景图片并居中显示文字，输出RGB565格式数据（支持InputStream）
     *
     * @param text 要显示的文字
     * @param backgroundImageInputStream 背景图片输入流
     * @param fixedLength 固定输出长度（字节数）
     * @return RGB565格式的图像数据
     */
    public static byte[] generate160x80ImageWithText(String text, InputStream backgroundImageInputStream, int fixedLength) throws IOException {
        // 创建160*80的图像
        BufferedImage image = new BufferedImage(160, 80, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // 绘制白色背景
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 160, 80);

        // 如果提供了背景图片，则绘制背景
        if (backgroundImageInputStream != null) {
            BufferedImage backgroundImage = ImageIO.read(backgroundImageInputStream);
            // 缩放并绘制背景图片以适应160*80画布
            g.drawImage(backgroundImage, 0, 0, 160, 80, null);
        }

        // 设置文字属性
        Font font = new Font("宋体", Font.PLAIN, 16); // 可根据需要调整字体大小
        g.setFont(font);
        g.setColor(Color.BLACK);

        // 关闭抗锯齿以获得清晰的点阵效果
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        // 获取字体度量信息
        FontMetrics metrics = g.getFontMetrics();

        // 计算文字的宽度和高度
        int textWidth = metrics.stringWidth(text);
        int textHeight = metrics.getHeight();

        // 计算居中位置
        int x = (160 - textWidth) / 2; // 水平居中
        int y = (80 - textHeight) / 2 + metrics.getAscent(); // 垂直居中

        // 绘制文字
        g.drawString(text, x, y);

        g.dispose();

        // 转换像素数据为RGB565格式（高位在前）
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        for (int yCoord = 0; yCoord < 80; yCoord++) {
            for (int xCoord = 0; xCoord < 160; xCoord++) {
                int rgb = image.getRGB(xCoord, yCoord);

                // 提取RGB分量
                int r = (rgb >> 16) & 0xFF;
                int g1 = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;

                // 转换为RGB565（5位红，6位绿，5位蓝）
                int r5 = (r >> 3) & 0x1F;
                int g6 = (g1 >> 2) & 0x3F;
                int b5 = (b >> 3) & 0x1F;

                // 组合为16位值
                int rgb565 = (r5 << 11) | (g6 << 5) | b5;

                // 高位在前（大端序）写入字节
                byteStream.write((rgb565 >> 8) & 0xFF); // 高字节
                byteStream.write(rgb565 & 0xFF);        // 低字节
            }
        }

        // 调整到固定长度
        byte[] rawData = byteStream.toByteArray();
        byte[] result = new byte[fixedLength];
        int copyLength = Math.min(rawData.length, fixedLength);
        System.arraycopy(rawData, 0, result, 0, copyLength);
        return result;
    }
    /**
     * 将RGB565格式的字节数组转换为BufferedImage
     *
     * @param data RGB565格式的数据
     * @param height 图像高度
     * @param width 图像宽度
     * @return 转换后的BufferedImage
     */
    public static BufferedImage convertByteArrayToImage(byte[] data, int height, int width) {
        if (data == null || data.length == 0) {
            return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
        }

        // 创建图像
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 处理RGB565数据
        int dataIndex = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // 每个像素占2个字节
                if (dataIndex + 1 >= data.length) {
                    return image;
                }

                // 读取两个字节组成RGB565值
                int highByte = data[dataIndex++] & 0xFF;
                int lowByte = data[dataIndex++] & 0xFF;
                int rgb565 = (highByte << 8) | lowByte;

                // 将RGB565转换为RGB888
                int r = ((rgb565 >> 11) & 0x1F) << 3;
                int g = ((rgb565 >> 5) & 0x3F) << 2;
                int b = (rgb565 & 0x1F) << 3;

                int rgb = (r << 16) | (g << 8) | b;
                image.setRGB(x, y, rgb);
            }
        }

        return image;
    }


    public static void main(String[] args) throws IOException {
        // ... 原有代码 ...

        // 测试生成160*80画布，嵌入背景图片并居中显示文字
//        String text = "现在危险，停止救援紧急撤离至安全区域";
        String text = "现在危险，停止救援，紧急撤离至安全区域！";
        String backgroundImagePath = "D:\\background.png"; // 替换为实际背景图片路径
        byte[] imageData = generate160x80ImageWithText(text, backgroundImagePath, 25600);

        System.out.println("生成的160*80 RGB565图像数据:");
        System.out.println("数据长度: " + imageData.length + " 字节");
        // 生成预览图片
        // 生成预览图片
        BufferedImage image160x80 = convertByteArrayToImage(imageData, 80, 160);
        ImageIO.write(image160x80, "PNG", new File("D:\\bitmap_160x80_preview.png"));
//        System.out.println("成功生成160*80预览图片: D:\\bitmap_160x80_preview.png");
        // 转换为十进制数组
//        int[] decimalArray = convertHexToDecimal(imageData);
//        System.out.println("生成的十进制数据（前50个）:");
//        System.out.println(Arrays.toString(Arrays.copyOf(decimalArray, Math.min(50, decimalArray.length))));
//
//        // 将数据分割成512字节的块
//        List<byte[]> chunks = splitByteArrayIntoChunks(imageData, 512);
//        printChunkInfo(chunks);
//
//        // 示例：获取特定块的数据
//        byte[] specificChunk = getChunk(imageData, 0, 512); // 获取第1块（索引0）
//        System.out.println("第1块数据大小: " + specificChunk.length + " 字节");
    }

}
