package com.yeejoin.amos.patrol.business.util;

import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

/**
 * @author keyong
 * @title: WordTemplateUtils
 * <pre>
 * @description: TODO
 * </pre>
 * @date 2023/4/21 16:35
 */
public class WordTemplateUtils {

        private static String fileUploadDir;

        private Configuration configuration;

        private static WordTemplateUtils wordTemplateUtils;

        private WordTemplateUtils() {
            configuration = new Configuration();
            configuration.setDefaultEncoding("utf-8");
        }

        public static synchronized WordTemplateUtils getInstance() {
            if (wordTemplateUtils == null) {
                //添加你的内容
                Properties props;
                try {
                    props = PropertiesLoaderUtils.loadAllProperties("application-dev.properties");
                    fileUploadDir = (String) props.get("file.uploadUrl");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                wordTemplateUtils = new WordTemplateUtils();
            }
            return wordTemplateUtils;
        }


        public void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map,
                                              String title, String ftlFile) throws IOException {
            configuration.setClassForTemplateLoading(this.getClass(), "/ftl");
            Template freemarkerTemplate = configuration.getTemplate(ftlFile, "UTF-8");
            File file = null;
            InputStream fin = null;
            ServletOutputStream out = null;
            try {
                // 调用工具类的createDoc方法生成Word文档
                file = createDoc(map, freemarkerTemplate);
                fin = new FileInputStream(file);

                response.setCharacterEncoding("utf-8");
                response.setContentType("application/msword");
                // 设置浏览器以下载的方式处理该文件名
                String fileName = (StringUtils.isNotEmpty(title) ? title : getUUID()) + ".doc";
                response.setHeader("Content-Disposition",
                        "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));

                out = response.getOutputStream();
                // 缓冲区
                byte[] buffer = new byte[512];
                int bytesToRead = -1;
                // 通过循环将读入的Word文件的内容输出到浏览器中
                while ((bytesToRead = fin.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesToRead);
                }
            } finally {
                if (fin != null) {
                    fin.close();
                }
                if (out != null) {
                    out.close();
                }
                if (file != null) {
                    file.delete();
                }// 删除临时文件
            }

        }

        /**
         * 生成文件名
         *
         * @param * @param
         * @return
         */
        public static String getUUID() {
            return UUID.randomUUID().toString().replace("-", "");
        }

        public File getWordFileItem(Map map, String title, String ftlFile,String type) throws IOException {
            configuration.setClassForTemplateLoading(this.getClass(), "/ftl");
            Template freemarkerTemplate = configuration.getTemplate(ftlFile, "UTF-8");
            File file = null;
            File filepdf = new File("sellPlan.pdf");
            InputStream fin = null;
            OutputStream os = null;
            try {
                // 调用工具类的createDoc方法生成Word文档
                file = createDoc(map, freemarkerTemplate);
                fin = new FileInputStream(file);
                os = new FileOutputStream(filepdf);
                wordTopdfByAspose(fin, os,type);
                return filepdf;
            } finally {
                if (fin != null) {
                    fin.close();
                }
                if (os != null) {
                    os.close();
                }
                if (file != null) {
                    file.delete();
                }// 删除临时文件
            }
        }


        private static File createDoc(Map<?, ?> dataMap, Template template) {
            String name = "sellPlan.doc";
            File f = new File(name);
            Template t = template;
            try {
                // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
                Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
                t.process(dataMap, w);
                w.close();
            } catch (Exception ex) {
                ex.printStackTrace();
                throw new RuntimeException(ex);
            }
            return f;
        }

        public boolean wordTopdfByAspose(InputStream inputStream, OutputStream outputStream,String type) {
            // 验证License 若不验证则转化出的pdf文档会有水印产生
            if (!getLicense()) {
                return false;
            }
            try {
                // 将源文件保存在com.aspose.words.Document中，具体的转换格式依靠里面的save方法
                com.aspose.words.Document doc = new com.aspose.words.Document(inputStream);
                // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,EPUB, XPS, SWF 相互转换
                if("pdf".equals(type)){
                    doc.save(outputStream, SaveFormat.PDF);
                }else {
                    doc.save(outputStream, SaveFormat.DOCX);
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.flush();
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return true;

        }

        // 官方文档的要求 无需理会
        public static boolean getLicense() {
            boolean result = false;
            try {
                String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";
                ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());
                License aposeLic = new License();
                aposeLic.setLicense(is);
                result = true;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }


        /**
         * 获得图片的base64码
         *
         * @param src 图片路径
         * @return String
         */
        @SuppressWarnings("deprecation")
        public String getImageBase(String src) {
            if (StringUtils.isEmpty(src)) {
                return "";
            }
            src = src.replaceAll("\\.\\.", "");
            String fileName = fileUploadDir + src;
            File file = new File(fileName);
            if (!file.exists()) {
                return "";
            }
            InputStream in = null;
            byte[] data = null;
            try {
                in = new FileInputStream(file);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            }
            try {
                data = new byte[in.available()];
                in.read(data);
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(data);
        }

}
