package com.smppw.modaq.infrastructure.util;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.docx4j.Docx4J;
import org.docx4j.openpackaging.packages.OpcPackage;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;

public class PdfUtil {

    public static void validateDocx(String path) throws Exception {
        File file = new File(path);

        // 基础检查
        if (!file.exists()) throw new FileNotFoundException("文件不存在");
        if (!file.canRead()) throw new IOException("无读取权限");
        if (file.length() == 0) throw new IOException("文件为空");

        // 文件头检查
        try (InputStream is = new FileInputStream(file)) {
            byte[] header = new byte[4];
            if (is.read(header) < 4) throw new IOException("文件过小");
            if (header[0] != 0x50 || header[1] != 0x4B) { // PK 头
                throw new IOException("不是ZIP格式文件");
            }
        }

        // 尝试作为ZIP打开
        try (java.util.zip.ZipFile zip = new java.util.zip.ZipFile(file)) {
            if (zip.getEntry("[Content_Types].xml") == null) {
                throw new IOException("缺少[Content_Types].xml");
            }
        } catch (IOException e) {
            throw new IOException("无效的ZIP格式: " + e.getMessage());
        }
    }

    public static void convertDocxToPdf(String input, String output) throws Exception {
        validateDocx(input);
        try (OutputStream os = new FileOutputStream(output)) {
            OpcPackage opc = OpcPackage.load(new File(input));
            if (opc instanceof WordprocessingMLPackage) {
                Docx4J.toPDF((WordprocessingMLPackage) opc, os);
            } else {
                throw new Exception("不是WordprocessingML文档");
            }
        }
    }

    /**
     * 将 PDF 的首页和尾页转换为 PNG 图片
     *
     * @param pdfFilepath 输入的 PDF 文件
     * @param outputDir   输出目录
     * @param dpi         图片分辨率（默认建议 300）
     * @return 生成的图片文件列表
     */
    public static List<String> convertFirstAndLastPagesToPng(String pdfFilepath, File outputDir, int dpi) throws IOException {
        List<String> generatedImages = ListUtil.list(false);

        try (PDDocument document = Loader.loadPDF(new RandomAccessReadBufferedFile(pdfFilepath))) {
            int totalPages = document.getNumberOfPages();
            if (totalPages == 0) {
                throw new IOException("PDF 文件无有效页面");
            }

            // 准备输出目录
            if (!outputDir.exists() && !outputDir.mkdirs()) {
                throw new IOException("无法创建输出目录: " + outputDir);
            }

            String baseName = FileUtil.mainName(pdfFilepath);
            PDFRenderer renderer = new PDFRenderer(document);

            // 始终处理首页（页码从1开始）
            String firstImg = renderPage(renderer, 0, baseName + ".png", outputDir, dpi);
            generatedImages.add(compressAndSave(firstImg));

            // 处理尾页（当总页数 > 1 时）
            if (totalPages > 1) {
                String lastImg = renderPage(renderer, totalPages - 1,
                        baseName + "_footer.png",
                        outputDir, dpi);
                generatedImages.add(compressAndSave(lastImg));
            }
        }

        return generatedImages;
    }

    /**
     * 渲染单页并保存为图片
     */
    private static String renderPage(PDFRenderer renderer, int pageIndex,
                                     String fileName, File outputDir, int dpi) throws IOException {
        BufferedImage image = renderer.renderImageWithDPI(pageIndex, dpi);
        File outputFile = new File(outputDir, fileName);
        ImageIO.write(image, "PNG", outputFile);
        return outputFile.getAbsolutePath();
    }

    /**
     * 检查图片分辨率是否超过限制
     *
     * @param image   图片对象
     * @param maxSize 最大允许尺寸（单边像素数）
     * @return 是否超出限制
     */
    private static boolean isResolutionExceeded(BufferedImage image, int maxSize) {
        return image.getWidth() > maxSize || image.getHeight() > maxSize;
    }

//    /**
//     * 压缩图片并转换为Base64
//     *
//     * @param inputFile 输入图片文件
//     * @param maxSize   最大允许尺寸（单边像素数）
//     * @param quality   压缩质量 (0.0-1.0)
//     * @param format    输出格式 ("jpg", "png"等)
//     * @return Base64编码的图片数据
//     */
//    public static String compressAndConvertToBase64(File inputFile, int maxSize, float quality, String format)
//            throws IOException {
//
//        // 读取原始图片
//        BufferedImage originalImage = ImageIO.read(inputFile);
//
//        // 检查分辨率是否超出限制
//        if (!isResolutionExceeded(originalImage, maxSize)) {
//            System.out.println("图片尺寸符合要求，无需压缩");
//        }
//
//        // 计算新尺寸（保持宽高比）
//        int originalWidth = originalImage.getWidth();
//        int originalHeight = originalImage.getHeight();
//        double ratio = (double) maxSize / Math.max(originalWidth, originalHeight);
//        int newWidth = (int) (originalWidth * ratio);
//        int newHeight = (int) (originalHeight * ratio);
//
//        // 创建缩放后的图片
//        Image scaledImage = originalImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
//        BufferedImage outputImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
//
//        // 绘制缩放后的图片
//        Graphics2D g2d = outputImage.createGraphics();
//        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//        g2d.drawImage(scaledImage, 0, 0, null);
//        g2d.dispose();
//
//        // 转换为Base64
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        ImageIO.write(outputImage, format, baos);
//        byte[] imageBytes = baos.toByteArray();
//
//        return Base64.getEncoder().encodeToString(imageBytes);
//    }

    public static String compressAndSave(String inputFile) throws IOException {
        return compressAndSave(FileUtil.file(inputFile));
    }

    public static String compressAndSave(File inputFile) throws IOException {
        int maxSize = 8192;
        String format = FileUtil.extName(inputFile);
        return compressAndSave(inputFile, null, maxSize, format);
    }

    /**
     * 压缩图片并保存到文件
     *
     * @param inputFile  输入文件
     * @param outputFile 输出文件
     * @param maxSize    最大尺寸
     * @param format     输出格式
     */
    public static String compressAndSave(File inputFile, File outputFile, int maxSize, String format)
            throws IOException {

        BufferedImage originalImage = ImageIO.read(inputFile);

        if (!isResolutionExceeded(originalImage, maxSize)) {
            if (outputFile != null) {
                // 直接复制文件
                Files.copy(inputFile.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
                return outputFile.getAbsolutePath();
            }
            return inputFile.getAbsolutePath();
        }
        if (outputFile == null) {
            outputFile = inputFile;
        }

        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
        double ratio = (double) maxSize / Math.max(originalWidth, originalHeight);
        int newWidth = (int) (originalWidth * ratio);
        int newHeight = (int) (originalHeight * ratio);

        Image scaledImage = originalImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
        BufferedImage outputImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2d = outputImage.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.drawImage(scaledImage, 0, 0, null);
        g2d.dispose();

        // 保存到文件
        ImageIO.write(outputImage, format, outputFile);
        return outputFile.getAbsolutePath();
    }

    public static void main(String[] args) {
        try {
            // 示例用法
            File inputFile = new File("D:\\home\\wwwroot\\mo_report_file\\wangzaijun@simuwang.com\\20250605\\image\\泓湖泓福积极配置2期私募证券投资基金-周报-20250530.png");
            int maxSize = 8192; // OpenAI限制

            // 1. 检查图片是否超出限制
            BufferedImage image = ImageIO.read(inputFile);
            if (isResolutionExceeded(image, maxSize)) {
                System.out.println("图片超出尺寸限制，需要压缩");
                System.out.println("原始尺寸: " + image.getWidth() + "x" + image.getHeight());

//                // 2. 压缩并转换为Base64
//                String base64Image = compressAndConvertToBase64(inputFile, maxSize, 0.85f, "png");
//                System.out.println("Base64 数据长度: " + base64Image.length());
//                System.out.println("Base64 前缀: " + base64Image.substring(0, 50) + "...");

                // 3. 压缩并保存到文件
                File outputFile = new File("D:\\home\\wwwroot\\mo_report_file\\wangzaijun@simuwang.com\\20250605\\image\\泓湖泓福积极配置2期私募证券投资基金-周报-20250530.png");
                String output = compressAndSave(inputFile, outputFile, maxSize, "png");
                System.out.println("图片已压缩保存到: " + output);

                // 验证压缩后尺寸
                BufferedImage compressedImage = ImageIO.read(outputFile);
                System.out.println("压缩后尺寸: " + compressedImage.getWidth() + "x" + compressedImage.getHeight());
            } else {
                System.out.println("图片尺寸符合要求");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
