package com.yida.data.common.core.utils;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.StrUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 二维码工具类
 *
 * @author ZYJ
 * @date 2021/8/23
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class QrCodeUtil {

    /**
     * 生成二维码图片
     *
     * @param text     需要生成的二维码的信息
     * @param width    二维码图片宽度
     * @param height   二维码图片高度
     * @param filePath 生成后的文件地址
     * @author ZYJ
     * @date 2021/8/23 14:16
     */
    public static void generateQrCodeImage(String text, int width, int height, String filePath)
        throws WriterException, IOException {
        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(generateBitMatrix(text, width, height), "PNG", path);
    }

    /**
     * @param text
     * @param width
     * @param height
     * @param logoUrl
     * @return
     * @throws WriterException
     * @throws IOException
     */
    public static String generateQrCodeBase64(String text, int width, int height, String logoUrl)
        throws WriterException, IOException {
        // 生成彩色图片
        MatrixToImageConfig config = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
        BufferedImage image = MatrixToImageWriter.toBufferedImage(generateBitMatrix(text, width, height), config);
        if (StrUtil.isNotBlank(logoUrl)) {
            String local = FileUtil.downloadToLocal(logoUrl);
            image = addlogo(image, new File(local));
        }
        return ImgUtil.toBase64(image, "png");
    }

    private static BufferedImage addlogo(BufferedImage bf, File logoFile) throws IOException {
        /**
         * 读取二维码图片，并构建绘图对象
         */
        Graphics2D g2 = bf.createGraphics();
        int matrixWidth = bf.getWidth();
        int matrixHeigh = bf.getHeight();
        /**
         * 读取Logo图片
         */
        BufferedImage logo = ImageIO.read(logoFile);
//        BufferedImageGraphicsConfig config = BufferedImageGraphicsConfig.getConfig(logo);
//        logo = config.createCompatibleImage(logo.getWidth(), logo.getHeight(), Transparency.OPAQUE);

        //开始绘制图片
        g2.drawImage(logo, matrixWidth / 5 * 2, matrixHeigh / 5 * 2, matrixWidth / 5, matrixHeigh / 5, null);//绘制
        BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke);// 设置笔画对象
        //指定弧度的圆角矩形
        RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth / 5 * 2, matrixHeigh / 5 * 2,
            matrixWidth / 5, matrixHeigh / 5, 20, 20);
        g2.setColor(Color.white);
        g2.draw(round);// 绘制圆弧矩形
        //设置logo 有一道灰色边框
        BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke2);// 设置笔画对象
        RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth / 5 * 2 + 2, matrixHeigh / 5 * 2 + 2,
            matrixWidth / 5 - 4, matrixHeigh / 5 - 4, 20, 20);
        g2.setColor(new Color(128, 128, 128));
        g2.draw(round2);// 绘制圆弧矩形
        g2.dispose();
        bf.flush();
        return bf;
    }

    private static BitMatrix generateBitMatrix(String text, int width, int height) throws WriterException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        //内容编码格式
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        // 指定纠错等级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //设置二维码边的空度，非负数
        hints.put(EncodeHintType.MARGIN, 0);
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        return bitMatrix;
    }

}
