package cn.com.ty.lift.common.utils;

import cn.hutool.core.util.StrUtil;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

//import javax.servlet.ServletOutputStream;
//import javax.servlet.http.HttpServletResponse;


public class WordUtil {

    private static Logger logger = LoggerFactory.getLogger(WordUtil.class);

    /**
     * 图片转base64的字符串
     *
     * @param imageAbsolutePath 图片路径
     * @return String
     */
    public static String imageToBase64Str(String imageAbsolutePath) {
        try (InputStream is = new FileInputStream(imageAbsolutePath)) {
            byte[] data = new byte[is.available()];
            is.read(data);
//            Base64Encoder encoder = new Base64Encoder();
//            return encoder.encode(data);
            return Base64.getEncoder().encodeToString(data);
        } catch (Exception e) {
            logger.error("图片转base64异常", e);
            return null;
        }
    }

    /**
     * 初始化配置文件
     *
     * @param folderPath 生成word的文件夹路径
     * @return Configuration
     */
    private static Configuration initConfiguration(String folderPath) {
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setTimeFormat("HH:mm:ss");
        configuration.setDateFormat("yyyy-MM-dd");
        configuration.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
        configuration.setObjectWrapper(new BeansWrapper() {
            @Override
            public TemplateModel wrap(Object object) throws TemplateModelException {
                if (object instanceof LocalDate) {
                    return new SimpleDate(Date.valueOf((LocalDate) object));
                }
                if (object instanceof LocalTime) {
                    return new SimpleDate(Time.valueOf((LocalTime) object));
                }
                if (object instanceof LocalDateTime) {
                    return new SimpleDate(Timestamp.valueOf((LocalDateTime) object));
                }
                return super.wrap(object);
            }
        });
        try {
            configuration.setDirectoryForTemplateLoading(new File(folderPath));
        } catch (IOException e) {
            logger.error("初始化configuration失败，路径不存在：{}", folderPath);
            throw new IllegalArgumentException(StrUtil.format("初始化configuration失败，路径不存在：{}", folderPath));
        }
        return configuration;
    }

    /**
     * 将数据写入word，并输出到指定路径
     *
     * @param dataMap        需要写入word的数据
     * @param ftlFolderPath  指定的word模板所在的文件夹
     * @param tempName       指定的word模板名称
     * @param outputFilePath 输出路径
     */
    public static boolean createWord(Map<String, Object> dataMap, String ftlFolderPath, String tempName, String outputFilePath) {
        logger.info("开始创建word到本地");
        boolean result = false;
        Configuration configuration = initConfiguration(ftlFolderPath);
        Template t = null;
        try {
            t = configuration.getTemplate(tempName);
            t.setEncoding("utf-8");
        } catch (IOException e) {
            logger.error("在路径：{}里找不到：{}", ftlFolderPath, tempName);
            throw new IllegalArgumentException(StrUtil.format("在路径：{}里找不到：{}", ftlFolderPath, tempName));
        }
        File outFile = new File(outputFilePath);

        try (FileOutputStream fos = new FileOutputStream(outFile);
             Writer out = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"))) {
            t.process(dataMap, out);
            result = true;
            logger.info("word创建成功");
        } catch (FileNotFoundException e) {
            logger.error("文件不存在：{}", outFile);
            throw new IllegalArgumentException(StrUtil.format("文件不存在：{}", outFile));
        } catch (UnsupportedEncodingException e) {
            logger.error("未知的编码格式");
            throw new IllegalArgumentException("未知的编码格式");
        } catch (TemplateException e) {
            logger.error("模板异常");
            throw new IllegalArgumentException("模板异常");
        } catch (IOException e) {
            logger.error("IO异常");
            throw new IllegalArgumentException("IO异常");
        }
        return result;
    }

//    /**
//     * 导出word文档，响应到请求端
//     *
//     * @param tempName，要使用的模板
//     * @param docName，导出文档名称
//     * @param dataMap，模板中变量数据
//     * @param resp,HttpServletResponse
//     */
//    public static boolean exportDoc(String folderPath, String tempName, String docName, Map<?, ?> dataMap, HttpServletResponse resp) {
//        boolean status = false;
//        Configuration configuration = initConfiguration(folderPath);
//        ServletOutputStream sos = null;
//        InputStream fin = null;
//        if (resp != null) {
//            resp.reset();
//        }
//
//        Template t = null;
//        try {
//            // tempName.ftl为要装载的模板
//            t = configuration.getTemplate(tempName);
//            t.setEncoding("utf-8");
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        // 输出文档路径及名称 ,以临时文件的形式导出服务器，再进行下载
//        String name = folderPath + "temp" + (int) (Math.random() * 100000) + ".doc";
//        File outFile = new File(name);
//
//        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"))) {
//            status = true;
//            t.process(dataMap, out);
//        } catch (Exception e1) {
//            e1.printStackTrace();
//        }
//
//        try {
//            fin = new FileInputStream(outFile);
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//        // 文档下载
//        resp.setCharacterEncoding("utf-8");
//        resp.setContentType("application/msword");
//        try {
//            docName = new String(docName.getBytes("UTF-8"), "ISO-8859-1");
//        } catch (UnsupportedEncodingException e1) {
//            e1.printStackTrace();
//        }
//        resp.setHeader("Content-disposition", "attachment;filename=" + docName + ".doc");
//        try {
//            sos = resp.getOutputStream();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        byte[] buffer = new byte[512]; // 缓冲区
//        int bytesToRead = -1;
//        // 通过循环将读入的Word文件的内容输出到浏览器中
//        try {
//            while ((bytesToRead = fin.read(buffer)) != -1) {
//                sos.write(buffer, 0, bytesToRead);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            if (fin != null)
//                try {
//                    fin.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            if (sos != null)
//                try {
//                    sos.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            if (outFile != null)
//                outFile.delete(); // 删除临时文件
//        }
//
//        return status;
//    }


    public static void main(String[] args) throws IOException {
        Map<String, Object> dataMap = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>(16);
        for (int i = 0; i < 10; i++) {
            Map<String, Object> itemMap = new HashMap<>(16);
            itemMap.put("item", i + 1);
            itemMap.put("name", "name" + (i + 1));
            itemMap.put("age", "age" + (i + 1));
            itemMap.put("adress", "adress" + (i + 1));
            list.add(itemMap);
        }


        dataMap.put("itemList", list);

        dataMap.put("title", "我是标题");
        dataMap.put("text", "我是被替换后的对象");

        //图片转码
        dataMap.put("base64_image", imageToBase64Str("C:\\Users\\suzan\\Desktop\\newPic.jpg"));

        createWord(dataMap, "C:\\Users\\suzan\\Desktop\\", "test.ftl", "C:\\Users\\suzan\\Desktop\\test.docx");
        System.out.println("模板生成成功");
    }

}