package org.example.mybatisplus.tools;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

import java.io.*;
import java.util.List;

public class WordPoiExporter {

    public static void init(String source,String path,JSONObject data) throws IOException {
//        InputStream stream = WordPoiExporter.class.getResourceAsStream("/foundation_report_template.json");
//        String json = inputStreamToString(stream);
//        JSONObject jsonObject = JSON.parseObject(json);

        try {
            XWPFDocument doc = processTemplate(source, data);
            FileOutputStream out = new FileOutputStream(path);

            doc.write(out);
            out.close();
//            saveAsPdf(doc, FxyTool.class.getResource("/output.pdf").getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static String inputStreamToString(InputStream stream) throws IOException {
        StringBuilder sb = new StringBuilder();
        InputStreamReader isr = new InputStreamReader(stream, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String read;
        while ((read = br.readLine()) != null) {
            sb.append(read);
        }
        br.close();
        return sb.toString();
    }
    private static void replaceTextWithFormat(XWPFParagraph paragraph,JSONObject jsonObject) {
        // 遍历所有Run（保留格式的最小单位）
        for (XWPFRun run : paragraph.getRuns()) {
            String runText = run.getText(0);
            if (runText == null) continue;
            if (runText.indexOf("${")>-1 && runText.indexOf("${image")==-1){
                System.out.println(runText);
                //获取变量属性值
                String key=runText.substring(runText.indexOf("${")+2,runText.indexOf("}"));
                String[] keys=key.split(":");
                System.out.println(JSONObject.toJSONString(keys));
                JSONObject data=jsonObject.getJSONObject(keys[0]);
                System.out.println(JSONObject.toJSONString(data));
                if(data==null) continue;
                if(keys.length==2){
                    String placeholder = "${" +key + "}";
                    if (runText.contains(placeholder)) {
                        System.out.println(placeholder);
                        String value=data.getString(keys[1]);
                        if(value==null)value="";
                        // 直接修改Run的文本（保留原格式）
                        run.setText(runText.replace(placeholder, value), 0);
                    }
                }else if(keys.length==3){
                    JSONObject data1=data.getJSONObject(keys[1]);
                    String placeholder = "${" +key + "}";
                    if (runText.contains(placeholder)) {
                        // 直接修改Run的文本（保留原格式）
                        String value=data1.getString(keys[2]);
                        if(value==null)value="";
                        run.setText(runText.replace(placeholder, value), 0);
                    }
                }
            }
        }
    }
    private static XWPFDocument processTemplate(String templatePath,
                                                JSONObject jsonObject) throws Exception {
        InputStream stream = new FileInputStream(templatePath);
        XWPFDocument doc = new XWPFDocument(stream);

        // 处理段落中的变量
        for (XWPFParagraph paragraph : doc.getParagraphs()) {
            replaceTextWithFormat(paragraph, jsonObject);
        }

        // 处理表格
        for (XWPFTable tbl : doc.getTables()) {
            List<XWPFTableRow> rows = tbl.getRows();
            for (int i = rows.size()-1; i >= 0; i--) {
                XWPFTableRow row = rows.get(i);
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph p : cell.getParagraphs()) {
                        String text = p.getText();
                        if (text.contains("${tableRow:")) {
                            String key=text.substring(text.indexOf("${")+2,text.indexOf("}"));
                            String[] keys=key.split(":");
                            // 找到表格占位行
                            // 获取原行（这里选择第一行作为示例）
                            JSONObject obj = jsonObject.getJSONObject(keys[1]);
                            System.out.println(JSONObject.toJSONString(keys));
                            JSONArray tableData = obj.getJSONArray(keys[2]);
                            if (tableData != null && tableData.size() > 0) {
                                addTableRows(tbl, tableData, row);
                            }
                            tbl.removeRow(tbl.getRows().indexOf(row));
                        } else {
                            replaceTextWithFormat(p, jsonObject);
                        }
                    }
                }
            }

        }

        // 处理图片（需要提前在模板中使用${image:imagePath}占位）
        for (XWPFParagraph p : doc.getParagraphs()) {
            List<XWPFRun> runs = p.getRuns();
            for (int i=0; i<runs.size(); i++) {
                XWPFRun placeholderRun=runs.get(i);
                String text = placeholderRun.getText(0);
                if (text != null && text.startsWith("${image:")) {
                    String placeholder = text.substring(8, text.length()-1);
                    System.out.println(placeholder);
                    String imagePath = (String) jsonObject.get(placeholder);
                    p.removeRun(p.getRuns().indexOf(placeholderRun));
                    if(StringUtils.isNotBlank(imagePath))
                        ImageUtils.insertImage(doc,p, imagePath, placeholderRun);
                }
            }
        }

        return doc;
    }

    private static void addTableRows(XWPFTable table, JSONArray data,XWPFTableRow sourceRow) {
        for (Object rowData : data) {
            JSONObject row = (JSONObject) rowData;
            XWPFTableRow newRow = table.createRow();
            copyRowStyle(sourceRow, newRow);
            int col = 0;
            for (Object value : row.values()) {
                XWPFTableCell sourceCell = sourceRow.getCell(col);
                XWPFTableCell newCell = newRow.getCell(col);
                copyCellContentAndStyle(sourceCell, newCell);
                newCell.setText(value.toString());
                col++;
            }
        }
    }

    // 复制行样式
    private static void copyRowStyle(XWPFTableRow sourceRow, XWPFTableRow targetRow) {
        targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
    }

    // 复制单元格内容和样式
    private static void copyCellContentAndStyle(XWPFTableCell sourceCell, XWPFTableCell targetCell) {
        // 复制单元格样式
        targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());

        // 复制段落内容和样式
        for (int i = 0; i < sourceCell.getParagraphs().size(); i++) {
            XWPFParagraph sourcePara = sourceCell.getParagraphs().get(i);
            XWPFParagraph targetPara;
            if (i < targetCell.getParagraphs().size()) {
                targetPara = targetCell.getParagraphs().get(i);
            } else {
                targetPara = targetCell.addParagraph();
            }
            copyParagraphContentAndStyle(sourcePara, targetPara);
        }
    }

    // 复制段落内容和样式
    private static void copyParagraphContentAndStyle(XWPFParagraph sourcePara, XWPFParagraph targetPara) {
        targetPara.getCTP().setPPr(sourcePara.getCTP().getPPr());

        // 复制文本内容和样式
        for (int i = 0; i < sourcePara.getRuns().size(); i++) {
            XWPFRun sourceRun = sourcePara.getRuns().get(i);
            XWPFRun targetRun = targetPara.createRun();
            targetRun.getCTR().setRPr(sourceRun.getCTR().getRPr());
        }
    }
    public static void convertWordToPdf(String inputFilePath, String outputFilePath)  {
//        try (FileInputStream fis = new FileInputStream(inputFilePath);
//             XWPFDocument document = new XWPFDocument(fis);
//             FileOutputStream fos = new FileOutputStream(outputFilePath)) {
//
//            PdfOptions options = PdfOptions.create();
//            PdfConverter.getInstance().convert(document, fos, options);
//        } catch (FileNotFoundException e) {
//            throw new RuntimeException(e);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
    }
    public static void convert(String inputPath, String outputPath) {
        try {
            // 设置类加载器
            Thread.currentThread().setContextClassLoader(WordPoiExporter.class.getClassLoader());

            // 加载 DOCX 文件
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputPath));

            // 创建 FOSettings 对象
            FOSettings foSettings = Docx4J.createFOSettings();
            foSettings.setWmlPackage(wordMLPackage);

            // 指定输出为 PDF
            foSettings.setApacheFopMime("application/pdf");

            // 创建输出流
            OutputStream outputStream = new FileOutputStream(new File(outputPath));

            // 执行转换
            Docx4J.toFO(foSettings, outputStream, Docx4J.FLAG_NONE);

            // 创建字体映射器
            Mapper fontMapper = new IdentityPlusMapper();

//            // 字体文件的 URI，可以是本地文件的 URI 或者网络文件的 URI
//            String fontFilePath = "C:\\Windows\\Fonts\\微软雅黑.ttf"; // 替换为实际的字体文件 URI
//            URI fontUri = new URI(fontFilePath);
//
//            PhysicalFonts.addPhysicalFont(fontUri);
//            URI fontUri1 = new URI("C:\\Windows\\Fonts\\思源黑体.ttf");
//
//            PhysicalFonts.addPhysicalFont(fontUri1);

            /*WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputPath));
            FOSettings foSettings = Docx4J.createFOSettings();
            foSettings.setWmlPackage(wordMLPackage);

            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                Docx4J.toPDF(wordMLPackage, fos);
            }*/

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void saveAsPdf(XWPFDocument doc, String pdfPath) throws Exception {
        // 创建PDF文档
        /*try (PDDocument pdfDoc = new PDDocument()) {
            PDPage page = new PDPage();
            pdfDoc.addPage(page);

            // 写入内容
            try ( PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, page)) {
                contentStream.setFont(PDType1Font.HELVETICA, 12);
                float margin = 50;
                float yStart = page.getMediaBox().getHeight() - margin;
                float yPosition = yStart;

                // 处理段落
                for (XWPFParagraph para : doc.getParagraphs()) {
                    String text = para.getText();
                    if (text == null || text.isEmpty()) continue;

                    // 写入文本（简单换行处理）
                    String[] lines = text.split("\n");
                    for (String line : lines) {
                        if (yPosition < margin) {
                            contentStream.close();
                            page = new PDPage();
                            pdfDoc.addPage(page);
                            contentStream = new PDPageContentStream(pdfDoc, page);
                            yPosition = yStart;
                        }
                        contentStream.beginText();
                        contentStream.newLineAtOffset(margin, yPosition);
                        contentStream.showText(line);
                        contentStream.endText();
                        yPosition -= 15; // 行间距
                    }
                }

                // 保存PDF
                contentStream.close();
                pdfDoc.save(pdfPath);
            }
        }*/
    }
}
