package com.sagacloud.utils.qrCode;
/*
 * Author: Jxing
 * Create Time: 2019/2/27
 */

import com.aliyun.oss.internal.OSSUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sagacloud.utils.ExternalUrl;
import com.sagacloud.utils.HttpRequestUtil;
import com.sagacloud.utils.OssUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class QRCodeObj {
    public static boolean autoGenerateQRCode ;
    static {
        try {
            autoGenerateQRCode = Boolean.parseBoolean(OssUtils.getProperty("auto.generate.qrcode"));
        }catch (Exception ex){
            autoGenerateQRCode = true;
        }
    }
    private int qrCodeSize = 400, logoSize = 60;
    private boolean isOverwrite = false;
    private Image logoImage;
    private Map<String, String> idFilekeyMap;

    public QRCodeObj(Map<String, String> idFilekeyMap, int qrCodeSize, int logoSize, boolean isOverwrite, String logoUrl) {
//        this.idFilekeyMap = idFilekeyMap;
//        logoImage = QRCodeUtil.getImage(logoUrl);
        this(idFilekeyMap, qrCodeSize, logoSize, isOverwrite, QRCodeUtil.getImage(logoUrl));
//        if(qrCodeSize >= 100 && qrCodeSize <= 5000){
//            this.qrCodeSize = qrCodeSize;
//        }
//        if (logoSize >= 10 && logoSize <= (int) Math.sqrt(this.qrCodeSize * this.qrCodeSize * 0.3)) {
//            this.logoSize = logoSize;
//        }
    }

    public QRCodeObj(Map<String, String> idFilekeyMap, int qrCodeSize, int logoSize, boolean isOverwrite, Image logoImage) {
        this.idFilekeyMap = idFilekeyMap;
        this.logoImage = logoImage;
        this.isOverwrite = isOverwrite;
        if(QRCodeUtil.isQRSizeQualified(qrCodeSize)){
            this.qrCodeSize = qrCodeSize;
        }
        if (QRCodeUtil.isLogoSizeQualified(this.qrCodeSize, logoSize)) {
            this.logoSize = logoSize;
        }
    }

    public void submit(Map<String, String> errorInfo){
        // key --> 对象id, value --> errorInfo
        for(String id : idFilekeyMap.keySet()) {
            try {
                String key = String.join("", "http://meos.sagacloud.cn/scan?key=", id);
                BufferedImage image = createImageFromFile(key, logoImage,  true);
                String result = HttpRequestUtil.sendImageFile(ExternalUrl.getFileUpload(idFilekeyMap.get(id), isOverwrite), image);
                if(!result.contains("success")){
                    if(result.contains("existed")){
                        errorInfo.put(id, "已存在图片");
                    }else {
                        errorInfo.put(id, "图片服务器异常");
                    }
                }
            } catch (Exception e) {
                errorInfo.put(id, "上传到图片服务器失败");
            }
        }
    }

    /**
     * 生成二维码的方法
     *
     * @param content      目标URL
     * @param imgFile      LOGO图片地址
     * @param needCompress 是否压缩LOGO
     * @return 二维码图片
     * @throws Exception
     */
    public BufferedImage createImageFromFile(String content, Image imgFile,
                                                    boolean needCompress) throws Exception {
        Hashtable hints = new Hashtable();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, QRCodeUtil.CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
                        : 0xFFFFFFFF);
            }
        }
        if (imgFile == null) {
            return image;
        }
        // 插入图片
        insertImageFromImage(image, imgFile, needCompress);
        return image;
    }


    /**
     * 插入LOGO
     *
     * @param source       二维码图片
     * @param imgFile      LOGO图片文件
     * @param needCompress 是否压缩
     * @throws Exception
     */
    private void insertImageFromImage(BufferedImage source, Image imgFile,
                                             boolean needCompress) throws Exception {

        Image src = imgFile;
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        if (needCompress) { // 压缩LOGO
            if (width > logoSize) {
                width = logoSize;
            }
            if (height > logoSize) {
                height = logoSize;
            }
            Image image = src.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            src = image;
        }
        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (qrCodeSize - width) / 2;
        int y = (qrCodeSize - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }
}
