package com.bonus.canteen.core.allocation.util;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.bonus.canteen.core.allocation.api.AllocMetadataApi;
import com.bonus.canteen.core.allocation.canteen.model.PayQRCodeModel;
import com.bonus.canteen.core.allocation.constants.QRTypeEnum;
import com.bonus.canteen.core.common.enums.FileUploadSourceEnum;
import com.bonus.canteen.core.common.enums.MetadataModelTypeEnum;
import com.bonus.canteen.core.common.sysfile.service.SysFileService;
import com.bonus.canteen.core.common.sysfile.vo.SysFileUploadVO;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.common.core.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Component
public class PayQRCodeUtil {
   private static final Logger log = LoggerFactory.getLogger(PayQRCodeUtil.class);
   @Autowired
   @Lazy
   private AllocMetadataApi allocMetadataApi;
   @Autowired
   @Lazy
   private SysFileService sysFileService;
   private static final Integer WIDTH = 472;
   private static final Integer HEIGHT = 709;

   public String generateQRCode(Long businessId, String businessName, QRTypeEnum qrTypeEnum) {
      PayQRCodeModel payQRCodeModel = new PayQRCodeModel();
      payQRCodeModel.setFirstName(businessName);
      String qRCodeToPath = this.allocMetadataApi.getMetadataValue(MetadataModelTypeEnum.MOBILE, "qRCodeToPath");
      if (CharSequenceUtil.isBlank(qRCodeToPath)) {
         throw new ServiceException("请配置二维码跳转地址");
      } else {
         if (qRCodeToPath.endsWith("/")) {
            qRCodeToPath = StrUtil.sub(qRCodeToPath, 0, -1);
         }

         qRCodeToPath = qRCodeToPath + "/QRScan/menu?tenantId=" + TenantContextHolder.getTenantId() + "&qrtype="
                 + qrTypeEnum.key() + "&placeId=" + businessId;
         String qrcode = this.getNormalQrCode(payQRCodeModel, FileUploadSourceEnum.STALL.key(), qRCodeToPath);
         log.info("生成二维码路径:{}", qrcode);
         return qrcode;
      }
   }

   private String getNormalQrCode(PayQRCodeModel payQRCodeModel, String uploadKey, String pageUrl) {
      try {
         BufferedImage bufferedImageQr = QrCodeUtil.generate(pageUrl, QrConfig.create());
         BufferedImage bufferedImageGround = qRCreateBackGroup();
         Graphics2D g2d = bufferedImageGround.createGraphics();
         int waterImgWidth = bufferedImageGround.getWidth();
         int waterImgHeight = bufferedImageGround.getHeight();
         g2d.setComposite(AlphaComposite.getInstance(10));
         g2d.drawImage(bufferedImageQr, 50, 160, waterImgWidth - 100, waterImgHeight - 337, (ImageObserver)null);
         String text = payQRCodeModel.getFirstName();
         Font font = new Font("黑体", 1, 32);
         g2d.setFont(font);
         g2d.setPaint(Color.BLACK);
         FontRenderContext contexts = g2d.getFontRenderContext();
         Rectangle2D boundss = font.getStringBounds(text, contexts);
         double ys = (double)HEIGHT - boundss.getHeight();
         double ascents = -boundss.getY();
         double baseYs = ys + ascents;
         g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         FontRenderContext context = g2d.getFontRenderContext();
         Rectangle2D stringBounds = font.getStringBounds(text, context);
         double fontWidth = stringBounds.getWidth();
         double staX = ((double)WIDTH - fontWidth) / 2.0;
         float staXf = (float)staX;
         float baseYsf = (float)baseYs;
         g2d.drawString(text, staXf, baseYsf - 580.0F);
         text = payQRCodeModel.getLastName();
         font = new Font("黑体", 1, 40);
         g2d.setFont(font);
         g2d.setPaint(Color.WHITE);
         contexts = g2d.getFontRenderContext();
         boundss = font.getStringBounds(text, contexts);
         ys = (double)HEIGHT - boundss.getHeight();
         ascents = -boundss.getY();
         baseYs = ys + ascents;
         g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
         context = g2d.getFontRenderContext();
         stringBounds = font.getStringBounds(text, context);
         fontWidth = stringBounds.getWidth();
         staX = ((double)WIDTH - fontWidth) / 2.0;
         staXf = (float)staX;
         baseYsf = (float)baseYs;
         g2d.drawString(text, staXf, baseYsf - 49.0F);
         g2d.dispose();
         ByteArrayOutputStream os = new ByteArrayOutputStream();
         ImageIO.write(bufferedImageGround, "jpg", os);
         InputStream input = new ByteArrayInputStream(os.toByteArray());
         String fileName = "payQRCode" + payQRCodeModel.getBusinessId() + ".jpg";
         MultipartFile file = new MockMultipartFile(fileName, fileName, "", input);
         SysFileUploadVO result = this.sysFileService.uploadFile(file, uploadKey);
         return result.getFileNameUrl();
      } catch (IOException var32) {
         log.error("生成位置二维码时发生IO异常方法)", var32);
         throw new ServiceException("生成位置二维码时异常");
      }
   }

   private static BufferedImage qRCreateBackGroup() {
      try {
         InputStream is = ((new Object() {
            public InputStream getImage() {
               return this.getClass().getResourceAsStream("/PayQRCode.png");
            }
         })).getImage();
         Image image = ImageIO.read(is);
         BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, 1);
         Graphics2D g2 = bufferedImage.createGraphics();
         g2.setBackground(Color.WHITE);
         g2.clearRect(0, 0, WIDTH, HEIGHT);
         g2.drawImage(image, 0, 0, WIDTH, HEIGHT, (ImageObserver)null);
         return bufferedImage;
      } catch (Exception var4) {
         log.error("[生成付款码]绘制完整背景图异常", var4);
         throw new ServiceException("绘制完整背景图发生异常");
      }
   }
}
