package cn.com.tenlion.buildingpictures.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import java.awt.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

/**
 * 生成微信小程序二维码
 * 崔宝铖 2021年6月24日10:18:13
 */
public class WeiXinBarCodeUtils {

    private static BufferedImage getImage(Map<String, String> paramsMap, int colorR, int colorG, int colorB) throws IOException {
        String accessToken = getAccessToken(paramsMap.get("appid"), paramsMap.get("secret"));
        URL url = new URL("https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        // 发送POST请求必须设置如下两行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        //设置超时间为5秒
        conn.setConnectTimeout(5*1000);
        //防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        conn.connect();
        StringBuffer buffer = new StringBuffer();
        for (Map.Entry<String, String> k : paramsMap.entrySet()) {
            if(!"path".equals(k.getKey()) && !"appid".equals(k.getKey()) && !"secret".equals(k.getKey())) {
                if (buffer.length() < 1) {
                    buffer.append( k.getKey() + "=" + k.getValue());
                }else {
                    buffer.append("&" + k.getKey() + "=" + k.getValue());
                }
            }
        }
        String param = buffer.toString();
        //POST请求
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
        JSONObject obj = new JSONObject();
        obj.put("path", paramsMap.get("path") + (StringUtils.isEmpty(param) ? "" : "?" + param) );
        obj.put("width", 400);
//        这种方法微信有很多颜色不支持, 改用拿到图片缓存后替换二维码区域像素点
//        JSONObject colorObject = new JSONObject();
//        colorObject.put("r", colorR + "");
//        colorObject.put("g", colorG + "");
//        colorObject.put("b", colorB + "");
//        obj.put("auto_color", true);
//        obj.put("line_color", colorObject);
        out.writeBytes(obj.toString());
        out.flush();
        out.close();
        //得到输入流
        InputStream inputStream = conn.getInputStream();
        //获取自己数组
        byte[] getData = readInputStream(inputStream);
        System.out.println(new String(getData));
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(getData));
        // 如果没有设置颜色, 原图返回
//        if(colorR == 0 && colorG == 0 && colorB == 0) {
//            return image;
//        }
        /**
         * 将小程序二维码的主题颜色改为自定义颜色
         */
        Color color = new Color(colorR, colorG, colorB);
        // 设置背景为透明颜色
        BufferedImage weiXinImage = new BufferedImage(image.getWidth(), image.getHeight(),  BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = weiXinImage.createGraphics();
        //消除文字锯齿
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        //消除图片锯齿
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        weiXinImage = graphics.getDeviceConfiguration().createCompatibleImage(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
        Graphics imageGraphics = weiXinImage.getGraphics();
        for (int x = 0; x < weiXinImage.getWidth(); x++) {
            for (int y = 0; y < weiXinImage.getHeight(); y++) {
                int clr = image.getRGB(x, y);
                // 获得像素对象
                Object data = image.getRaster().getDataElements(x, y, null);
                int red = image.getColorModel().getRed(data);
                int blue = image.getColorModel().getBlue(data);
                int green = image.getColorModel().getGreen(data);
                if(red < 250 && blue < 250 &&  green < 250) {
                    if(red == 0 && blue == 0  &&  green == 0 ) {
                        // 自定义颜色
                        imageGraphics.setColor(color);
                        imageGraphics.drawRect( x, y, 1, 1);
                    }else {
                        // 原来的颜色
                        imageGraphics.setColor(new Color(clr));
                        imageGraphics.drawRect ( x, y, 1, 1);
                    }
                }
            }
        }
        //ImageIO.write(image, "jpg", new File("D:\\TEST1.jpg"));
        //ImageIO.write(weiXinImage, "jpg", new File("D:\\TEST2.jpg"));
        return weiXinImage;
    }

    /**
     * 生成小程序二维码
     * @param params 携带参数
     * @return
     * @throws IOException
     */
    public static BufferedImage getBarCodeImage(String params, int colorR, int colorG, int colorB) throws IOException {
        Map<String, String> paramsMap = new HashMap<String, String>();
        String[] paramsArray = params.split("&");
        for (String param : paramsArray) {
            String[] paramData = param.split("=");
            paramsMap.put(paramData[0], paramData[1]);
        }
        return getImage(paramsMap, colorR, colorG, colorB);
    }

    /**
     * 生成小程序二维码
     * @param appId appId
     * @param secret secret
     * @param path 小程序路径
     * @param width 尺寸
     * @return
     * @throws IOException
     */
    public static BufferedImage getBarCodeImage(String appId, String secret, String path, Integer width) throws IOException {
        Map<String, String> paramsMap = new HashMap<String, String>();
        paramsMap.put("path", path);
        paramsMap.put("appid", appId);
        paramsMap.put("secret", secret);
        BufferedImage weiXinImage =  getImage(paramsMap, 0, 0, 0);
        if(weiXinImage != null ) {
            return weiXinImage;
//            BufferedImage image = new BufferedImage(width, width, BufferedImage.TYPE_INT_RGB);
//            Graphics2D graphics = image.createGraphics();
//            // 消除文字锯齿
//            graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//            // 消除图片锯齿
//            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//            // 放大图片
//            image = graphics.getDeviceConfiguration().createCompatibleImage(image.getWidth(), image.getHeight(), Transparency.TRANSLUCENT);
//            Graphics imageGraphics = image.getGraphics();
//            // 放大图片
//            // 将头像放入模板中
//            imageGraphics.drawImage(weiXinImage, 0, 0, width, width, null);
//            return image;
        }
        return null;
    }


    /**
     * 图片压缩-按照固定宽高原图压缩
     * @Title : thumbnail
     * @功能描述 : TODO
     * @设定文件 : @param img 本地图片地址
     * @设定文件 : @param width 图片宽度
     * @设定文件 : @param height 图片高度
     * @设定文件 : @return
     * @设定文件 : @throws IOException
     * @返回类型 : Image
     * @throws :
     */
    private static Image thumbnailBufferdImage(BufferedImage BI, int width, int height) throws IOException {
        Image image = BI.getScaledInstance(width, height, Image.SCALE_SMOOTH);
        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        g.setColor(Color.RED);
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return image;
    }

    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

    /**
     * 获取accessToken
     * @param appId
     * @param secret
     * @return
     */
    private static String getAccessToken(String appId, String secret) {
        String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                + appId
                + "&secret="
                + secret;
        String result = HttpUtil.sendGet(url);
        JSONObject object = JSONObject.parseObject(result);
        String Access_Token = object.getString("access_token");
        return Access_Token;
    }
}
