package com.gree.mall.miniapp.utils.image;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;

@Slf4j
public class ImageHandlerUtils {


    /**
     * 根据指定大小和指定精度压缩图片
     *
     * @param inputStream
     *            输入流
     * @param desPath
     *            目标图片地址
     * @param desFileSize
     *            指定图片大小，单位kb
     * @param accuracy
     *            精度，递归压缩的比率，建议小于0.9
     * @param convertWidth
     *            转换宽度
     * @param convertHeight
     *            转换高度
     * @return
     */
    public static void compressPicForScale(InputStream inputStream, String desPath,
                                             long desFileSize, double accuracy, Integer convertWidth, Integer convertHeight) throws IOException {
        // 1、先转换成jpg
        Thumbnails.of(inputStream).scale(1f).toFile(desPath);

        // 检查文件是否为横版，横版变竖版
        File srcFile = new File(desPath);
        BufferedImage bim = ImageIO.read(srcFile);

        if (bim.getHeight() < bim.getWidth()) {
            Thumbnails.of(desPath).rotate(90).scale(1).toFile(desPath);
        }

        // 递归压缩，直到目标文件大小小于desFileSize
        compressPicCycle(desPath, desFileSize, accuracy);
//        if (Objects.nonNull(convertWidth) && Objects.nonNull(convertHeight)) {
//            Thumbnails.of(desPath).forceSize(720,960).toFile(desPath);
//        }
    }

    private static void compressPicCycle(String desPath, long desFileSize, double accuracy) throws IOException {
        File srcFileJPG = new File(desPath);
        long srcFileSizeJPG = srcFileJPG.length();
        // 2、判断大小，如果小于500kb，不压缩；如果大于等于500kb，压缩
        if (srcFileSizeJPG <= desFileSize * 1024) {
            return;
        }
        // 计算宽高
        BufferedImage bim = ImageIO.read(srcFileJPG);
        int srcWdith = bim.getWidth();
        int srcHeigth = bim.getHeight();
        int desWidth = new BigDecimal(srcWdith).multiply(
                new BigDecimal(accuracy)).intValue();
        int desHeight = new BigDecimal(srcHeigth).multiply(
                new BigDecimal(accuracy)).intValue();

        Thumbnails.of(desPath).size(desWidth, desHeight).outputQuality(accuracy).toFile(desPath);

        compressPicCycle(desPath, desFileSize, accuracy);
    }


    /**
     * 采集图片-绘画文字
     * @param srcImgPath
     * @param outImgPath
     * @param markContentColor
     * @param fontSize
     * @param waterMarkContent
     * @param fileSuffix
     * @throws IOException
     */
    public static void waterPress(String srcImgPath, String outImgPath,
                                  Color markContentColor, int fontSize, String waterMarkContent, String fileSuffix) throws IOException {
        String[] waterMarkContents = waterMarkContent.split("\\|\\|");
        // 读取原图片信息
        File srcImgFile = new File(srcImgPath);
        Image srcImg = ImageIO.read(srcImgFile);
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);
        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        // 得到画笔对象
        Graphics2D g = bufImg.createGraphics();
        // 设置起点
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        Font font = new Font("宋体", Font.BOLD, fontSize);
        // 设置水印文字字体
        g.setFont(font);

        // 数组长度
        int contentLength = waterMarkContents.length;
        // 获取水印文字中最长的
        int maxLength = 0;
        for (String markContent : waterMarkContents) {
            int fontLen = getWatermarkLength(markContent, g);
            if (maxLength < fontLen) {
                maxLength = fontLen;
            }
        }

        for (int j = 0; j < contentLength; j++) {
            waterMarkContent = waterMarkContents[j];
            int tempX = 10;
            // 单字符长度
            int tempCharLen = 0;
            // 单行字符总长度临时计算
            int tempLineLen = 0;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < waterMarkContent.length(); i++) {
                char tempChar = waterMarkContent.charAt(i);
                tempCharLen = getCharLen(tempChar, g);
                tempLineLen += tempCharLen;
                if (tempLineLen >= srcImgWidth) {
                    // 字体阴影
                    g.setColor(Color.WHITE);
                    g.drawString(sb.toString(), tempX + 1, fontSize + (1));
                    // 根据图片的背景设置水印颜色
                    g.setColor(markContentColor);
                    // 长度已经满一行,进行文字叠加
                    g.drawString(sb.toString(), tempX, fontSize );
                    // 清空内容,重新追加
                    sb.delete(0, sb.length());
                    tempLineLen = 0;
                }
                // 追加字符
                sb.append(tempChar);
            }
            // 字体阴影
            g.setColor(Color.WHITE);
            g.drawString(sb.toString(), 1, srcImgHeight - (contentLength - j - 0.5f) * (fontSize + 3) + (1));
            // 根据图片的背景设置水印颜色
            g.setColor(markContentColor);
            // 通过设置后两个输入参数给水印定位 0.5f是离底比例  tempY相加行距
            g.drawString(sb.toString(), 0, srcImgHeight - (contentLength - j - 0.5f) * (fontSize + 3));
        }
        g.dispose();


        // 输出图片
        FileOutputStream outImgStream = new FileOutputStream(outImgPath);
        ImageIO.write(bufImg, fileSuffix, outImgStream);
        outImgStream.flush();
        outImgStream.close();
    }


    /**
     * 保险凭证
     * @param srcImgPath
     * @param outImgPath
     * @param markContentColor
     * @param fontSize
     * @param waterMarkContent
     * @throws IOException
     */
    public static byte[] waterPressOfInsure(InputStream srcImgPath, String outImgPath,
                                  Color markContentColor, int fontSize, String waterMarkContent) throws IOException {
        String[] waterMarkContents = waterMarkContent.split("\\|\\|");
        // 读取原图片信息
        //File srcImgFile = new File(srcImgPath);
        Image srcImg = ImageIO.read(srcImgPath);
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);
        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        // 得到画笔对象
        Graphics2D g = bufImg.createGraphics();
        // 设置起点
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        Font font = new Font("宋体", Font.BOLD, fontSize);
        // 根据图片的背景设置水印颜色
        g.setColor(markContentColor);
        // 设置水印文字字体
        g.setFont(font);
        // 数组长度
        int contentLength = waterMarkContents.length;
        // 获取水印文字中最长的
        int maxLength = 0;
        for (String markContent : waterMarkContents) {
            int fontLen = getWatermarkLength(markContent, g);
            if (maxLength < fontLen) {
                maxLength = fontLen;
            }
        }

        g.drawString(waterMarkContents[0], 120, 180);
        g.drawString(waterMarkContents[1], 505, 180);
        g.drawString(waterMarkContents[2], 155, 235);
        g.drawString(waterMarkContents[3], 555, 235);

        g.drawString(waterMarkContents[4], 60, 330);
        g.drawString(waterMarkContents[5], 60, 350);
        g.drawString(waterMarkContents[6], 60, 370);
        g.drawString(waterMarkContents[7], 60, 390);
        g.drawString(waterMarkContents[8], 60, 410);
        g.drawString(waterMarkContents[9], 60, 450);

        g.dispose();

        // 输出图片
//        FileOutputStream outImgStream = new FileOutputStream(outImgPath);
//        ImageIO.write(bufImg, "jpg", outImgStream);
//        outImgStream.flush();
//        outImgStream.close();

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write( bufImg, "jpg", bos );
        bos.close();

        return bos.toByteArray();
    }



    private static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }

    /**
     * 获取水印文字总长度
     *
     * @paramwaterMarkContent水印的文字
     * @paramg
     * @return水印文字总长度
     */
    private static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(
                waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }



    public static void main(String[] args) throws IOException {
//        InputStream inputStream  = ImageHandlerUtils.class.getResourceAsStream("/static/insure.jpg");
//        waterPressOfInsure(inputStream,"B://1.jpg",Color.BLACK,15,"你好啊||123321123312||李佳辉||李佳辉||兹经投保人申请，公司同意自2023-06-30日起，对保险单作如下批改:||《新增被保人》||邹国强居民 身份证 440232198610051316||“本保险合同每人意外伤害保险金额80万元整、意外医疗保险金额12万元整，意外住院津贴80元/天||本保单终保日期:2023-12-31”||本次批改合计加收保费CNY 675.00元。");
    }

}
