package com.awspaas.user.apps.donenow_ctt;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

public class QrCodeReaderUtil {

    /**
     * 从图片或PDF文件中识别二维码。
     * 如果是PDF，会逐页扫描，直到找到第一个二维码。
     *
     * @param file 图片文件（如.jpg, .png）或PDF文件（.pdf）
     * @return 识别到的二维码内容。如果未找到或发生错误，返回相应的错误信息字符串。
     */
    public static String readQrCode(File file) {
        if (!file.exists()) {
            return "错误：文件不存在。";
        }

        String fileName = file.getName().toLowerCase();

        try {
            // 1. 判断文件类型并处理
            if (fileName.endsWith(".pdf")) {
                return readQrFromPdf(file);
            } else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith(".png") || fileName.endsWith(".gif")) {
                return readQrFromImage(file);
            } else {
                return "错误：不支持的文件格式。请提供图片(.jpg, .png等)或PDF(.pdf)文件。";
            }

        } catch (Exception e) {
            // 捕获所有其他未预料的异常
            return "处理文件时发生未知错误: " + e.getMessage();
        }
    }

    /**
     * 从图片文件中识别二维码
     */
    private static String readQrFromImage(File imageFile) throws IOException {
        BufferedImage image = ImageIO.read(imageFile);
        if (image == null) {
            return "无法加载图片或图片格式不支持。";
        }
        return decodeImage(image);
    }

    /**
     * 从PDF文件中识别二维码
     */
    private static String readQrFromPdf(File pdfFile) throws IOException {
        try (PDDocument document = PDDocument.load(pdfFile)) { // try-with-resources 确保文档被关闭
            if (document.isEncrypted()) {
                return "错误：无法处理加密的PDF文件。";
            }

            PDFRenderer renderer = new PDFRenderer(document);
            int numPages = document.getNumberOfPages();

            System.out.println("开始扫描PDF文件，共 " + numPages + " 页...");

            for (int i = 0; i < numPages; i++) {
                // 将第 i 页渲染成 BufferedImage
                // 300 是 DPI (dots per inch)，值越高图片越清晰，但识别速度越慢。300是一个不错的平衡。
                BufferedImage image = renderer.renderImageWithDPI(i, 300);
                String result = decodeImage(image);

                // 如果在当前页识别到了二维码，直接返回结果
                if (!result.startsWith("在图片中未找到二维码") && !result.startsWith("识别二维码时发生未知错误")) {
                    System.out.println("在第 " + (i + 1) + " 页成功识别到二维码。");
                    return result;
                }
            }
            // 如果所有页都扫描完仍未找到
            return "在PDF文件的所有页面中均未找到二维码。";
        }
    }

    /**
     * 核心解码逻辑，接收一个 BufferedImage 并尝试识别其中的二维码
     */
    private static String decodeImage(BufferedImage image) {
        try {
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            Map<DecodeHintType, Object> hints = new HashMap<>();
            hints.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.of(BarcodeFormat.QR_CODE));
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);

            MultiFormatReader reader = new MultiFormatReader();
            Result result = reader.decode(bitmap, hints);

            return "内容: " + result.getText() + "; 格式: " + result.getBarcodeFormat();

        } catch (NotFoundException e) {
            // 这个异常是预期的，当图片中没有二维码时抛出
            return "在图片中未找到二维码。";
        } catch (Exception e) {
            return "识别二维码时发生未知错误: " + e.getMessage();
        }
    }
}