package com.ruoyi.gysl.utils;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HtmlToPdfConverter {

    public static MultipartFile convertHtmlToPdf(String htmlArticleTitle, String htmlContent) throws IOException {

        String ht = content2Html(htmlContent);


        String path = System.getProperty("user.dir");
        // 根据日期建文件夹
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String[] split = format.split("-");
        Path dirPath = Paths.get(path, "temporary", split[0], split[1], split[2]);
        try {
            Files.createDirectories(dirPath);
        } catch (IOException e) {
            throw new RuntimeException("创建文件夹失败: " + e.getMessage(), e);
        }
        File pdfFile = new File(dirPath.toFile(), "pdf-" + System.currentTimeMillis() + ".pdf");
        // 创建PDF文档
        Document document = new Document();

        FileOutputStream fos = null;
        InputStream is = null;
        try {
            fos = new FileOutputStream(pdfFile);

            PdfWriter writer = PdfWriter.getInstance(document, fos);
            XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
            fontProvider.register("C:/Windows/Fonts/simsun.ttc");

            document.open();
            // 添加标题
            Paragraph paragraph = new Paragraph(htmlArticleTitle); // 设置你自定义的字体格式
            document.add(paragraph);
            String updatedHtmlContent = "";
            if (htmlContent.contains("img")) {
                updatedHtmlContent = replaceImgSrcWithBase64(ht);

                if (updatedHtmlContent != null) {
                    is = new ByteArrayInputStream(updatedHtmlContent.getBytes(StandardCharsets.UTF_8));
                    XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, StandardCharsets.UTF_8, fontProvider);
                    // 添加图片
                    Elements imgElements = Jsoup.parse(updatedHtmlContent).select("img");
                    for (Element img : imgElements) {
                        String imgSrc = img.attr("src");
                        if (imgSrc.startsWith("data:image/jpeg;base64,")) {
                            String base64Data = imgSrc.substring("data:image/jpeg;base64,".length());
                            byte[] imageBytes = Base64.getDecoder().decode(base64Data);
                            Image image = Image.getInstance(imageBytes);
                            document.add(image); // 添加图片到 PDF
                        }
                    }
                }

            } else {
                is = new ByteArrayInputStream(ht.getBytes(StandardCharsets.UTF_8));
                XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, StandardCharsets.UTF_8, fontProvider);

            }

        } catch (DocumentException | IOException e) {
            throw new RuntimeException("转换PDF失败: " + e.getMessage(), e);
        } finally {

            if (document.isOpen()) {
                document.close(); // 确保Document关闭
            }
            if (fos != null) {
                try {
                    fos.close(); // 关闭文件输出流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close(); // 关闭输入流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return getMultipartFile(pdfFile);
    }

    private static MultipartFile getMultipartFile(File file) throws IOException {
        try (FileInputStream fileInputStream = new FileInputStream(file)) {
            return new MockMultipartFile(file.getName(), file.getName(), "application/pdf", fileInputStream);
        }
    }

    public static String content2Html(String htmlContent) {
        String COMPLETE_CONTENT = "<html><head></head><body style=\"font-family: SimSun;\">" + htmlContent + "</body></html>";
        return COMPLETE_CONTENT.replace("<br>", "<br/>");
    }


    private static String replaceImgSrcWithBase64(String htmlContent) {
        List<String> imgSrcs = new ArrayList<>();
        String regex = "<img[^>]+src=\"([^\"]+)\"[^>]*>"; // 正确的正则表达式
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(htmlContent);
        String baseUrl = "http://39.101.188.84:7071";

        // 使用 StringBuilder 来构建新的 HTML
        StringBuilder updatedHtml = new StringBuilder(htmlContent);

        // 定义要替换的起始位置
        int offset = 0;

        while (matcher.find()) {
            String imgSrc = matcher.group(1); // 捕获组返回 img src 的值
            String imgUrl = baseUrl + imgSrc;

            // 将 URL 转化为 Base64
            try {
                URL url = new URL(imgUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestProperty("User-Agent", "Mozilla/5.0"); // 添加 User-Agent
                connection.setDoInput(true);
                connection.connect();
                InputStream inputStream = connection.getInputStream();
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                inputStream.close();
                byte[] imageBytes = outputStream.toByteArray();
                String base64 = Base64.getEncoder().encodeToString(imageBytes);

                // 替换 img 标签的 src 属性为 Base64 数据
                String base64ImgTag = "<img src=\"data:image/jpeg;base64," + base64 + "\" />";
                int start = matcher.start() + offset; // 累计偏移量
                int end = matcher.end();

                // 替换原来的 img 标签
                updatedHtml.replace(start, end, base64ImgTag);
                //System.out.println(updatedHtml.toString());
                // 更新偏移量
                offset += base64ImgTag.length() - (end - start);
            } catch (Exception e) {
                e.printStackTrace();
                return null; // 处理异常或返回特定的错误值
            }
        }
        return updatedHtml.toString();
    }

    public String convertImageToBase64(String imgUrl) {
        try {
            // String encodedImgUrl = URLEncoder.encode(imgUrl, StandardCharsets.UTF_8.toString());

            URL url = new URL(imgUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("User-Agent", "Mozilla/5.0"); // 添加 User-Agent
            connection.setDoInput(true);
            connection.connect();
            InputStream inputStream = connection.getInputStream();

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            inputStream.close();

            byte[] imageBytes = outputStream.toByteArray();
            String base64 = Base64.getEncoder().encodeToString(imageBytes);
            return "data:image/jpeg;base64," + base64; // 根据实际情况修改 MIME 类型
        } catch (Exception e) {
            e.printStackTrace();
            return null; // 处理异常或返回特定的错误值
        }
    }


}
