package vip.xiaonuo.disk.util;

import io.minio.DownloadObjectArgs;
import io.minio.MinioClient;
import io.minio.UploadObjectArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.util.UUID;

@Component
public class PdfUtils {

    private final String minioEndpoint;
    private final String accessKey;
    private final String secretKey;
    private final String bucketName;
    private final MinioClient minioClient;
    private final String tempDir = System.getProperty("java.io.tmpdir") + "/minio-converter/";

    // 使用构造函数注入@Value属性
    @Autowired
    public PdfUtils(
            @Value("${ufop.minio.endpoint}") String minioEndpoint,
            @Value("${ufop.minio.access-key}") String accessKey,
            @Value("${ufop.minio.secret-key}") String secretKey,
            @Value("${ufop.minio.bucket-name}") String bucketName
    ) {
        this.minioEndpoint = minioEndpoint;
        this.accessKey = accessKey;
        this.secretKey = secretKey;
        this.bucketName = bucketName;
        this.minioClient = MinioClient.builder()
                .endpoint(minioEndpoint)
                .credentials(accessKey, secretKey)
                .build();
        createTempDir();
    }

    private void createTempDir() {
        File dir = new File(tempDir);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new RuntimeException("无法创建临时目录: " + tempDir);
        }
    }


    public void main(String[] args) throws Exception {
        convertToPdf("upload/20250611/答辩会议室号.xls","室号.pdf");
    }

//    @Async
    public void convertToPdf(String objectName, String fileId) throws Exception {
        long start = System.currentTimeMillis();
        File tempFile = null;

        try {
            // 1. 下载源文件
            tempFile = downloadFile(objectName);

            // 2. 执行转换
            String outputPath = convertToPdfLocal(tempFile.getAbsolutePath(), "convert");

            // 3. 上传转换结果
            uploadToMinio(outputPath, fileId);

        } finally {
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
            cleanTempDir();
        }
        System.out.println("总耗时：" + (System.currentTimeMillis() - start) + "ms");
    }

    private File downloadFile(String objectName) throws Exception {
        // 提取纯文件名（去除路径）
        String fileName = new File(objectName).getName();
        // 生成唯一临时文件名
        String uniqueName = UUID.randomUUID() + "_" + fileName;
        File tempFile = new File(tempDir, uniqueName);

        minioClient.downloadObject(
                DownloadObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .filename(tempFile.getAbsolutePath())
                        .build());
        return tempFile;
    }

    // 新增路径创建工具方法
    private void ensureDirectoryExists(String path) {
        File dir = new File(path).getParentFile();
        if (dir != null && !dir.exists()) {
            if (!dir.mkdirs()) {
                throw new RuntimeException("无法创建目录: " + dir.getAbsolutePath());
            }
        }
    }

    private String convertToPdfLocal(String filePath, String targetFolder) {
        String osName = System.getProperty("os.name").toLowerCase();
        String outputPath = tempDir + "converted_" + System.currentTimeMillis() + ".pdf";
        // 在执行转换前确保输出目录存在
        ensureDirectoryExists(outputPath);
        try {
            ProcessBuilder processBuilder = new ProcessBuilder();
            if (osName.contains("windows")) {
                processBuilder.command(
                        "cmd.exe", "/c",
                        "soffice", "--headless", "--convert-to", "pdf",
                        filePath, "--outdir", tempDir);
            } else {
                processBuilder.command(
                        "soffice", "--headless", "--convert-to", "pdf:writer_pdf_Export",
                        filePath, "--outdir", tempDir);
            }

            Process process = processBuilder.start();
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                throw new RuntimeException("转换失败，退出码：" + exitCode);
            }


            // 查找生成的PDF文件
            File outputDir = new File(tempDir);
            File[] files = outputDir.listFiles((dir, name) ->
                    name.toLowerCase().endsWith(".pdf") && !name.equals(filePath));

            if (files != null && files.length > 0) {
                File pdfFile = files[0];
                Files.move(pdfFile.toPath(), new File(outputPath).toPath());
                return outputPath;
            }
            throw new FileNotFoundException("未找到生成的PDF文件");

        } catch (IOException | InterruptedException e) {
            throw new RuntimeException("转换过程中发生错误", e);
        }
    }

    private void uploadToMinio(String filePath, String fileId) throws Exception {
        String fileName = new File(filePath).getName();

        minioClient.uploadObject(
                UploadObjectArgs.builder()
                        .bucket(bucketName)
                        .object("converted/"+fileId)
                        .filename(filePath)
                        .build());
    }

    private void cleanTempDir() {
        File[] files = new File(tempDir).listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.getName().startsWith("converted_") ||
                        file.getName().startsWith("temp_")) {
                    file.delete();
                }
            }
        }
    }


    public String getFileUrl(String objectName) {
        return minioEndpoint + "/" + bucketName + "/" + objectName;
    }

//    public List<String> convertToPng(String pdfObjectName, int pages) throws Exception {
//        File tempPdf = downloadFile(pdfObjectName);
//        List<String> pngUrls = new ArrayList<>();
//
//        try (PDDocument document = PDDocument.load(tempPdf)) {
//            PDFRenderer renderer = new PDFRenderer(document);
//            String baseName = tempPdf.getName().replace(".pdf", "");
//
//            for (int i = 0; i < pages; i++) {
//                BufferedImage image = renderer.renderImageWithDPI(i, 150);
//                String outputPath = tempDir + baseName + "_" + (i + 1) + ".png";
//                ImageIO.write(image, "PNG", new File(outputPath));
//                uploadToMinio(outputPath, "png/" + baseName);
//                pngUrls.add(getFileUrl("png/" + baseName + "/" + new File(outputPath).getName()));
//            }
//        } finally {
//            tempPdf.delete();
//            cleanTempDir();
//        }
//        return pngUrls;
//    }
//
//    /***
//     * PDF文件转PNG图片，全部页数
//     *
//     * @param PdfFilePath pdf文件路径 物理路径
//     * @param dstImgFolder 图片存放的文件夹
//     * @param dpi dpi越大转换后越清晰，相对转换速度越慢 dpi为96,100,105,120,150,200中,105显示效果较为清晰,体积稳定,dpi越高图片体积越大,一般电脑显示分辨率为96
//     * @return
//     */
//    public int pdf2Image(String PdfFilePath, String dstImgFolder, int dpi) {
//        int pages = 1;
//        PDDocument pdDocument;
//        try {
//            File file = new File(PdfFilePath);
//            while (!file.exists()) {
//                System.out.println("文件未生成，等待1秒");
//                Thread.sleep(1000);
//            }
//            pdDocument = PDDocument.load(file);
//            int dot = PdfFilePath.lastIndexOf('.');
//            int lastSep = PdfFilePath.lastIndexOf(File.separator) + 1;
//            String imagePDFName = PdfFilePath.substring(lastSep, dot); // 获取图片文件名
//
//            PDFRenderer renderer = new PDFRenderer(pdDocument);
//            /* dpi越大转换后越清晰，相对转换速度越慢 */
//            pages = pdDocument.getNumberOfPages();
//            StringBuffer imgFilePath = null;
//            for (int i = 0; i < pages; i++) {
//                String imgFilePathPrefix = dstImgFolder + File.separator + imagePDFName;
//                imgFilePath = new StringBuffer();
//                imgFilePath.append(imgFilePathPrefix);
//                imgFilePath.append("_");
//                imgFilePath.append(String.valueOf(i + 1));
//                imgFilePath.append(".png");
//                File dstFile = new File(imgFilePath.toString());
//                BufferedImage image = renderer.renderImageWithDPI(i, dpi);
//                ImageIO.write(image, "png", dstFile);
//            }
//            System.out.println("PDF文档转PNG图片成功！");
//        } catch (IOException | InterruptedException e) {
//            e.printStackTrace();
//        }
//        return pages;
//    }

}
