package com.njcn.gather.tools.report.util;

import com.njcn.gather.tools.report.model.enums.ReportResponseEnum;
import lombok.extern.slf4j.Slf4j;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;
import org.docx4j.TraversalUtil;
import org.docx4j.TraversalUtil.CallbackImpl;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Word文档分析工具类
 * 基于docx4j的Word文档分析工具，专门用于占位符提取和验证
 * 与PlaceholderUtil配合使用，提供完整的模板处理解决方案
 * <p>
 * 技术栈：纯docx4j解决方案，专注于${placeholder}格式处理
 *
 * @author hongawen
 * @version 2.0
 * @data 2025/9/5 11:00
 */
@Slf4j
public class WordDocumentUtil {

    /**
     * 支持的占位符格式正则表达式
     * ${placeholder}
     */
    private static final Pattern PLACEHOLDER_PATTERN_DOLLAR = Pattern.compile("\\$\\{([^}]+)}");

    /**
     * 从Word文档输入流中提取所有${placeholder}格式的占位符
     *
     * @param templateInputStream Word模板文档输入流
     * @param keepFormat          是否保持${...}完整格式，true返回${companyName}，false返回companyName
     * @return 包含所有占位符的Set集合（去重）
     * @throws com.njcn.common.pojo.exception.BusinessException 模板处理失败或参数验证失败
     */
    public static Set<String> extractPlaceholders(InputStream templateInputStream, boolean keepFormat, List<String> excludePlaceholders) {
        if (templateInputStream == null) {
            throw ReportExceptionUtil.create(ReportResponseEnum.VALIDATION_ERROR);
        }
        Set<String> placeholders = new HashSet<>();
        try {
            WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(templateInputStream);
            MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart();

            // 使用TraversalUtil遍历所有Text节点
            CallbackImpl textCallback = new CallbackImpl() {
                @Override
                public List<Object> apply(Object content) {
                    if (content instanceof Text) {
                        Text textNode = (Text) content;
                        String text = textNode.getValue();
                        if (StringUtils.hasText(text)) {
                            // 在每个文本节点中搜索占位符
                            Matcher matcher = PLACEHOLDER_PATTERN_DOLLAR.matcher(text);
                            while (matcher.find()) {
                                String result;
                                if (keepFormat) {
                                    result = matcher.group(0);
                                } else {
                                    result = matcher.group(1);
                                }
                                // 添加到结果集合中，排除指定占位符
                                if (StringUtils.hasText(result) && !excludePlaceholders.contains(matcher.group(1))) {
                                    placeholders.add(result.trim());
                                }
                            }
                        }
                    }
                    return null;
                }
            };
            // 遍历整个文档
            TraversalUtil.visit(mainDocumentPart, textCallback);
        } catch (Exception e) {
            log.error("提取占位符时发生异常", e);
            throw ReportExceptionUtil.create(ReportResponseEnum.TEMPLATE_PROCESS_ERROR);
        }

        return placeholders;
    }

    /**
     * 从Word文档输入流中提取所有${placeholder}格式的占位符（返回纯变量名）
     *
     * @param templateInputStream Word模板文档输入流
     * @return 包含所有占位符变量名的Set集合（去重）
     */
    public static Set<String> extractPlaceholders(InputStream templateInputStream, List<String> excludePlaceholders) {
        return extractPlaceholders(templateInputStream, false, excludePlaceholders);
    }

    /**
     * 从Word文档输入流中提取所有占位符（返回完整${...}格式）
     *
     * @param templateInputStream Word模板文档输入流
     * @return 包含所有完整${...}格式占位符的Set集合
     */
    public static Set<String> extractPlaceholdersWithFormat(InputStream templateInputStream, List<String> excludePlaceholders) {
        return extractPlaceholders(templateInputStream, true, excludePlaceholders);
    }


    /**
     * 验证Word文档中是否包含指定的占位符
     *
     * @param templateInputStream Word模板文档输入流
     * @param placeholder         要验证的占位符（纯变量名）
     * @return true 如果文档包含该占位符，false 否则
     */
    public static boolean containsPlaceholder(InputStream templateInputStream, String placeholder) {
        if (templateInputStream == null || !StringUtils.hasText(placeholder)) {
            throw ReportExceptionUtil.create(ReportResponseEnum.VALIDATION_ERROR);
        }
        try {
            WordprocessingMLPackage wordPackage = WordprocessingMLPackage.load(templateInputStream);
            MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart();

            // 使用TraversalUtil遍历所有Text节点查找占位符
            final boolean[] found = {false};
            final String targetPlaceholder = "${" + placeholder + "}";

            CallbackImpl textCallback = new CallbackImpl() {
                @Override
                public List<Object> apply(Object content) {
                    if (content instanceof Text && !found[0]) {
                        Text textNode = (Text) content;
                        String text = textNode.getValue();
                        if (StringUtils.hasText(text)) {
                            if (text.contains(targetPlaceholder) || text.contains(placeholder)) {
                                found[0] = true;
                            }
                        }
                    }
                    return null;
                }
            };

            // 遍历整个文档
            TraversalUtil.visit(mainDocumentPart, textCallback);

            return found[0];
        } catch (Exception e) {
            log.error("验证占位符时发生异常: {}", placeholder, e);
            throw ReportExceptionUtil.create(ReportResponseEnum.TEMPLATE_PROCESS_ERROR);
        }
    }


    /**
     * 测试方法
     */
    public static void main(String[] args) {
        String templatePath = "F:\\gitea\\fusionForce\\CN_Gather\\entrance\\src\\main\\resources\\model\\report_table.docx";

        try (java.io.FileInputStream templateStream = new java.io.FileInputStream(templatePath)) {
            Set<String> placeholders = extractPlaceholders(templateStream, Arrays.asList("CreateId", "total", "count"));

            System.out.println("模板文件: " + templatePath);
            System.out.println("发现 " + placeholders.size() + " 个占位符:");
            for (String placeholder : placeholders) {
                System.out.println("${" + placeholder + "}");
            }

        } catch (Exception e) {
            System.err.println("错误: " + e.getMessage());
        }
    }
}