package com.gic.haoban.manage.service.util;

import com.alibaba.fastjson.JSON;
import com.freewayso.image.combiner.ImageCombiner;
import com.freewayso.image.combiner.enums.OutputFormat;
import com.freewayso.image.combiner.enums.ZoomMode;
import com.gic.thirdparty.cloudfile.CloudFileUtil;
import com.gic.thirdparty.cloudfile.enums.CloudFileBusinessOptEnum;
import com.gic.thirdparty.cloudfile.enums.CloudFileTypeEnum;
import com.gic.thirdparty.cloudfile.pojo.CloudFileInfo;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author MUSI
 * @Date 2023/3/15 9:48 PM
 * @Description
 * @Version
 **/
@Slf4j
public class DrawImageUtils {

    @Getter
    @AllArgsConstructor
    public enum DrawBkgImg {
        AREA_WEEK_BKG("template/area_week_bkg.png", "区经周报背景图", 352, 416, 320),
        AREA_MONTH_BKG("template/area_month_bkg.png", "区经月报背景图", 352, 416, 320),
        CLERK_WEEK_BKG("template/week_bkg.png", "导购/店长周报背景图", 260, 320, 353),
        CLERK_MONTH_BKG("template/month_bkg.png", "导购/店长月报背景图", 260, 320, 353),
        ;
        private String path;
        private String desc;
        /**
         * 第一个位置宽度
         */
        private int numWidth;

        /**
         * 金额开始位置的左上顶点坐标
         */
        private int amountStart;
        /**
         * 金额宽度
         */
        private int amountWidth;


    }

    /**
     * 绘画素材周报/月报 海报图
     *
     * @param factoryCode
     * @param firstValue
     * @param amountText
     */
    public static String drawImage(String factoryCode, String firstValue, String amountText, DrawBkgImg drawBkgImg) {
        if (drawBkgImg == null) {
            log.info("合成图片的背景模板为空 factoryCode:{}", factoryCode);
            return null;
        }
        try {
            long startTime = System.currentTimeMillis();
            InputStream inputStream = DrawImageUtils.class.getClassLoader().getResourceAsStream(drawBkgImg.getPath());
            if (inputStream == null) {
                log.info("模板文件不存在 path:{}", drawBkgImg.getPath());
                return null;
            }

            BufferedImage image = ImageIO.read(inputStream);
            Graphics2D pen = image.createGraphics();
            pen.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            pen.setColor(Color.WHITE);
            Font font = new Font("微软雅黑", Font.BOLD, 56);
            pen.setFont(font);
            FontMetrics metrics = pen.getFontMetrics(font);
            int startX = 40 + (drawBkgImg.numWidth - metrics.stringWidth(firstValue)) / 2;
            pen.drawString(firstValue, startX, 250);
            int amountX = drawBkgImg.amountStart + (drawBkgImg.amountWidth - metrics.stringWidth(amountText)) / 2;
            pen.drawString(amountText, amountX, 250);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", bos);
            pen.dispose();
            CloudFileInfo cloudFileInfo = CloudFileUtil.uploadFile(bos.toByteArray(), "png", CloudFileTypeEnum.IMAGE, factoryCode, CloudFileBusinessOptEnum.HAOBAN_COMMON);
            log.info("上传图片结果:{}", JSON.toJSONString(cloudFileInfo));
            long endTime = System.currentTimeMillis();
            log.info("合成图片耗时 {} ms", (endTime - startTime));
            if (cloudFileInfo != null) {
                return cloudFileInfo.getOrgFileUrl();
            }
        } catch (Exception ex) {
            log.info("合成月报图片异常", ex);
        }
        return null;
    }


    /***
     * 二维码合成
     * 1、先获取图片的宽高
     * 2、如果图片高度大于2000，则按最大高度2000，宽度等比处理
     * 3、图片与二维码按照750:136比例显示
     *
     * 位置距离右边20px，底部20px
     */
    public static String addWater(String factoryCode, String url, InputStream qrCodeStream) {
        // 读取原图片信息
        //文件转化为图片
        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start("下载图片");
            long startTime = System.currentTimeMillis();
            Image srcImg = ImageIO.read(new URL(url));
            stopWatch.stop();
            //获取图片的宽
            int srcImgWidth = srcImg.getWidth(null);
            //获取图片的高
            int srcImgHeight = srcImg.getHeight(null);
            log.info("图片宽度：{}, 图片高度:{}", srcImgHeight, srcImgHeight);
            BufferedImage bufImg = null;
            if (srcImgHeight > 2000) {
                log.info("原图片高度超过2000 高度:{}, 等比压缩", srcImgHeight);
                // 按高度等比压缩
                int tempWidth = BigDecimal.valueOf(srcImgWidth)
                        .multiply(BigDecimal.valueOf(2000).divide(BigDecimal.valueOf(srcImgHeight), 2, RoundingMode.HALF_DOWN))
                        .intValue();
                log.info("压缩后的宽：{}", tempWidth);
                srcImgHeight = 2000;
                srcImgWidth = tempWidth;
            }
            bufImg = resize(srcImg, srcImgHeight, srcImgWidth, false);
            Graphics2D g = bufImg.createGraphics();
            //使用工具类生成二维码
            stopWatch.start("处理二维码");
            Image image = ImageIO.read(qrCodeStream);
            //将小图片绘到大图片上,500,300 .表示你的小图片在大图片上的位置。
            int qrCodeHeight = image.getHeight(null);
            int qrCodeWidth = image.getWidth(null);
            log.info("二维码图片宽度:{},高度:{}", qrCodeWidth, qrCodeHeight);

            int qrCodeWidthTemp = srcImgWidth * 136 / 750;
            log.info("二维码计算后的宽度 {}", qrCodeWidthTemp);
            BufferedImage qrCodeImage = resize(image, qrCodeWidthTemp, qrCodeWidthTemp, true);
            stopWatch.stop();
            stopWatch.start("合成图片");
            g.drawImage(qrCodeImage, srcImgWidth - (qrCodeWidthTemp + 20), srcImgHeight - (qrCodeWidthTemp + 20), null);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ImageIO.write(bufImg, "png", bos);
            g.dispose();
            byte[] bytes = bos.toByteArray();
            log.info("合成之后的大小 {}", bytes.length);
            CloudFileInfo cloudFileInfo = CloudFileUtil.uploadFile(bytes, "jpg", CloudFileTypeEnum.IMAGE, factoryCode, CloudFileBusinessOptEnum.HAOBAN_COMMON);
            log.info("上传图片结果:{}", JSON.toJSONString(cloudFileInfo));
            stopWatch.stop();
            log.info("处理耗时: {}", stopWatch.prettyPrint());
            long endTime = System.currentTimeMillis();
            log.info("合成图片耗时 {} 秒", (endTime - startTime) / 1000);
            if (cloudFileInfo != null) {
                return cloudFileInfo.getOrgFileUrl();
            }
        }catch (Exception ex) {
            log.info("处理图片发生异常", ex);
        }
        return url;
    }

    public static String addWaterNew(String factoryCode, String url, String qrCodeUrl) {
        // 读取原图片信息
        //文件转化为图片
        try {
            //BufferedImage qrCodeBufferedImage = ImageIO.read(qrCodeInputStream);
            long startTime = System.currentTimeMillis();
            ImageCombiner imageCombiner = new ImageCombiner(url, OutputFormat.PNG);
            int srcImgWidth = imageCombiner.getCanvasWidth();
            int srcImgHeight = imageCombiner.getCanvasHeight();
            log.info("图片宽度：{}, 图片高度:{}", srcImgWidth, srcImgHeight);
            if (srcImgHeight > 2000) {
                log.info("原图片高度超过2000 高度:{}, 等比压缩", srcImgHeight);
                // 按高度等比压缩
                srcImgHeight = 2000;
                imageCombiner = new ImageCombiner(url, 0, srcImgHeight, ZoomMode.Height, OutputFormat.PNG);
                srcImgWidth = imageCombiner.getCanvasWidth();
                log.warn("转换后实际的宽: {}, 高:{}", imageCombiner.getCanvasWidth(), imageCombiner.getCanvasHeight());
            }
            log.info("转换后图片宽度：{}, 图片高度:{}", srcImgWidth, srcImgHeight);
            // 计算二维码宽度
            int qrCodeWidthTemp = srcImgWidth * 136 / 750;
            log.info("二维码计算后的宽度 {}", qrCodeWidthTemp);
            imageCombiner.addImageElement(qrCodeUrl, srcImgWidth - (qrCodeWidthTemp + 20), srcImgHeight - (qrCodeWidthTemp + 20), qrCodeWidthTemp, qrCodeWidthTemp, ZoomMode.Height);
            imageCombiner.combine();
            InputStream combinedImageStream = imageCombiner.getCombinedImageStream();
            log.info("合成之后的大小 {}", combinedImageStream.available());
            CloudFileInfo cloudFileInfo = CloudFileUtil.uploadFile(combinedImageStream, "png", CloudFileTypeEnum.IMAGE, factoryCode, CloudFileBusinessOptEnum.HAOBAN_COMMON);
            combinedImageStream.close();
            log.info("上传图片结果:{}", JSON.toJSONString(cloudFileInfo));
            long endTime = System.currentTimeMillis();
            log.info("合成图片耗时 {} 秒", (endTime - startTime) / 1000);
            if (cloudFileInfo != null) {
                return cloudFileInfo.getOrgFileUrl();
            }
        }catch (Exception ex) {
            log.info("处理图片发生异常", ex);
        }
        return url;
    }

    public static BufferedImage resize(Image img, int h, int w, boolean clip) throws IOException {
        //参数是TYPE_3BYTE_BGR时，图片最清晰！
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
        //留一个像素的空白区域，这个很重要，画圆的时候把这个覆盖
        Graphics graphics = image.getGraphics();
        if (clip) {
            int border = 1;
            //图片是一个圆型
            Ellipse2D.Double shape = new Ellipse2D.Double(border, border, h - border * 2, w - border * 2);
            //需要保留的区域
            graphics.setClip(shape);
        }
        // 绘制缩小后的图像
        graphics.drawImage(img, 0, 0, w, h, null);
        graphics.dispose();
        return image;
    }

    public static void main(String[] args) throws Exception {

        String qrcodeUrl = "https://gicinner-1251519181.cos.ap-shanghai.myqcloud.com/image/material_content-80819999f96f448d9fcccb5ac86e6c37.png";
        String url = "https://jhdm-1251519181.cos.ap-shanghai.myqcloud.com/image/material_content-7c3bc8061ffb4e2694c0e288a1ce176b.jpeg?imageView2/format/jpg/q/50";
        //String url = "https://newdmwltest-1251519181.cos.ap-shanghai.myqcloud.com/image/material_content-bd89447576b5438d8045def2da2c4c0f.jpg?imageView2/format/jpg/q/50";
        System.setProperty("gic.module.name", "haoban-manage3-service");

        System.out.println(DrawImageUtils.addWaterNew("jhdm", url, qrcodeUrl));

//        ByteArrayOutputStream byteArrayOutputStream = null;
//        InputStream inputStream = null;
//        try {
//            URL openUrl = new URL(qrcodeUrl);
//            inputStream = openUrl.openStream();
//            byteArrayOutputStream = cloneInputStream(inputStream);
//        }catch (Exception ex) {
//            log.info("获取二维码流对象异常 qrCodeUrl:{}", ex);
//        }
//        if (byteArrayOutputStream == null) {
//            return;
//        }
//        ArrayList<Object> objects = new ArrayList<>();
//        for (int i = 0; i < 10; i++) {
//            objects.add(i);
//        }
//        ByteArrayOutputStream finalByteArrayOutputStream = byteArrayOutputStream;
//        InputStream finalInputStream = inputStream;
//        List<String> collect = objects.stream()
//                .map(item -> DrawImageUtils.addWaterNew("jhdm", url, qrcodeUrl))
//                .collect(Collectors.toList());
//        System.out.println(JSON.toJSONString(collect));
    }


    /**
     * inputStrean 拷贝
     * @param input
     * @return
     */
    public static ByteArrayOutputStream cloneInputStream(InputStream input) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = input.read(buffer)) > -1) {
                baos.write(buffer, 0, len);
            }
            baos.flush();
            return baos;
        } catch (Exception ex) {
            log.info("stream 拷贝异常", ex);
            return null;
        }
    }
}
