package com.ningdatech.kqapi.common.util;

import cn.hutool.core.io.IoUtil;
import com.ningdatech.basic.exception.BizException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.core.io.ByteArrayResource;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * <p>
 * FreemarkerWordUtil
 * </p>
 *
 * @author WendyYang
 * @since 2023/7/24
 **/
@Slf4j
public class FreemarkerWordUtil {

    private static void setDownFileName(HttpServletResponse response, String fileName) {
        String fileNameEncoded;
        try {
            fileNameEncoded = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("文件名编码异常");
        }
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoded);
    }

    private static final Configuration CONFIGURATION = new Configuration(Configuration.VERSION_2_3_31);

    static {
        CONFIGURATION.setDefaultEncoding("UTF-8");
        CONFIGURATION.setClassForTemplateLoading(FreemarkerWordUtil.class, "/template");
    }

    /**
     * 生成word文件
     *
     * @param dataMap      word中需要展示的动态数据，用map集合来保存
     * @param templateName word模板名称，例如：test.ftl
     * @param filePath     文件生成的目标路径，例如：D:/wordFile/
     * @param fileName     生成的文件名称，例如：test.doc
     */
    public static void create(Object dataMap, String templateName, String filePath, String fileName) {
        try {
            Template template = CONFIGURATION.getTemplate(templateName);
            //输出文件
            File outFile = new File(filePath + File.separator + fileName);
            //如果输出目标文件夹不存在，则创建
            if (!outFile.getParentFile().exists()) {
                boolean ignore = outFile.getParentFile().mkdirs();
            }
            //将模板和数据模型合并生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(outFile.toPath()), StandardCharsets.UTF_8));
            //生成文件
            template.process(dataMap, out);
            IoUtil.flush(out);
            IoUtil.close(out);
        } catch (Exception e) {
            log.error("根据模版生成Word文件失败：", e);
            throw BizException.wrap("根据模版生成Word文件失败");
        }
    }

    public static void export(String fileName, Object data, HttpServletResponse response, String templateName) throws TemplateException, IOException {
        Template template = CONFIGURATION.getTemplate(templateName);
        response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
        response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
        setDownFileName(response, fileName);
        try (StringWriter out = new StringWriter();
             Writer writer = new BufferedWriter(out, 4096)) {
            template.process(data, writer);
            try (InputStream is = new ByteArrayResource(out.toString().getBytes(StandardCharsets.UTF_8)).getInputStream();
                 ServletOutputStream outputStream = response.getOutputStream()) {
                // 缓冲区
                byte[] buffer = new byte[1024];
                int bytesToRead;
                // 通过循环将读入的Word文件的内容输出到浏览器中
                while ((bytesToRead = is.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesToRead);
                }
            }
        }


    }

}
