package yem.base.common.utils;



import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import kd.bos.context.RequestContext;
import kd.bos.fileservice.FileService;
import kd.bos.fileservice.FileServiceFactory;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.service.attachment.FileItemExt;
import kd.bos.service.attachment.FileSource;
import kd.bos.util.FileNameUtils;

import java.io.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


/**
 * @BelongsProject: yem-cosmic
 * @BelongsPackage: yem.base.common.utils
 * @ClassName QRCodeToolUtil
 * @Author: LiuHB
 * @CreateTime: 2025-01-08  15:32
 */
public class QRCodeUtil {
    private static final Log log = LogFactory.getLog(QRCodeUtil.class);
    private static final boolean isLinux = isOSLinux();
    private static final String realePath;//存储地址

    static {
        if (isLinux) {
            realePath = "/kingdee/qrcode";
        } else {
            realePath = "C:/kingdee/qrcode";
        }
    }

    public static String getRealePath() {
        return realePath;
    }

    public static String createQRImage(String qrCodeText) {
        return createQRImage(qrCodeText, 150);
    }

    public static String createQRImage(String qrCodeText, int size) {
        return createQRImage(qrCodeText, "jpg", size);
    }

    public static String createQRImage(String qrCodeText, String fileType, int size) {
        fileType = StringUtils.isEmpty(fileType) ? "jpg" : fileType;
        String fileName = String.format("%s.%s", "qrcode", fileType);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            Map<EncodeHintType, Object> hintMap = new HashMap<>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            hintMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(qrCodeText, BarcodeFormat.QR_CODE, size, size, hintMap);
            MatrixToImageWriter.writeToStream(bitMatrix, fileType, outputStream);

            byte[] bytes = outputStream.toByteArray();
            InputStream inputStream = new ByteArrayInputStream(bytes);

            FileService service = FileServiceFactory.getImageFileService();
            String tenantId = RequestContext.get().getTenantId();
            String accountId = RequestContext.get().getAccountId();
            String uuid = UUID.randomUUID().toString().replace("-", "");
            String path = FileNameUtils.getBillImageFileName(tenantId, accountId, "tpv", uuid + "/" + fileName);
            FileItemExt fileItem = new FileItemExt(fileName, path, inputStream);
            fileItem.setSource(FileSource.PICTURE_FIELD);
            fileItem.setComputeDigest(true);
            fileItem.setCreateNewFileWhenExists(true);
            return service.upload(fileItem);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("二维码生成异常。", e);
        }
        return "";
    }

    public static String createQRFile(String qrCodeText) {
        return createQRFile(qrCodeText, 80);
    }

    public static String createQRFile(String qrCodeText, int size) {
        return createQRFile(qrCodeText, "jpg", size);
    }

    public static String createQRFile(String qrCodeText, String fileType, int size) {
        fileType = StringUtils.isEmpty(fileType) ? "jpg" : fileType;
        String fileName = String.format("%s.%s", "qrcode", fileType);
        String uuid = createUUID();
        String tenantId = RequestContext.get().getTenantId();
        String accountId = RequestContext.get().getAccountId();
        String path = FileNameUtils.getBillImageFileName(tenantId, accountId, "tpv", uuid + "/" + fileName);

        String filePath = String.format("%s%s", realePath, path);
        File qrFile = new File(filePath);
        try {
            createNewFile(qrFile);
            Map<EncodeHintType, Object> hintMap = new HashMap<>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            hintMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(qrCodeText, BarcodeFormat.QR_CODE, size, size, hintMap);
            MatrixToImageWriter.writeToPath(bitMatrix, fileType, qrFile.toPath());

            FileService service = FileServiceFactory.getImageFileService();
            FileItemExt fileItem = new FileItemExt(fileName, path, new FileInputStream(qrFile));
            fileItem.setSource(FileSource.PICTURE_FIELD);
            fileItem.setComputeDigest(true);
            fileItem.setCreateNewFileWhenExists(true);
            return service.upload(fileItem);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("二维码生成异常。", e);
        }
        return "";
    }

    public static String createQRImageBase64(String qrCodeText) {
        int size = 80;
        String fileType = "jpg";
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            Map<EncodeHintType, Object> hintMap = new HashMap<>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            hintMap.put(EncodeHintType.CHARACTER_SET, "utf-8");
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(qrCodeText, BarcodeFormat.QR_CODE, size, size, hintMap);
            MatrixToImageWriter.writeToStream(bitMatrix, fileType, outputStream);

            byte[] bytes = outputStream.toByteArray();
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("二维码生成异常。", e);
        }
        return "";
    }

    public static void createNewFile(File file) throws IOException {
        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        file.createNewFile();
        if (isLinux) {
            file.setExecutable(true);//设置可执行权限
            file.setReadable(true);//设置可读权限
            file.setWritable(true);//设置可写权限
        }
    }

    private static boolean isOSLinux() {
        String os = System.getProperty("os.name");
        return os != null && os.toLowerCase().contains("linux");
    }

    public static String createUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

}
