package com.artfess.base.util;

import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class WordUtil {

    /**
     * 生成word文件
     *
     * @param dataMap      word中需要展示的动态数据，用map集合来保存
     * @param templateName word模板名称，例如：test.ftl
     * @param filePath     文件生成的目标路径，例如：D:/wordFile/
     * @param fileName     生成的文件名称，例如：test.doc
     */
    @SuppressWarnings("unchecked")
    public static void createWord(HttpServletResponse response, Map dataMap, String templateName, String filePath, String fileName) {
        try {
            //创建配置实例
            Configuration configuration = new Configuration();
            //设置编码
            configuration.setDefaultEncoding("UTF-8");
            //ftl模板文件
            configuration.setClassForTemplateLoading(WordUtil.class, "/");
            //获取模板
            Template template = configuration.getTemplate("FTL_Template/" + templateName);
            //输出文件
            File outFile = new File(filePath);

            //如果输出目标文件夹不存在，则创建
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }
            //将模板和数据模型合并生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));
            //生成文件
            template.process(dataMap, out);
            //关闭流
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static File generateAndZipWordFiles(List<?> dataList, String filePath, String docName, String outputZipPath) {
        try {
            // 初始化 FreeMarker 配置
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
            configuration.setDefaultEncoding("UTF-8");
            configuration.setClassForTemplateLoading(WordUtil.class, "/");
            // 设置数字格式，避免千分位分隔
            configuration.setNumberFormat("0");
            // 创建临时目录存放生成的 Word 文件
            File tempDir = new File("tempWordFiles");
            if (!tempDir.exists()) {
                tempDir.mkdir();
            }
            // 循环生成 Word 文件
            for (int i = 0; i < dataList.size(); i++) {
                Object data = dataList.get(i);
                String outputFilePath = tempDir.getAbsolutePath() + File.separator + docName + i + ".docx";
                File outputFile = new File(outputFilePath);

                // 获取模板并生成 Word 文件
                Template template = configuration.getTemplate(filePath);
                try (FileOutputStream fos = new FileOutputStream(outputFile);
                     BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8))) {
                    template.process(data, writer);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            // 将所有 Word 文件打包成 ZIP 文件
            try (FileOutputStream fos = new FileOutputStream(outputZipPath);
                 ZipOutputStream zipOut = new ZipOutputStream(fos)) {
                for (File file : tempDir.listFiles()) {
                    try (FileInputStream fis = new FileInputStream(file)) {
                        // 创建 ZIP 条目
                        ZipEntry zipEntry = new ZipEntry(file.getName());
                        zipOut.putNextEntry(zipEntry);
                        // 将文件内容写入 ZIP
                        byte[] bytes = new byte[1024];
                        int length;
                        while ((length = fis.read(bytes)) >= 0) {
                            zipOut.write(bytes, 0, length);
                        }
                    }
                }
            }
            // 删除临时目录及其内容
            deleteTempDir(tempDir);
            return new File(outputZipPath);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static void deleteTempDir(File tempDir) {
        if (tempDir.isDirectory()) {
            File[] files = tempDir.listFiles();
            if (files != null) {
                for (File file : files) {
                    deleteTempDir(file);
                }
            }
        }
        tempDir.delete();
    }
}

