package com.ruoyi.common.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import com.google.zxing.oned.EAN13Writer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.codec.binary.Base32;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.*;

public class CodeGeneratorUtils {

// 生成订单编码
//    public static String generateOrderCode(Integer maxCount) {
//        String timestamp = getTimestamp();
//        String randomNum = generateRandomNumber();
//        String counterStr = getCounter(maxCount);
//        String codeWithoutCheck = timestamp + randomNum + counterStr;
//        char checkDigit = calculateCheckDigit(codeWithoutCheck);
//        return codeWithoutCheck + checkDigit;
//    }
    // 生成编码
    public static String generateCode(Integer maxCount) {
        String timestamp = getTimestamp();
        String randomNum = generateRandomNumber();
        String counterStr = getCounter(maxCount);
        String codeWithoutCheck = timestamp + randomNum + counterStr;
        char checkDigit = calculateCheckDigit(codeWithoutCheck);
        return codeWithoutCheck + checkDigit;
    }

    // 获取时间戳
    private static String getTimestamp() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        return sdf.format(new Date());
    }

    // 生成随机数
    private static String generateRandomNumber() {
        Random random = new Random();
        int num = random.nextInt(1000);
        return String.format("%03d", num);
    }

    // 获取计数器值
    private static String getCounter(Integer maxCount) {
//        String current = getTimestamp();
//        if (!current.equals(currentDate)) {
//            counter = 0;
//            currentDate = current;
//        }
//        counter++;
        if (maxCount >= 9999) {
            throw new RuntimeException("每天生成的编号已达到上限（9999）");
        }
        int counter = maxCount + 1;
        return String.format("%04d", counter);
    }

    // 计算校验码
    private static char calculateCheckDigit(String code) {
        int sum = 0;
        boolean alternate = false;
        for (int i = code.length() - 1; i >= 0; i--) {
            int n = Integer.parseInt(code.substring(i, i + 1));
            if (alternate) {
                n *= 2;
                if (n > 9) {
                    n = (n % 10) + 1;
                }
            }
            sum += n;
            alternate = !alternate;
        }
        int checkDigit = (10 - (sum % 10)) % 10;
        return Character.forDigit(checkDigit, 10);
    }

    // 生成 EAN - 13 条形码
    public static void generateEAN13Barcode(String code, String filePath) throws WriterException, IOException {
        EAN13Writer ean13Writer = new EAN13Writer();
        BitMatrix bitMatrix = ean13Writer.encode(code, BarcodeFormat.EAN_13, 300, 150);
        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

    // 生成 Code 128 条形码
    public static void generateCode128Barcode(String code, String filePath) throws WriterException, IOException {
        Code128Writer code128Writer = new Code128Writer();
        BitMatrix bitMatrix = code128Writer.encode(code, BarcodeFormat.CODE_128, 300, 150);
        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

    // 生成 QR Code 二维码
    public static void generateQRCode(String code, String filePath) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        BitMatrix bitMatrix = qrCodeWriter.encode(code, BarcodeFormat.QR_CODE, 300, 300, hints);
        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

    // Base32 编码
    public static String base32Encode(String input) {
        Base32 base32 = new Base32();
        byte[] bytes = input.getBytes();
        return base32.encodeAsString(bytes);
    }

    public static String generateOrderNumber() {
        // 生成精简后的时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
        String timestamp = sdf.format(new Date());

        // 生成 3 位随机数
        Random random = new Random();
        int randomNum = random.nextInt(1000);
        String formattedRandomNum = String.format("%03d", randomNum);

        // 拼接基础编号
        String baseNumber = timestamp + formattedRandomNum;

        // 计算校验码
        int total = 0;
        for (int i = 0; i < baseNumber.length(); i++) {
            int digit = Character.getNumericValue(baseNumber.charAt(i));
            total += digit * (i + 1);
        }
        int checkDigit = total % 10;

        // 添加校验码到基础编号
        String orderNumberWithCheck = baseNumber + checkDigit;
//        System.out.println("订单编号：" + orderNumberWithCheck);
        // 使用 Base32 编码缩短长度
//        byte[] bytes = orderNumberWithCheck.getBytes();
//        String encodedOrder = Base64.getEncoder().withoutPadding().encodeToString(bytes);

        return orderNumberWithCheck;
    }

    public static String generateBreweryCode(Integer maxCount) {
        // 生成精简后的时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
        String timestamp = sdf.format(new Date());
        final BigInteger number = new BigInteger(maxCount + timestamp);
        return "BR" + Base36Utils.encode(number);
    }

    public static String generateBarCode(Integer maxCount) {
        // 生成精简后的时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
        String timestamp = sdf.format(new Date());
        final BigInteger number = new BigInteger(maxCount + timestamp);
        return "ST" + Base36Utils.encode(number);
    }

    public static String generateGoodsCode(Integer maxCount) {
        // 生成精简后的时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
        String timestamp = sdf.format(new Date());
        final BigInteger number = new BigInteger(maxCount + timestamp);
        return "PR" + Base36Utils.encode(number);
    }

    public static String generateBeerCode(Integer maxCount) {
        // 生成精简后的时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
        String timestamp = sdf.format(new Date());
        final BigInteger number = new BigInteger(maxCount + timestamp);
        return "BE" + Base36Utils.encode(number);
    }

    public static String generateQrBatchCode(String prefix,String yyyyMMdd,
                                             Integer maxCount,Integer printCount) {
        return prefix + "_" + yyyyMMdd + "_" + String.format("%03d", maxCount) + "_" + String.format("%03d", printCount);
    }

    public static String generateActivityCode(Integer maxCount) {
        // 生成精简后的时间戳
        SimpleDateFormat sdf = new SimpleDateFormat("yyMM");
        String timestamp = sdf.format(new Date());
//        final BigInteger number = new BigInteger(String.valueOf(maxCount));
        return "AC" +timestamp+ String.format("%05d", maxCount);
    }

//    public static void main(String[] args) {
//        String orderNumber = generateBreweryCode(3);
//        System.out.println(orderNumber);
//    }

//    public static void main(String[] args) {
//        String code = generateCode();
//        String base32Code = base32Encode(code);
//
//        // 生成 EAN - 13 条形码
////            generateEAN13Barcode(code, "ean13_barcode.png");
////            System.out.println("EAN - 13 条形码生成成功，保存为 ean13_barcode.png");
//
//        // 生成 Code 128 条形码
////            generateCode128Barcode(code, "code128_barcode.png");
////            System.out.println("Code 128 条形码生成成功，保存为 code128_barcode.png");
//
//        // 生成 QR Code 二维码
////            generateQRCode(base32Code, "qrcode.png");
////            System.out.println("QR Code 二维码生成成功，保存为 qrcode.png");
//
//        System.out.println("原始编码: " + code);
//        System.out.println("Base32 编码: " + base32Code);
//    }
}
