package com.yifu.cloud.plus.v1.yifu.social.util;

import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.social.config.SocialFriendConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialFriendBackLog;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.xwpf.usermodel.*;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.core.office.OfficeManager;
import org.jodconverter.local.LocalConverter;
import org.jodconverter.local.office.LocalOfficeManager;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hgw
 * @description word工具类
 * @date 2025-5-26 16:03:05
 */
public class WordToImageUtil {

	private static final String  PDF_TEMP ="\\test126666.docx";
	private static final String  IMAGE_TEMP ="\\document_with_seal.png";
	private static final String  TO_IMAGE_TEMP ="\\ToImgTemp.png";
	public static String replaceTextInWord(InputStream templateFile, Map<String, String> replacements
			, InputStream imageStream, RestTemplate restTemplate, SocialFriendConfig socialFriendConfig
			, TSocialFriendBackLog backLog) {
		String projectRoot = System.getProperty(CommonConstants.USER_DIR);
		String outputFilePath = projectRoot + PDF_TEMP;
		String outputImagePath = projectRoot + IMAGE_TEMP;
		try (XWPFDocument document = new XWPFDocument(templateFile)) {
			// 替换段落中的文本
			for (XWPFParagraph paragraph : document.getParagraphs()) {
				for (String key : replacements.keySet()) {
					if (paragraph.getText().contains(key)) {
						String newText = paragraph.getText().replace(key, replacements.get(key));
						paragraph.getRuns().clear();
						XWPFRun newRun = paragraph.createRun();
						newRun.setText(newText);
					}
				}
			}
			String text;
			// 替换表格中的文本
			for (XWPFTable table : document.getTables()) {
				for (XWPFTableRow row : table.getRows()) {
					for (XWPFTableCell cell : row.getTableCells()) {
						for (XWPFParagraph p : cell.getParagraphs()) {
							for (XWPFRun run : p.getRuns()) {
								text = run.getText(0);
								if (Common.isNotNull(text) && replacements.get(text) != null) {
									run.setText(replacements.get(text), 0);
								}
							}
						}
					}
				}
			}
			// 保存输出文件
			try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
				document.write(fos);
			}
			return convertAndAddSeal(outputFilePath, imageStream, outputImagePath, projectRoot, restTemplate
					, socialFriendConfig, backLog);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			Path outputPath = Paths.get(outputFilePath);
			if (Files.exists(outputPath)) {
				try {
					Files.delete(outputPath); // 如果文件不存在会抛异常，先判断是否存在
				} catch (DirectoryNotEmptyException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (imageStream != null) {
				try {
					imageStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return "-";
	}

	// 在生产环境中，建议在整个应用生命周期中共享一个OfficeManager：
	public static OfficeManager OFFICE_MANAGER;
	static {
		OFFICE_MANAGER = LocalOfficeManager.builder()
				.portNumbers(2003)
				.build();
		try {
			OFFICE_MANAGER.start();
		} catch (OfficeException e) {
			e.printStackTrace();
		}
	}
	public static String convertAndAddSeal(String inputDocx, InputStream sealImagePath, String outputImagePath
			, String projectRoot, RestTemplate restTemplate, SocialFriendConfig socialFriendConfig
			, TSocialFriendBackLog backLog) throws IOException, OfficeException {

		File pdfFile = null;
		File imgFile = null;
		try {
			// Step 1: Word 转为 PDF（中间格式）
			pdfFile = new File(inputDocx.replace(".docx", ".pdf"));
			Map<String, Object> pdfProps = new HashMap<>();
			pdfProps.put("FilterName", "writer_pdf_Export");
			pdfProps.put("SelectPdfVersion", 1); // PDF/A-1
			LocalConverter.builder()
					.officeManager(OFFICE_MANAGER)
					.storeProperties(pdfProps)
					.build()
					.convert(new File(inputDocx))
					.to(pdfFile)
					.execute();

			// Step 2: PDF 转为 PNG 图片（可使用 Apache PDFBox 或 ImageMagick 转换）
			BufferedImage pageImage = convertPdfToImage(pdfFile.getAbsolutePath());

			// Step 3: 加盖公章
			BufferedImage sealedImage = addSealToImage(pageImage, sealImagePath);

			imgFile = new File(outputImagePath);
			// Step 4: 输出图片
			ImageIO.write(sealedImage, "png", imgFile);
			if (imgFile.exists()) {
				// file 压缩到1M以内
				imgFile = compressImage(projectRoot, imgFile);
				String key  = System.currentTimeMillis() + imgFile.getName();
				byte[] fileContent = Files.readAllBytes(imgFile.toPath());
				String base64String = Base64.getEncoder().encodeToString(fileContent);
				String url = socialFriendConfig.uploadPng(restTemplate, key, base64String, backLog);
				if (Common.isEmpty(url)){
					return "--";
				}
				return url;
			}
		} finally {
			if (pdfFile != null) {
				pdfFile.delete();
			}
			if (imgFile != null) {
				imgFile.delete();
			}
		}
		return "---";
	}

	private static File compressImage(String projectRoot, File originalFile) throws IOException {
		BufferedImage image = ImageIO.read(originalFile);
		int quality = 100; // 从100%开始
		File compressedFile = new File(projectRoot, TO_IMAGE_TEMP);
		int maxSize = 1024 * 1024;
		while (originalFile.length() > maxSize && quality > 10) {
			quality -= 5;
			ImageIO.write(image, "png", compressedFile);
			if (compressedFile.length() < maxSize) {
				originalFile.delete();
				compressedFile.renameTo(originalFile);
				break;
			}
			compressedFile.delete();
		}
		return originalFile;
	}

	private static BufferedImage convertPdfToImage(String pdfPath) throws IOException {
		try (PDDocument document = PDDocument.load(new File(pdfPath))) {
			PDFRenderer pdfRenderer = new PDFRenderer(document);
			// 渲染第一页为图像，分辨率为 300 DPI
			return pdfRenderer.renderImageWithDPI(0, 300, ImageType.RGB);
		}
	}

	private static BufferedImage addSealToImage(BufferedImage image, InputStream sealImagePath) throws IOException {
		BufferedImage seal = ImageIO.read(sealImagePath);

		BufferedImage combined = new BufferedImage(
				image.getWidth(),
				image.getHeight(),
				BufferedImage.TYPE_INT_ARGB);

		Graphics2D g = combined.createGraphics();
		g.drawImage(image, 0, 0, null);

		// 设置公章位置（右下角）
		int x = 1600;
		int y = 1150;

		g.drawImage(seal, x, y, null);
		g.dispose();

		return combined;
	}

}
