package com.yaoyicloud.tools;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;

import com.deepoove.poi.xwpf.XWPFStructuredDocumentTag;

public final class DocxUtil {

    public static void mergeDocx(XWPFDocument target, List<XWPFDocument> sources, String outputPath)
        throws InvalidFormatException, FileNotFoundException, IOException {
        mergeDocx(target, sources, outputPath, true);
    }

    /*
     * 只更新target的内容，全局设定（fonts, styles, custom items）都使用target docx
     */
    public static void mergeDocx(XWPFDocument target, List<XWPFDocument> sources, String outputPath,
        boolean clearTargetBody) throws InvalidFormatException, FileNotFoundException, IOException {
        if (clearTargetBody) {
            target.getDocument().unsetBody();
            target.getDocument().addNewBody();
        }
        for (XWPFDocument source : sources) {
            appendSourceContent(target, source);
        }

        try (FileOutputStream out = new FileOutputStream(outputPath)) {
            target.write(out);
            target.close();
        }
    }

    private static void appendSourceContent(XWPFDocument target, XWPFDocument source) throws InvalidFormatException {
        for (IBodyElement element : source.getBodyElements()) {
            if (element instanceof XWPFParagraph) {
                appendParagraph(target, (XWPFParagraph) element);
            } else if (element instanceof XWPFTable) {
                appendTable(target, (XWPFTable) element);
            } else if (element instanceof XWPFStructuredDocumentTag) {
                // todo: 目录，自定义标签等
                continue;
            }
        }
    }

    private static void appendTable(XWPFDocument target, XWPFTable oldTable) {
        XWPFTable newTable = target.createTable();
        newTable.getCTTbl().set(oldTable.getCTTbl().copy());
    }

    private static void appendParagraph(XWPFDocument target, XWPFParagraph oldParagraph) throws InvalidFormatException {
        // Remove additional blank page
        // if (i == doc1.getBodyElements().size() - 1
        // && oldParagraph.isPageBreak()
        // && StrUtil.isBlank(oldParagraph.getText())) {
        // continue;
        // }

        // Copy Picture
        for (int i = 0; i < oldParagraph.getRuns().size(); i++) {
            XWPFRun oldRun = oldParagraph.getRuns().get(i);

            // Check if the run has embedded images
            List<XWPFPicture> pictures = oldRun.getEmbeddedPictures();
            for (int j = 0; j < pictures.size(); j++) {
                XWPFPictureData picData = pictures.get(j).getPictureData();

                // copy picture
                // String fileName = picData.getFileName();
                String newRelationId = target.addPictureData(picData.getData(), picData.getPictureType());

                // update image rId to the new run
                // 注意这里用新文件的rId更新了旧文件的Run，然后复制旧文件的XML到新文件
                // 如果直接编辑新文件需要在复制XML后重新生成XWPFParagraph对象，才能正确反映更新的XML数据
                CTPicture ctPic = pictures.get(j).getCTPicture();
                CTBlipFillProperties bill = ctPic.getBlipFill();
                CTBlip blip = bill.getBlip();
                blip.setEmbed(newRelationId);
            }
        }
        // Copy Xml content
        XWPFParagraph newParagraph = target.createParagraph();
        newParagraph.getCTP().set(oldParagraph.getCTP().copy());
    }

}
