package com.jeeplus.modules.warehouse.qrcode.util;


import com.jeeplus.common.utils.text.EscapeUtil;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.warehouse.goods.entity.GoodsInfo;
import com.jeeplus.modules.warehouse.profitwarehousing.entity.ProfitWarehousingInfo;
import com.jeeplus.modules.warehouse.qrcode.entity.QrCode;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import javax.imageio.*;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.AttributedString;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Locale;

public class DrawQrcodeUtil {
    /**
     * 1英寸是2.54里面
     */
    private static final double INCH_2_CM = 2.54d;
    public static final int M86_53 = 1;
    public static final int M110_90 = 2;
    public static final int M220_140 = 3;
    public static final int M250_160 = 4;
    public static final int A86_53 = 5;
    public static final int A110_90 = 6;
    public static final int A220_140 =7;
    public static final int A250_160 = 8;
    public static final int C86_53 =9;
    public static final int C110_90 =10;
    public static final int C220_140 = 11;
    public static final int C250_160 = 12;
    @Test
    public void test() throws IOException {
        int dpi = 300;
        QrCode qrCode = new QrCode();
        File backGroundImg = new File("H:\\qrcodeBG\\86-53.png");
        File qrcodeFile = new File("H:\\qrcodeBG\\qrcode-viewfile.png");

        Office office = new Office();
        office.setId("123");
        office.setName("测试数据公司一");
        /*asset.setBelongUnit(office);
        asset.setName("测试资产名称一");
        asset.setModelNum("NPL-C370-9965-432");
        asset.setNum("0000-2016-12051-001");*/

        BufferedImage bufferedImage = createAssetImageNew(qrcodeFile,qrCode);

        System.out.println("height"+bufferedImage.getHeight());
        System.out.println("Tileheight"+bufferedImage.getTileHeight());
        System.out.println("getWidth"+bufferedImage.getWidth());
        System.out.println("TileWidth"+bufferedImage.getTileWidth());

        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName("png"); iw.hasNext();){
            ImageWriter writer = iw.next();
            ImageWriteParam writeParam = writer.getDefaultWriteParam();
            ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
            IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
            if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
                continue;
            }
            //ByteArrayOutputStream output = new ByteArrayOutputStream();
            FileOutputStream output = new FileOutputStream(new File("H:\\qrcode-86-53.png"));
            ImageOutputStream stream = null;
            try {
                setDPI(metadata, dpi);
                stream = ImageIO.createImageOutputStream(output);
                writer.setOutput(stream);
                writer.write(metadata, new IIOImage(bufferedImage, null, metadata), writeParam);
            } finally {
                try {
                    stream.close();
                } catch (IOException e) {
                }
            }
            //return output.toByteArray();
        }
        //ImageIO.write(bufferedImage, "PNG", new File("H:\\qrcode-86-53.png"));
    }

    public void writeImage(BufferedImage bufferedImage,String path) throws FileNotFoundException {
        int dpi = 300;
        for (Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName("png"); iw.hasNext();){
            ImageWriter writer = iw.next();
            ImageWriteParam writeParam = writer.getDefaultWriteParam();
            ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
            IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
            if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
                continue;
            }
            //ByteArrayOutputStream output = new ByteArrayOutputStream();
            FileOutputStream output = new FileOutputStream(new File(path));
            ImageOutputStream stream = null;
            try {
                setDPI(metadata, dpi);
                stream = ImageIO.createImageOutputStream(output);
                writer.setOutput(stream);
                writer.write(metadata, new IIOImage(bufferedImage, null, metadata), writeParam);
            } catch (IIOInvalidTreeException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    stream.close();
                    output.flush();
                    output.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private void setDPI(IIOMetadata metadata, int dpi) throws IIOInvalidTreeException {
        // for PMG, it's dots per millimeter
        double dotsPerMilli = 1.0 * dpi / 10 / INCH_2_CM;
        IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
        horiz.setAttribute("value", Double.toString(dotsPerMilli));

        IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
        vert.setAttribute("value", Double.toString(dotsPerMilli));

        IIOMetadataNode dim = new IIOMetadataNode("Dimension");
        dim.appendChild(horiz);
        dim.appendChild(vert);

        IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
        root.appendChild(dim);

        metadata.mergeTree("javax_imageio_1.0", root);
    }

    private static class QRcodeSize{
        private int initfontSize;
        private int initContentX;
        private int initContentY;
        private int initContentYIncrement;
        private int qrcodeX;
        private int qrcodeY;
        private int qrcodeWidth;
        private int qrcodeHeight;
        private Color color;

        public QRcodeSize(int initfontSize, int initContentX, int initContentY, int initContentYIncrement, int qrcodeX, int qrcodeY, int qrcodeWidth, int qrcodeHeight,Color color) {
            this.initfontSize = initfontSize;
            this.initContentX = initContentX;
            this.initContentY = initContentY;
            this.initContentYIncrement = initContentYIncrement;
            this.qrcodeX = qrcodeX;
            this.qrcodeY = qrcodeY;
            this.qrcodeWidth = qrcodeWidth;
            this.qrcodeHeight = qrcodeHeight;
            this.color = color;
        }

        public int getInitfontSize() {
            return initfontSize;
        }

        public void setInitfontSize(int initfontSize) {
            this.initfontSize = initfontSize;
        }

        public int getInitContentX() {
            return initContentX;
        }

        public void setInitContentX(int initContentX) {
            this.initContentX = initContentX;
        }

        public int getInitContentY() {
            return initContentY;
        }

        public void setInitContentY(int initContentY) {
            this.initContentY = initContentY;
        }

        public int getInitContentYIncrement() {
            return initContentYIncrement;
        }

        public void setInitContentYIncrement(int initContentYIncrement) {
            this.initContentYIncrement = initContentYIncrement;
        }

        public int getQrcodeX() {
            return qrcodeX;
        }

        public void setQrcodeX(int qrcodeX) {
            this.qrcodeX = qrcodeX;
        }

        public int getQrcodeY() {
            return qrcodeY;
        }

        public void setQrcodeY(int qrcodeY) {
            this.qrcodeY = qrcodeY;
        }

        public int getQrcodeWidth() {
            return qrcodeWidth;
        }

        public void setQrcodeWidth(int qrcodeWidth) {
            this.qrcodeWidth = qrcodeWidth;
        }

        public int getQrcodeHeight() {
            return qrcodeHeight;
        }

        public void setQrcodeHeight(int qrcodeHeight) {
            this.qrcodeHeight = qrcodeHeight;
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }
    }

    // D:/jeeplus/userfiles/1/程序附件/image/500107-2023-07-0011.png
    public static BufferedImage createAssetImageNew(File qrcodeFile,QrCode qrCode) throws IOException {
        GoodsInfo goodsInfo = qrCode.getGoodsInfo();
        QRcodeSize qRcodeSize = null;
        qRcodeSize = new QRcodeSize(8,800,1800,78,800,200,1600,1600,new Color(34,25,21));
//        BufferedImage bgImage = new BufferedImage(1600, 2400, BufferedImage.TYPE_4BYTE_ABGR);
        BufferedImage bgImage = new BufferedImage(3200, 2400, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = bgImage.createGraphics();
        BufferedImage qrcodeImage = ImageIO.read(qrcodeFile);

        RenderingHints rh=new RenderingHints(RenderingHints. KEY_ANTIALIASING,
                RenderingHints. VALUE_ANTIALIAS_ON);
        rh.put(RenderingHints.KEY_STROKE_CONTROL
                , RenderingHints.VALUE_STROKE_PURE);
        rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
                , RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2.setRenderingHints(rh);

        Font font = new Font("等线",Font.PLAIN,100);

        g2.setFont(font); //设置字体:字体、字号、大小
        g2.setColor(qRcodeSize.color);//设置背景颜色
//        g2.setBackground(c);
        int contentX = qRcodeSize.getInitContentX();
        int contentY = qRcodeSize.getInitContentY() + 150;
        //写二维码
        g2.drawImage(qrcodeImage,qRcodeSize.getQrcodeX(),qRcodeSize.getQrcodeY(),qRcodeSize.getQrcodeWidth(),qRcodeSize.getQrcodeHeight(),null,null);

        //写入货品名称
        String contentTitle1 = "品名：";
        int contentTitle1Width = g2.getFontMetrics().stringWidth(contentTitle1);
        g2.drawString(contentTitle1,contentX,contentY);
        String name = formatContent(goodsInfo.getType().getName(),10);
        AttributedString as = new AttributedString(name);
        as.addAttribute(TextAttribute.FONT, font);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, name.length());
        g2.drawString(as.getIterator(),contentX+contentTitle1Width,contentY);
        //写入货品类型
       /* String contentTitle2 = "货品类型：";
        int contentTitle2Width = g2.getFontMetrics().stringWidth(contentTitle2);
        g2.drawString(contentTitle2,contentX,contentY+150);
        String typeName = goodsInfo.getType().getName();
        if (typeName.length() > 8) {
            String str1 = typeName.substring(0, 8);
            str1 = formatContent(str1,9);
            as = new AttributedString(str1);
            as.addAttribute(TextAttribute.FONT, font);
            as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, str1.length());
            g2.drawString(as.getIterator(),contentX+contentTitle2Width,contentY+150);
            String str2 = typeName.substring(8, typeName.length());
            str2 = formatContent(str2,9);
            as = new AttributedString(str2);
            as.addAttribute(TextAttribute.FONT, font);
            as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, str2.length());
            g2.drawString(as.getIterator(),contentX+contentTitle2Width,contentY+300);

        } else {
            typeName = formatContent(goodsInfo.getType().getName(),10);
            as = new AttributedString(typeName);
            as.addAttribute(TextAttribute.FONT, font);
            as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, typeName.length());
            g2.drawString(as.getIterator(),contentX+contentTitle2Width,contentY+150);

        }*/




        //写入物资编码
        String contentTitle4 = "物资编码：";
        int contentTitle4Width = g2.getFontMetrics().stringWidth(contentTitle4);
        g2.drawString(contentTitle4,contentX,contentY+150);
        String code = qrCode.getCode();
        as = new AttributedString(code);
        as.addAttribute(TextAttribute.FONT, font);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, code.length());
        g2.drawString(as.getIterator(),contentX+contentTitle4Width,contentY+150);


        return bgImage;
    }
    public static BufferedImage createAssetImageNew2(File qrcodeFile,QrCode qrCode) throws IOException {
        ProfitWarehousingInfo profitWarehousingInfo = qrCode.getProfitWarehousingInfo();
        QRcodeSize qRcodeSize = null;
        qRcodeSize = new QRcodeSize(8,800,1800,78,800,200,1600,1600,new Color(34,25,21));
//        BufferedImage bgImage = new BufferedImage(1600, 2400, BufferedImage.TYPE_4BYTE_ABGR);
        BufferedImage bgImage = new BufferedImage(3200, 2400, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = bgImage.createGraphics();
        BufferedImage qrcodeImage = ImageIO.read(qrcodeFile);

        RenderingHints rh=new RenderingHints(RenderingHints. KEY_ANTIALIASING,
                RenderingHints. VALUE_ANTIALIAS_ON);
        rh.put(RenderingHints.KEY_STROKE_CONTROL
                , RenderingHints.VALUE_STROKE_PURE);
        rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
                , RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2.setRenderingHints(rh);

        Font font = new Font("等线",Font.PLAIN,100);
        g2.setFont(font); //设置字体:字体、字号、大小
        g2.setColor(qRcodeSize.color);//设置背景颜色
//        g2.setBackground(c);
        int contentX = qRcodeSize.getInitContentX();
        int contentY = qRcodeSize.getInitContentY() + 150;
        //写二维码
        g2.drawImage(qrcodeImage,qRcodeSize.getQrcodeX(),qRcodeSize.getQrcodeY(),qRcodeSize.getQrcodeWidth(),qRcodeSize.getQrcodeHeight(),null,null);

        //写入货品名称
        String contentTitle1 = "货品名称：";
        int contentTitle1Width = g2.getFontMetrics().stringWidth(contentTitle1);
        g2.drawString(contentTitle1,contentX,contentY);
        String name = formatContent(profitWarehousingInfo.getType().getName(),10);
        AttributedString as = new AttributedString(name);
        as.addAttribute(TextAttribute.FONT, font);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, name.length());
        g2.drawString(as.getIterator(),contentX+contentTitle1Width,contentY);


        String contentTitle4 = "物资编码：";
        int contentTitle4Width = g2.getFontMetrics().stringWidth(contentTitle4);
        g2.drawString(contentTitle4,contentX,contentY+150);
        String code = qrCode.getCode();
        as = new AttributedString(code);
        as.addAttribute(TextAttribute.FONT, font);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, code.length());
        g2.drawString(as.getIterator(),contentX+contentTitle4Width,contentY+150);



        return bgImage;
    }

    /**
     *  生成二维码包装图片
     *  @param bgImg 背景图片
     *  @param logo  头部logo
     *  @param qrCode 资产二维码
     *  @param qc
     * */

    public static BufferedImage createAssetImage(File bgImg, InputStream logo, InputStream qrCode,InputStream luqiaoLogo, QrCode qc, int coefficint) throws IOException {
        GoodsInfo goodsInfo = qc.getGoodsInfo();
        // 220   宽：2598---- 高：1654  2.56
        // 110   宽：1299  高 827   1.28
        //default 宽：1016   高 626
        double cfwidth,cfheight;
        Color c;
        switch (coefficint){
            case 2:
                cfwidth = 1.28;
                cfheight = 1.32;
                c = new Color(38,60,146);
                break;
            case 3:
                cfwidth = 2.56;
                cfheight = 2.64;
                c = new Color(38,60,146);
                break;
            default:
                cfwidth = 1;
                cfheight = 1;
                c = Color.WHITE;
                break;
        }


        BufferedImage bgImage = ImageIO.read(bgImg);

        BufferedImage logoImage = ImageIO.read(logo);
        BufferedImage qrcodeImage = ImageIO.read(qrCode);

        BufferedImage luqiaoLogoImage = ImageIO.read(luqiaoLogo);
        //得到它的绘制环境(这张图片的笔)
        Graphics2D g2 = (Graphics2D) bgImage.getGraphics();

        RenderingHints rh=new RenderingHints(RenderingHints. KEY_ANTIALIASING,
                RenderingHints. VALUE_ANTIALIAS_ON);
        rh.put(RenderingHints.KEY_STROKE_CONTROL
                , RenderingHints.VALUE_STROKE_PURE);
        rh.put(RenderingHints.KEY_ALPHA_INTERPOLATION
                , RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2.setRenderingHints(rh);

        Font font = new Font("黑体",Font.BOLD,(int)(64 * cfwidth));

        g2.setFont(font); //设置字体:字体、字号、大小
        g2.setColor(c);//设置背景颜色

        String name = goodsInfo.getName();
        String typeName = goodsInfo.getType().getName();
        String model = goodsInfo.getModel();
        String code = qc.getCode();
        /*String assetNum = "JZLQ02-2018-2315-001";
        String assetName = "压路机";
        String zerenren = "李四";
        String chuciqiyongriqi = "2018-06-25";*/
        int contentX = (int)Math.round(60*cfwidth);
        int contentY = (int)Math.round(260*cfheight);

        Font contentFont = new Font("黑体",Font.BOLD,(int)Math.round(28*cfwidth));
        g2.setFont(contentFont); //设置字体:字体、字号、大小
        g2.setColor(c);//设置字体颜色


        //写入货品名称
        String contentTitle1 = "货品名称：";
        int contentTitle1Width = g2.getFontMetrics().stringWidth(contentTitle1);
        g2.drawString(contentTitle1,contentX,contentY);
        name = formatContent(name,21);
        AttributedString as = new AttributedString(name);
        as.addAttribute(TextAttribute.FONT, contentFont);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, name.length());
        g2.drawString(as.getIterator(),contentX+contentTitle1Width,contentY);

        //写入货品类型
        String contentTitle2 = "货品类型：";
        int contentTitle2Width = g2.getFontMetrics().stringWidth(contentTitle2);
        g2.drawString(contentTitle2,contentX,contentY+(int)(100*cfheight));
        typeName = formatContent(typeName,21);
        as = new AttributedString(typeName);
        as.addAttribute(TextAttribute.FONT, contentFont);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, typeName.length());
        g2.drawString(as.getIterator(),contentX+contentTitle2Width,contentY+(int)Math.round(100*cfheight));

        //写入规格型号
        String contentTitle3 = "规格型号：";
        int contentTitle3Width = g2.getFontMetrics().stringWidth(contentTitle3);
        g2.drawString(contentTitle3,contentX,contentY+(int)Math.round(200*cfheight));
        model = formatContent(model,21);
        as = new AttributedString(model);
        as.addAttribute(TextAttribute.FONT, contentFont);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, model.length());
        g2.drawString(as.getIterator(),contentX+contentTitle3Width,contentY+(int)Math.round(200*cfheight));

        //写入物资编码
        String contentTitle4 = "物资编码：";
        int contentTitle4Width = g2.getFontMetrics().stringWidth(contentTitle4);
        g2.drawString(contentTitle4,contentX,contentY+(int)Math.round(200*cfheight));
        model = formatContent(model,21);
        as = new AttributedString(model);
        as.addAttribute(TextAttribute.FONT, contentFont);
        as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_DASHED, 0, model.length());
        g2.drawString(as.getIterator(),contentX+contentTitle4Width,contentY+(int)Math.round(200*cfheight));

        //写二维码
        g2.drawImage(qrcodeImage,(int)Math.round(640*cfwidth),(int)Math.round(250*cfheight),(int)Math.round(300*cfwidth),(int)Math.round(300*cfheight),null,null);

        //写入二维码中的logo
        g2.drawImage(luqiaoLogoImage,(int)Math.round(760*cfwidth),(int)Math.round(370*cfheight),(int)Math.round(60*cfwidth),(int)Math.round(60*cfheight),null,null);
        return bgImage;
    }

    /**
     * 字符长度若不足指定长度，在字符串后添加空格
     * @param str
     * @param length 指定长度
     */
    public static String formatContent(String str,int length){
        try {
            int trueSize = getChineseLength(str,"utf-8");
            if(trueSize<length){
                int count = length - trueSize;
                for(int i = 0;i<count;i++){
                    str = str+" ";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 获中英文混合状态下字符串的实际长度。例如 "你好1" 实际长度为5
     * @param str
     * @param endcoding 字符串的字符编码
     */
    public static int getChineseLength(String str, String endcoding) throws Exception {
        int len = 0; //定义返回的字符串长度
        int j = 0;
        //按照指定编码得到byte[]
        byte[] b_name = str.getBytes(endcoding);
        do {
            short tmpst = (short) (b_name[j] & 0xF0);
            if (tmpst >= 0xB0) {
                if (tmpst < 0xC0) {
                    j += 2;
                    len += 2;
                } else if ((tmpst == 0xC0) || (tmpst == 0xD0)) {
                    j += 2;
                    len += 2;
                } else if (tmpst == 0xE0) {
                    j += 3;
                    len += 2;
                } else {
                    short tmpst0 = (short) (((short) b_name[j]) & 0x0F);
                    if (tmpst0 == 0) {
                        j += 4;
                        len += 2;
                    } else if (tmpst0 < 12) {
                        j += 5;
                        len += 2;
                    } else {
                        j += 6;
                        len += 2;
                    }
                }
            } else {
                j += 1;
                len += 1;
            }
        } while (j <= b_name.length - 1);
        return len;
    }

    /**
     * 设置字符的间距
     * @param str 要写入的字符串
     * @param x 字符串写入的位置
     * @param y 字符串写入的位置
     * @param rate 设置字符串间距倍数，例如1.2
     * @param g 画布类对象
     *
     * */
    public static void MyDrawString(String str,int x,int y,double rate,Graphics g){
        String tempStr=new String();
        int orgStringWight=g.getFontMetrics().stringWidth(str);
        int orgStringLength=str.length();
        int tempx=x;
        int tempy=y;
        while(str.length()>0) {
            tempStr=str.substring(0, 1);
            str=str.substring(1, str.length());
            g.drawString(tempStr, tempx, tempy);
            tempx=(int)(tempx+(double)orgStringWight/(double)orgStringLength*rate);
        }
    }

}
