package com.tofly.feesapi.common.dzht;

import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.tofly.common.core.util.StringUtil;
import com.tofly.feesapi.common.exception.FeesErrorCode;
import com.tofly.feesapi.common.exception.FeesException;
import com.tofly.feesapi.file.fileconfiguration.FileStorageService;
import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import com.aspose.words.Document;

import com.aspose.words.SaveFormat;


import javax.annotation.Resource;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.*;

@Slf4j
@Service
public class CommOfficeService {

    @Resource
    private ResourceLoader resourceLoader;
    @Autowired
    private FileStorageService fileStorageService;

    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = CommOfficeService.class.getClassLoader().getResourceAsStream("license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            is.close();
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 读取word文档
     *
     * @param wordurl word文档地址
     * @return
     */
    public XWPFDocument getHealthReport(String wordurl) {
        try {
            InputStream inputStream = fileStorageService.getByteDataforFileInputStream(wordurl);
            FileInputStream fileInputStream = SpringUtils.convertInputStreamToFileInputStream(inputStream);
            XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream);
            // 替换文本数据构建
            return xwpfDocument;
        } catch (Exception e) {
            log.error("getHealthReport error:{}", e.getMessage());
            throw new FeesException("读取word文档失败！", FeesErrorCode.BUSINESS_ERROR);
        }
    }

    /**
     * 构建替换字段Map(构造key，以${name}形式)
     *
     * @param obj 替换字段对象
     * @return 返回构建替换字段Map
     */
    public Map<String, String> objectToMap(Object obj) {
        Map<String, String> map = new HashMap<>();
        Class<?> clazz = obj.getClass();

        // 获取类中所有声明的字段（包括私有、受保护、默认、公共）
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true); // 设置字段可访问（如果是私有的）

            try {
                Object value = field.get(obj);
                String key = "${" + field.getName() + "}"; // 构造key，以${name}形式
                map.put(key, String.valueOf(value));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        return map;
    }

    /**
     * 替换word的关键字
     *
     * @param document      word文档对象
     * @param insertTextMap 替换字段Map
     */
    public void paragraphTextAndImagesFilling(XWPFDocument document, Map<String, String> insertTextMap) {
        Set<String> keys = insertTextMap.keySet();
        Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
        while (itPara.hasNext()) {
            // 获取文档中当前的段落文字信息
            XWPFParagraph paragraph = itPara.next();
            List<XWPFRun> runs = paragraph.getRuns();
            // 遍历段落文字对象
            for (XWPFRun run : runs) {
                if (run != null) {
                    String text = run.getText(0);  // 获取当前 run 的文本

                    if (text != null) {
                        // 遍历每个占位符，确保逐个替换文本和图片
                        for (String key : keys) {
                            Object replacement = insertTextMap.get(key);

                            // 替换文本（文本占位符的替换）
                            if (text.contains(key) && replacement instanceof String) {
                                String replacementStr = (String) replacement;

                                // 判断是否为网络图片 URL
                                if (replacementStr.startsWith("http://") || replacementStr.startsWith("https://")) {
                                    // 替换图片占位符
                                    run.setText("", 0);  // 清除占位符文本
                                    try (InputStream inputStream = new URL(replacementStr).openStream()) {
                                        run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, replacementStr, Units.toEMU(100), Units.toEMU(100)); // 设置图片大小
                                    } catch (IOException | InvalidFormatException e) {
                                        System.err.println("Error downloading image from URL: " + replacementStr);
                                    }
                                } else if (replacementStr.endsWith(".png") || replacementStr.endsWith(".jpg")) {
                                    // 替换本地图片占位符
                                    run.setText("", 0);  // 清除占位符文本
                                    try (InputStream inputStream = new FileInputStream(replacementStr)) {
                                        run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, replacementStr, Units.toEMU(100), Units.toEMU(100)); // 设置图片大小
                                    } catch (IOException e) {
                                        throw new RuntimeException(e);
                                    } catch (InvalidFormatException e) {
                                        throw new RuntimeException(e);
                                    }
                                } else {
                                    if (StringUtil.isEmpty(replacementStr)) {
                                        replacementStr = "/";
                                    }
                                    // 替换文本占位符
                                    text = text.replace(key, replacementStr);  // 替换文本中的占位符
                                    run.setText(text, 0);  // 更新 run 的文本
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * word转pdf
     *
     * @param document word文档对象
     * @return 返回pdf文件地址
     */
    public void WordToPdf(XWPFDocument document, String pdfFilePath) {
        OutputStream outputStream = null;
        try {
            PdfOptions pdfOptions = PdfOptions.create();
            // 输出路径
            outputStream = new FileOutputStream(pdfFilePath);
            // 调用转换
            PdfConverter.getInstance().convert(document, outputStream, pdfOptions);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * word转pdf
     *
     * @param sourceFile word文件路径
     * @param filePath   pdf文件目录
     * @return
     * @throws Exception
     */
    public static File docTurnPdf(File sourceFile, String filePath) throws Exception {
        if (!getLicense()) {// 验证License
            return null;
        }
        System.out.println("sourceFile====" + sourceFile.getPath());
        System.out.println("filePath====" + filePath);
        // 创建文档对象
        PDDocument document = new PDDocument();
        // 定义保存路径（使用File类）
        //File file = new File(filePath);
        File file = File.createTempFile(new Date().getTime() + ".pdf", ".pdf");
        System.out.println("filePath====" + new Date().getTime() + ".pdf");
        // 保存PDF文件
        document.save(file);
        System.out.println("新建file====" + file.getPath());
        // 关闭文档
        document.close();
        FileOutputStream os = new FileOutputStream(file);

//
//        File newDirectory = new File(filePath);
//        //目录不存在就创建
//        if (!newDirectory.exists()) {
//            newDirectory.mkdir();
//        }
//        newDirectory.createNewFile();
//        //File returnFile = File.createTempFile(fileName,".pdf");
//        System.out.println("新建file====" + filePath);
        OsInfo osInfo = SystemUtil.getOsInfo();
        if (osInfo.isLinux()) {
            System.out.println("isLinux====" + true);
            FontSettings.setFontsFolders(
                    new String[]{"/usr/share/fonts", "/usr/share/fonts/WindowsFonts"}
                    , true);
        }
//        FileOutputStream os = new FileOutputStream(newDirectory);
        Document doc = new Document(sourceFile.getAbsolutePath());//Address是将要被转化的word文档
        doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
        os.close();
        return file;
    }

    /**
     * 实体类转map
     *
     * @param obj
     * @return
     */
    public Map<String, Object> modelToMap(Object obj) {
        try {
            Map<String, Object> map = new HashMap<>();
            Class<?> clazz = obj.getClass();
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true); // 使得私有字段也可以访问
                if (StringUtil.isNotNull(field.get(obj))) {
                    map.put(field.getName(), field.get(obj));
                } else {
                    map.put(field.getName(), "");
                }
            }
            return map;
        } catch (Exception ex) {

        }
        return null;
    }
}
