package org.example.mybatisplus.tools;

import com.alibaba.fastjson2.JSON;
import freemarker.template.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.zip.*;

public class WordExportDemo {

    public static void main(String[] args) {
        try {
            // 1. 初始化导出器
            WordExporter exporter = new WordExporter("G:\\Code\\new\\mybatisplus-fxy\\jijinhui.docx");
            Map<String, Object> data = new HashMap<>();

            Map<String, String> item = new HashMap<>();
            item.put("entName", "项目 66");
            item.put("name", "项目33");
            item.put("value", "值44");
            // 2. 添加文本数据
            exporter.addText("data", item);
            exporter.addText("item", item);

            // 3. 添加图片数据
            exporter.addImage(
                    "G:\\Code\\new\\fxy-tool\\src\\main\\resources\\pic1.png",  // 图片路径
                    "rIdImage1",               // 唯一关系ID
                    400,                       // 宽度（像素）
                    300                        // 高度（像素）
            );
            // 4. 生成文档
            exporter.export("output.docx");
            System.out.println("文档生成成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class WordExporter {
    private final Path templatePath;
    private final Map<String, Object> dataModel = new HashMap<>();
    private ImageData image;

    public WordExporter(String templatePath) {
        this.templatePath = Paths.get(templatePath);
    }

    public void addText(String key, Object value) {
        dataModel.put(key, value);
    }

    public void addImage(String imagePath, String relationId, int width, int height) {
        this.image = new ImageData(imagePath, relationId, width, height);
        dataModel.put("image", image);
    }

    public void export(String outputPath) throws Exception {
        Path tempDir = Paths.get("G:\\Code\\new\\mybatisplus-fxy\\jijinhui\\");
//        Files.createDirectories(tempDir);
//        System.out.println("临时目录: " + tempDir.toAbsolutePath());
        try {
            // 1. 解压模板
//            unzipTemplate(tempDir);

            System.out.println(JSON.toJSONString(this.dataModel));
            Map<String, Object> data = new HashMap<>();
            Map<String, String> item = new HashMap<>();
            item.put("entName", "项目 66");
            item.put("value", "值 66" );
            data.put("data", item);
            item.put("name", "项目33");
            item.put("value", "值44");
            data.put("item", item);
            data.put("image", new ImageData("G:\\Code\\new\\fxy-tool\\src\\main\\resources\\pic1.png",  // 图片路径
                    "rIdImage1",               // 唯一关系ID
                    400,                       // 宽度（像素）
                    300   ));
            // 2. 处理 XML 文件
            processXmlFile("/word/document.xml", data);
            processXmlFile("/word/_rels/document.xml.rels", data);

            // 3. 复制图片
            if (image != null) {
                copyImage(tempDir);
            }

            // 4. 重新打包
            zipDirectory(tempDir, Paths.get(outputPath));
        } finally {
            //deleteDirectory(tempDir.toFile());
        }
    }

    // ---------------------- 内部工具方法 ----------------------
    private void unzipTemplate(Path targetDir) throws IOException {
        try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(templatePath))) {
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                Path entryPath = targetDir.resolve(entry.getName());
                if (entry.isDirectory()) {
                    Files.createDirectories(entryPath);
                } else {
                    Files.createDirectories(entryPath.getParent());
                    Files.copy(zis, entryPath, StandardCopyOption.REPLACE_EXISTING);
                }
            }
        }
    }

    private void processXmlFile(String xmlPath, Map<String, Object> model) throws Exception {
        // 配置FreeMarker
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_34);
        cfg.setDirectoryForTemplateLoading(new File("G:\\Code\\new\\mybatisplus-fxy\\jijinhui"));
        cfg.setDefaultEncoding("UTF-8");

        // 处理模板
        Template template = cfg.getTemplate(xmlPath);
        StringWriter writer = new StringWriter();
        template.process(model, writer);
    }

    private void copyImage(Path tempDir) throws IOException {
        Path mediaDir = tempDir.resolve("word/media");
        Files.createDirectories(mediaDir);

        byte[] bytes = Files.readAllBytes(Paths.get(image.imagePath));
        String fileName = new File(image.imagePath).getName();
        Files.write(mediaDir.resolve(fileName), bytes);
        image.fileName = fileName;
    }

    private void zipDirectory(Path sourceDir, Path output) throws IOException {
        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(output))) {
            Files.walk(sourceDir)
                    .filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        String entryName = sourceDir.relativize(path).toString().replace("\\", "/");
                        try {
                            zos.putNextEntry(new ZipEntry(entryName));
                            Files.copy(path, zos);
                            zos.closeEntry();
                        } catch (IOException e) {
                            throw new UncheckedIOException(e);
                        }
                    });
        }
    }

    private void deleteDirectory(File dir) {
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    file.delete();
                }
            }
        }
        dir.delete();
    }

    // ---------------------- 图片数据类 ----------------------
    private static class ImageData {
        String imagePath;
        String relationId;
        int width;
        int height;
        String fileName;

        public ImageData(String imagePath, String relationId, int width, int height) {
            this.imagePath = imagePath;
            this.relationId = relationId;
            this.width = width;
            this.height = height;
        }

        // FreeMarker 访问的 getter
        public String getRelationId() { return relationId; }
        public int getWidth() { return width; }
        public int getHeight() { return height; }
        public String getFileName() { return fileName; }
    }
}
