package com.yeejoin.amos.boot.biz.common.utils;

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 javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 二维码工具类
 *
 * @author Administrator
 */
public class QRCodeUtil {

    private static final String CHARSET = "utf-8";
    private static final int QRCODE_SIZE = 45;
    private static Random random = new Random();
    private static int randomNumForQrCode;

    /**
     * <pre>
     * 根据当前记录ID生成QRCode
     * </pre>
     *
     * @return
     */
    public static String generateQRCode(Date dateCreated, String pointNo) {
        return String.valueOf(dateCreated.getTime() + pointNo);
    }


    /**
     * <pre>
     * 生成QRCode
     * </pre>
     *
     * @return
     */
    public static String generateQRCode() {
        String res;
        //加锁生成随机数，保证自增后释放
        Lock lock = new ReentrantLock();
        lock.lock();
        randomNumForQrCode += 1;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        try {
            res = simpleDateFormat.format(new Date(System.currentTimeMillis())).substring(5, 8) + String.valueOf(IdWorker.getFlowIdWorkerInstance().nextId()).substring(0, 10) + randomNumForQrCode;
        } catch (Exception e) {
            String tmp = "";
            for (int i = 0; i < 13; i++) {
                tmp += SecureRandomUtil.getIntSecureRandom(10);
            }
            res = simpleDateFormat.format(new Date(System.currentTimeMillis())).substring(2, 8) + tmp.substring(0, 10) + randomNumForQrCode;
        } finally {
            lock.unlock();
        }
        return res;
    }


    /**
     * 生成临时的qrCode
     *
     * @return
     */
    public static String temporaryQrCode() {
        long qrCode = -1 * System.currentTimeMillis();
        qrCode += (long) (SecureRandomUtil.getIntSecureRandomByDouble() * 10000000);
        return String.valueOf(qrCode);
    }

    /**
     * 根据二维码信息，生成二维码图片 用户excel，word等导出图片
     *
     * @param content
     * @return
     */
    public static byte[] generateQRCodeImageByteData(String content) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(
                    content
                    , BarcodeFormat.QR_CODE
                    , QRCODE_SIZE
                    , QRCODE_SIZE,
                    hints);
            int width = bitMatrix.getWidth();
            int height = bitMatrix.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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }
            ImageIO.write(image, "png", out);
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据二维码信息，生成二维码图片 用户excel，word等导出图片  可自定义图片大小
     *
     * @param content
     * @return
     */
    public static byte[] generateQRCodeImageByteData(String content, int size) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(
                    content
                    , BarcodeFormat.QR_CODE
                    , size
                    , size,
                    hints);
            int width = bitMatrix.getWidth();
            int height = bitMatrix.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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }
            ImageIO.write(image, "png", out);
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
