package com.nasc.web.controller.tool;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;

import javax.imageio.ImageIO;
import javax.xml.bind.DatatypeConverter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Base64;
import java.util.Random;

public class BarcodeGenerator {

    public static String generateBarcodeWithTextAsBase64(String content, int barcodeWidth, int barcodeHeight, int textHeight, int textPadding, String textFont) throws WriterException, IOException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());

        BitMatrix bitMatrix = new Code128Writer().encode(content, BarcodeFormat.CODE_128, barcodeWidth, barcodeHeight, hints);

        // Create a buffered image to draw the barcode and text
        int imageHeight = barcodeHeight + textHeight + textPadding;
        BufferedImage bufferedImage = new BufferedImage(barcodeWidth, imageHeight, BufferedImage.TYPE_BYTE_BINARY);

        // Fill the background with white
        Graphics2D g2d = bufferedImage.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, barcodeWidth, imageHeight);

        // Draw the barcode
        for (int x = 0; x < bitMatrix.getWidth(); x++) {
            for (int y = 0; y < bitMatrix.getHeight(); y++) {
                if (bitMatrix.get(x, y)) {
                    bufferedImage.setRGB(x, y, new Color(0, 0, 0).getRGB());
                }
            }
        }

        // Set the font for the text
        Font font = new Font(textFont, Font.PLAIN, textHeight);
        g2d.setFont(font);
        g2d.setColor(Color.BLACK);

        // Calculate the text position (centered horizontally)
        FontMetrics fontMetrics = g2d.getFontMetrics();
        int textX = (barcodeWidth - fontMetrics.stringWidth(content)) / 2;
        int textY = barcodeHeight + (textPadding - fontMetrics.getDescent()) / 2 + fontMetrics.getAscent(); // Center text vertically within the padding

        // Draw the text
        g2d.drawString(content, textX, textY);

        // Dispose the graphics object
        g2d.dispose();

        // Convert the buffered image to a byte array and encode it as Base64
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "PNG", byteArrayOutputStream);
        byte[] imageBytes = byteArrayOutputStream.toByteArray();
        return Base64.getEncoder().encodeToString(imageBytes);
    }

    public static String generateBarcodeAsBase64(String content, int width, int height) throws WriterException, IOException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());

        BitMatrix bitMatrix = new Code128Writer().encode(content, BarcodeFormat.CODE_128, width, height, hints);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", byteArrayOutputStream);

        byte[] imageBytes = byteArrayOutputStream.toByteArray();
        return DatatypeConverter.printBase64Binary(imageBytes);
    }

    public static String shuffleString(String str) {
        // 将字符串转换为字符数组
        char[] charArray = str.toCharArray();
        // 创建一个随机数生成器
        Random random = new Random();
        // 使用Fisher-Yates洗牌算法来打乱字符数组
        for (int i = charArray.length - 1; i > 0; i--) {
            // 生成一个0到i之间的随机索引
            int randomIndex = random.nextInt(i + 1);
            // 交换charArray[i]和charArray[randomIndex]
            char temp = charArray[i];
            charArray[i] = charArray[randomIndex];
            charArray[randomIndex] = temp;
        }
        // 将字符数组转换回字符串
        return new String(charArray);
    }

}