package fcb.project.manager.base.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import fdage.back.sdk.utils.FileUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

import static com.google.zxing.client.j2se.MatrixToImageConfig.BLACK;
import static com.google.zxing.client.j2se.MatrixToImageConfig.WHITE;

/**
 * @author abnerhou
 * @date 2020/4/23 17:35
 * @desciption
 */
@Component
@Log4j2
public class DataUtils {

    public static BigDecimal getBigDecimalObj(Object data) {

        if (null == data) {
            return null;
        } else if (data instanceof String) {
            String dataStr = (String) data;
            if (!StringUtils.isEmpty(dataStr.trim())) {
                return new BigDecimal(dataStr.trim());
            }
        } else if (data instanceof Long) {
            Long dataLong = (Long) data;
            return BigDecimal.valueOf(dataLong);
        } else if (data instanceof Integer) {
            Integer dataInt = (Integer) data;
            return BigDecimal.valueOf(dataInt);

        } else if (data instanceof Double) {
            Double dataDouble = (Double) data;
            return BigDecimal.valueOf(dataDouble);
        }

        return null;

    }

    public static Integer getInteger(Object object) {
        if (null == object) {
            return new Integer(0);
        }
        if (object instanceof String) {
            String ojStr = (String) object;
            if (StringUtils.isEmpty(ojStr)) {
                //TODO:在斟酌这里的处理方式
                return new Integer(0);
            } else {
                return new Integer(Integer.parseInt(ojStr.trim()));
            }
        } else if (object instanceof Integer) {
            return (Integer) object;
        } else if (object instanceof Long) {
            return (Integer) object;
        } else if (object instanceof Double) {
            return (Integer) object;
        } else {
            return new Integer(0);
        }
    }

    public static Integer getIntegerWithDefault(Object object, boolean withDefault) {
        if (null == object) {

            return withDefault ? new Integer(0) : null;
        }
        if (object instanceof String) {
            String ojStr = (String) object;
            if (StringUtils.isEmpty(ojStr)) {

                return withDefault ? new Integer(0) : null;
            } else {
                return new Integer(Integer.parseInt(ojStr.trim()));
            }
        } else if (object instanceof Integer) {
            return (Integer) object;
        } else if (object instanceof Long) {
            return (Integer) object;
        } else if (object instanceof Double) {
            return (Integer) object;
        } else {
            return withDefault ? new Integer(0) : null;
        }
    }

    public static Map<String, Object> assembleResult(long totalNum, long totalPageNum, long currPageNum, Object list) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("totalNum", totalNum);
        resultMap.put("totalPageNum", totalPageNum);
        resultMap.put("curPage", currPageNum);
        resultMap.put("list", list);
        return resultMap;
    }

    public static <T> void assembleTimeQueryWrapper(Map<String, Object> constantQuery, String dynamicQuery,
                                                    QueryWrapper<T> queryWrapper, String idQuery,
                                                    String secondQuery, String thirdQuery) {
        assembleConstantQuery(queryWrapper, constantQuery);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(dynamicQuery)) {
            queryWrapper.and(wrapper -> wrapper
                    .or().like(org.apache.commons.lang3.StringUtils.isNotBlank(secondQuery), secondQuery, dynamicQuery)
                    .or().like(org.apache.commons.lang3.StringUtils.isNotBlank(thirdQuery), thirdQuery, dynamicQuery)
                    .or().like(dynamicQuery.length() <= 32 && org.apache.commons.lang3.StringUtils.isNotBlank(idQuery), idQuery, dynamicQuery));
        }

    }

    public static <T> void assembleConstantQuery(QueryWrapper<T> queryWrapper, Map<String, Object> constantQuery) {
        if (null != queryWrapper && !CollectionUtils.isEmpty(constantQuery)) {
            for (Map.Entry<String, Object> entry : constantQuery.entrySet()) {
                queryWrapper.eq(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     *  根据map的key进行字典升序排序
     * @param map
     * @return map
     */
    public static Map<String, Object> sortMapByKey(Map<String, Object>map) {
        Map<String, Object> treemap = new TreeMap<String, Object>(map);
        List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(treemap.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
            @Override
            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                return org.apache.commons.lang3.StringUtils.compare(o1.getKey() , o2.getKey());
            }
        });
        return treemap;
    }

    /**
     *
     * 生成MD5 32位小写字符的密码串
     * */
    public static String md5Encryption(String jsonStr) {
        String re_md5 = new String();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(jsonStr.getBytes());
            byte b[] = md.digest();
            StringBuffer buf = new StringBuffer("");
            int i;
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0){
                    i += 256;
                }
                if (i < 16){
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
            re_md5 = buf.toString();
        } catch (NoSuchAlgorithmException e) {
            log.info("生成MD5密文出错了:{}" , e);
            e.printStackTrace();
        }
        return re_md5.toLowerCase();
    }

    /**
    *
     * 根据上传的照片生成二维码
    * **/
    public static boolean createQRCode(String url, String outPath, File logoPathFile) throws Exception {
        // 生成二维码

        int width = 300; // 二维码图片宽度 300
        int height = 300; // 二维码图片高度300

        String format = "jpg";// 二维码的图片格式 gif

        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        // 指定纠错等级,纠错级别（L 7%、M 15%、Q 25%、H 30%）
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 内容所使用字符集编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//      hints.put(EncodeHintType.MAX_SIZE, 350);//设置图片的最大值
//      hints.put(EncodeHintType.MIN_SIZE, 100);//设置图片的最小值
        hints.put(EncodeHintType.MARGIN, 1);//设置二维码边的空度，非负数

        BitMatrix bitMatrix = new MultiFormatWriter().encode(url,
                //编码类型，目前zxing支持：Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,
                //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,
                //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION
                BarcodeFormat.QR_CODE,
                width, //条形码的宽度
                height, //条形码的高度
                hints);//生成条形码时的一些配置,此项可选

        //File outputFile = new File("d:" + File.separator + "new-1.gif");//指定输出路径
        File outputFile = new File(outPath);//指定输出路径
        FileUtils.deleteFile(outPath);
        return writeToFile(bitMatrix, format, outputFile, logoPathFile);
    }

    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
//              image.setRGB(x, y,  (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB()));
            }
        }
        return image;
    }

    public static boolean writeToFile(BitMatrix matrix, String format, File file, File logoPathFile) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        //设置logo图标
        LogoConfig logoConfig = new LogoConfig();
        image = logoConfig.LogoMatrix(image, logoPathFile);

        if(null == image){
            return false;
        }
        File parFile = new File(file.getParent() + File.separator);
        if (!parFile.exists()){
            parFile.mkdirs();
        }

        if (!ImageIO.write(image, format, file)) {
            //throw new IOException("Could not write an image of format " + format + " to " + file);
            log.info("Could not write an image of format " + format + " to " + file);
            return false;
        } else {
            log.info("二维码生成成功！");
            return true;
        }
    }

    public static void main(String[] args) throws Exception{
        createQRCode("https://www.4dkankan.com/spc.html?m=t-pnj0IJX", "C:/Users/4dage/Desktop/logo-file/t-pnj0IJX1.png", null);
    }

}
