package com.jeequan.jeepay.bizcommons.manage.qrshell;

import com.alibaba.fastjson.JSON;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;

/**
* shellA 图片生成器
*
* @author terrfly
* @date 2022/1/17 17:36
*/
@Data
@Service
public class ShellAGenerator extends AbstractGenerator {

    /** 生成二维码图片的 buffer缓冲值 **/
    @Override
    public BufferedImage genQrImgBuffer(String configModelStr, String qrUrlContent, Long qrcId, String mchStoreName, boolean isViewFlag) throws IOException, WriterException {

        CommonConfigModel configModel = JSON.parseObject(configModelStr, CommonConfigModel.class);

        String qrId = "No." + qrcId.toString();

        //图片的宽和高
        int imgWidth = 308 * 3;  //924
        int imgHeight = 450 * 3; //1350

        BufferedImage bufferedImage = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);

        //设置： 全局背景颜色为白色
        Graphics2D graphic = bufferedImage.createGraphics();
        graphic.setColor(Color.white);//背景设置为白色
        graphic.fillRect(0, 0, imgWidth, imgHeight);
        graphic.drawRenderedImage(bufferedImage, null);
        graphic.dispose();

        //设置： 二维码背景颜色
        graphic = bufferedImage.createGraphics();
        graphic.setColor( new Color(Integer.parseInt(StringUtils.defaultIfEmpty(configModel.getBgColor(), "#5094d5").substring(1),16)) );//背景色的设置
        graphic.fillRect(0, 330, imgWidth, 825);
        graphic.drawRenderedImage(bufferedImage, null);
        graphic.dispose();

        //设置：二维码上的文字
        if(StringUtils.isNotEmpty(configModel.getDescText())){
            graphic = bufferedImage.createGraphics();
            graphic.setColor(Color.black);//背景设置为白色

            Font font = new Font(AbstractGenerator.DEFAULT_FONT, Font.PLAIN, 48);
            FontMetrics metrics = graphic.getFontMetrics(font);
            int x =  (imgWidth - metrics.stringWidth(configModel.getDescText())) / 2;

            graphic.setFont(font); //字体、字型、字号
            graphic.drawString(configModel.getDescText(), x, 300); //画文字
            graphic.drawRenderedImage(bufferedImage, null);
            graphic.dispose();
        }


        if(configModel.isShowIdFlag()){
            //设置：二维码编号
            graphic = bufferedImage.createGraphics();
            graphic.setColor(Color.white);//背景设置为白色

            Font qrIdFont = new Font(AbstractGenerator.DEFAULT_FONT, Font.PLAIN, 27);
            FontMetrics metrics = graphic.getFontMetrics(qrIdFont);
            int x =  (imgWidth - metrics.stringWidth(qrId)) / 2;

            graphic.setFont(qrIdFont); //字体、字型、字号
            graphic.drawString(qrId , x, 1100); //画文字
            graphic.drawRenderedImage(bufferedImage, null);
            graphic.dispose();
        }

        //设置：二维码背景图
        BufferedImage waterImg = getStaticImg("/shellA/i_bg.png"); //水印图片
        graphic = bufferedImage.createGraphics();
        graphic.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); //alpha 水印的透明度  0完全透明， 1不透明
        graphic.drawImage(waterImg, 120, 400, waterImg.getWidth(), waterImg.getHeight(), null);
        graphic.dispose();

        //顶部 logo
        List<BufferedImage> topImgArray = new ArrayList<>();
        if(configModel.getPayTypeList() != null){
            for (CommonConfigModel.PayType payType : configModel.payTypeList) {
                if("unionpay".equals(payType.getName()) || "ysfpay".equals(payType.getName())  ||"wxpay".equals(payType.getName()) || "alipay".equals(payType.getName()) ){
                    topImgArray.add(getStaticImg("/commons/" + "t_" + payType.getName() + ".png"));
                }else{
                    File imgFile = downloadAndGetCacheFile(payType.getImgUrl()); // 下载图片
                    if(imgFile != null){
                        topImgArray.add(ImageIO.read(imgFile));
                    }
                }
            }
        }

        List<int[]> areaArrays = getPayTypeLocation(topImgArray.size());
        if(areaArrays != null && !areaArrays.isEmpty()){
            for (int i = 0; i < areaArrays.size() ;i++) {
                BufferedImage waterImg1 = topImgArray.get(i); //水印图片
                graphic = bufferedImage.createGraphics();
                graphic.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); //alpha 水印的透明度  0完全透明， 1不透明
                graphic.drawImage(waterImg1, areaArrays.get(i)[0], areaArrays.get(i)[1], waterImg1.getWidth(), waterImg1.getHeight(), null);
                graphic.dispose();

            }
        }

        //设置：二维码 190X190
        //生成真实的二维码图片
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode(qrUrlContent, BarcodeFormat.QR_CODE, 570, 570, hints);// 生成矩阵
        BufferedImage waterQrImg = MatrixToImageWriter.toBufferedImage(bitMatrix);

        graphic = bufferedImage.createGraphics();
        graphic.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); //alpha 水印的透明度  0完全透明， 1不透明
        graphic.drawImage(waterQrImg, 178, 466, waterQrImg.getWidth(), waterQrImg.getHeight(), null);
        graphic.dispose();


        //二维码中间logo
        if(StringUtils.isNotEmpty(configModel.getQrInnerImgUrl() )){

            File imgFile = downloadAndGetCacheFile(configModel.getQrInnerImgUrl());
            if(imgFile != null){
                //设置：底部logo
                BufferedImage waterLogo = ImageIO.read(imgFile); //水印图片
                graphic = bufferedImage.createGraphics();
                graphic.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); //alpha 水印的透明度  0完全透明， 1不透明
                graphic.drawImage(waterLogo, 420, 666, 80, 80, null);
                graphic.dispose();
            }
        }

        //底部logo
        if(StringUtils.isNotEmpty(configModel.getLogoImgUrl() )){

            File imgFile = downloadAndGetCacheFile(configModel.getLogoImgUrl());
            if(imgFile != null){
                //设置：底部logo
                BufferedImage waterLogo = ImageIO.read(imgFile); //水印图片
                graphic = bufferedImage.createGraphics();
                graphic.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); //alpha 水印的透明度  0完全透明， 1不透明

                int bottomHeight = imgHeight - 330 - 825; //底部背景高度
                int graphicHeight = 330 + 825 + ((bottomHeight - waterLogo.getHeight()) / 2); //画图的高度

                graphic.drawImage(waterLogo, ((imgWidth-waterLogo.getWidth()) / 2) ,  graphicHeight, waterLogo.getWidth(), waterLogo.getHeight(), null);
                graphic.dispose();
            }
        }

        // 预览需要缩小三倍
        return isViewFlag ? zoomOutImage(bufferedImage, 2) : bufferedImage;
    }


    public static BufferedImage zoomOutImage(BufferedImage originalImage, Integer times){

        int width = originalImage.getWidth()/times;
        if(width < 0){
            width=originalImage.getWidth();
        }
        int height = originalImage.getHeight()/times;
        if(height < 0){
            height=originalImage.getHeight();
        }
        BufferedImage newImage = new BufferedImage(width,height,originalImage.getType());

        Graphics g = newImage.getGraphics();

        g.drawImage(originalImage, 0,0,width,height,null);

        g.dispose();

        return newImage;

    }


    /**
     *
     * @Title: 构造图片
     * @Description: 生成水印并返回java.awt.image.BufferedImage
     * @param file
     *            源文件(图片)
     * @param waterFile
     *            水印文件(图片)
     * @param x
     *            距离右下角的X偏移量
     * @param y
     *            距离右下角的Y偏移量
     * @param alpha
     *            透明度, 选择值从0.0~1.0: 完全透明~完全不透明
     * @return BufferedImage
     * @throws IOException
     */
    public static BufferedImage watermark(File file, File waterFile, int x, int y, float alpha) throws IOException {
        // 获取底图
        BufferedImage buffImg = ImageIO.read(file);
        // 获取层图
        BufferedImage waterImg = ImageIO.read(waterFile);
        // 创建Graphics2D对象，用在底图对象上绘图
        Graphics2D g2d = buffImg.createGraphics();
        int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
        int waterImgHeight = waterImg.getHeight();// 获取层图的高度
        // 在图形和图像中实现混合和透明效果
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
        // 绘制
        g2d.drawImage(waterImg, x, y, waterImgWidth, waterImgHeight, null);
        g2d.dispose();// 释放图形上下文使用的系统资源
        return buffImg;
    }



    private List<int[]> getPayTypeLocation(int size){

        if(size == 1){
            return Arrays.asList(new int[]{402, 72});
        }

        if(size == 2){
            return Arrays.asList(new int[]{252, 72}, new int[]{552, 72});
        }

        if(size == 3){
            return Arrays.asList(new int[]{162, 72}, new int[]{402, 72}, new int[]{642, 72});
        }

        if(size == 4){
            return Arrays.asList(new int[]{138, 72}, new int[]{318, 72}, new int[]{513, 72}, new int[]{693, 72});
        }

        if(size == 5){
            return Arrays.asList(new int[]{62, 72}, new int[]{232, 72}, new int[]{402, 72}, new int[]{572, 72}, new int[]{742, 72});
        }

        return null;
    }


}
