package cn.exploring.engine.server.core.qcode;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.exploring.engine.server.core.storage.StorageService;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;

@Service
public class QCodeService {
    @Autowired
    WxMaService wxMaService;

    @Autowired
    private StorageService storageService;

    public static final String INVOTE = "INVOTE";  // 生成邀请码类型的标识

    public String createShareQrcodeImage(String id, String url, String type, String pic, String name) {
        try {
            File file = wxMaService.getQrcodeService().createWxaCodeUnlimit("id," + id, url);
            FileInputStream inputStream = new FileInputStream(file);

            //savePic(inputStream, organize.getOrgName() + "-" + file.getName());

            byte[] imageData = null;
            if (!StringUtils.isEmpty(type) && INVOTE.equals(type)) {  // 后台生成邀请码
                imageData = drawPicture(inputStream, pic, name);
            } else {  // 生成二维码
                imageData = drawPicture(inputStream);
            }

            //将二维码图片保存
            ByteArrayInputStream inputStream2 = new ByteArrayInputStream(imageData);
            //存储分享图
            String keyName = getKeyName(id, url);
            String result = storageService.store(inputStream2, imageData.length, "image/jpeg", keyName, storageService.generateKey(keyName));
            return result;
        } catch (WxErrorException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "";
    }

    private void savePic(InputStream inputStream, String fileName) {
        OutputStream os = null;
        try {
            String path = "/storage/ewm/";
            byte[] bs = new byte[1024];
            int len;
            File tempFile = new File(path);
            if (!tempFile.exists()) {
                tempFile.mkdirs();
            }
            os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private String getKeyName(String id, String url) {
        return "QCODE_" + url + "_"  + id + ".jpg";
    }

    /**
     * 将二维码图片保存
     *
     * @param qrCodeImg  二维码图片
     * @return
     * @throws IOException
     */
    private byte[] drawPicture(InputStream qrCodeImg) throws IOException {
        BufferedImage qrCodeImage = ImageIO.read(qrCodeImg);

        //转jpg
        BufferedImage result = new BufferedImage(qrCodeImage.getWidth(), qrCodeImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        result.getGraphics().drawImage(qrCodeImage, 0, 0, null);
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ImageIO.write(result, "jpg", bs);

        //最终byte数组
        return bs.toByteArray();
    }

    /**
     * 将邀请码保存
     *
     * @param qrCodeImg  二维码图片
     * @return
     * @throws IOException
     */
    private byte[] drawPicture(InputStream qrCodeImg, String orgUrl, String orgName) throws IOException {
        // 底图
        ClassPathResource redResource = new ClassPathResource("invote.png");
        BufferedImage red = ImageIO.read(redResource.getInputStream());

        // 组织头图
        URL orgPic = new URL(orgUrl);
        BufferedImage orgImage = ImageIO.read(orgPic);

        //小程序二维码
        BufferedImage qrCodeImage = ImageIO.read(qrCodeImg);

        //底层空白 bufferedImage
        BufferedImage baseImage = new BufferedImage(red.getWidth(), red.getHeight(), BufferedImage.TYPE_4BYTE_ABGR_PRE);

        //画上图片
        drawImgInImg(baseImage, red, 0, 0, red.getWidth(), red.getHeight());

        //画上组织图片
        drawImgInImg(baseImage, orgImage, 131, 0, 210, 210);

        //画上小程序二维码
        drawImgInImg(baseImage, qrCodeImage, 98, 316, 278, 278);

        //写上组织名称
        drawTextInImgCenter(baseImage, orgName, 217, new Color(50, 51, 51));

        //写上提示
        drawTextInImgCenter(baseImage, "用微信扫描二维码即可使用", 701, new Color(126, 124, 126));

        //转jpg
        BufferedImage result = new BufferedImage(baseImage.getWidth(), baseImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        result.getGraphics().drawImage(baseImage, 0, 0, null);
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ImageIO.write(result, "jpg", bs);

        //最终byte数组
        return bs.toByteArray();
    }

    private void drawTextInImgCenter(BufferedImage baseImage, String textToWrite, int y, Color color) {
        Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
        g2D.setColor(color);

        String fontName = "Microsoft YaHei";

        Font f = new Font(fontName, Font.PLAIN, 28);
        g2D.setFont(f);
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 计算文字长度，计算居中的x点坐标
        FontMetrics fm = g2D.getFontMetrics(f);
        int textWidth = fm.stringWidth(textToWrite);
        int widthX = (baseImage.getWidth() - textWidth) / 2;
        // 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。

        g2D.drawString(textToWrite, widthX, y);
        // 释放对象
        g2D.dispose();
    }

    private void drawTextInImg(BufferedImage baseImage, String textToWrite, int x, int y) {
        Graphics2D g2D = (Graphics2D) baseImage.getGraphics();
        g2D.setColor(new Color(126, 124, 126));

        //TODO 注意，这里的字体必须安装在服务器上
        g2D.setFont(new Font("Microsoft YaHei", Font.PLAIN, 28));
        g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        System.out.println(2);

        g2D.drawString(textToWrite, x, y);
        g2D.dispose();
    }

    private void drawImgInImg(BufferedImage baseImage, BufferedImage imageToWrite, int x, int y, int width, int heigth) {
        Graphics2D g2D = (Graphics2D) baseImage.getGraphics();

        /*if (tm) {  // 透明
            baseImage = g2D.getDeviceConfiguration().createCompatibleImage(width, heigth, Transparency.TRANSLUCENT);
            g2D.dispose();
            g2D = baseImage.createGraphics();
        }*/

        g2D.drawImage(imageToWrite, x, y, width, heigth, null);
        g2D.dispose();
    }
}
