package com.zt.plat.module.base.service.doctemplate.render;

import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import java.io.StringWriter;
import java.util.Map;
import java.util.Properties;

/**
 * Velocity 渲染引擎实现
 */
@Component
@Slf4j
public class VelocityRenderEngineImpl implements IVelocityRenderEngine {

    private static volatile boolean velocityInitialized = false;

    @PostConstruct
    public synchronized void initVelocity() {
        if (velocityInitialized) {
            return;
        }

        try {
            Properties props = new Properties();
            props.setProperty("input.encoding", "UTF-8");
            props.setProperty("output.encoding", "UTF-8");
            props.setProperty("resource.loader", "string");
            props.setProperty("string.resource.loader.class", StringResourceLoader.class.getName());
            props.setProperty("runtime.log.logsystem.class",
                    "org.apache.velocity.runtime.log.NullLogChute");
            props.setProperty("eventhandler.referenceinsertion.class",
                    "org.apache.velocity.app.event.implement.EscapeHtmlReference");
            props.setProperty("eventhandler.escape.html.match", "true");

            Velocity.init(props);
            velocityInitialized = true;
            log.info("Velocity 模板引擎初始化成功");
        } catch (Exception e) {
            log.error("Velocity 模板引擎初始化失败", e);
            throw new RuntimeException("Velocity 模板引擎初始化失败", e);
        }
    }

    @Override
    public String render(String templateContent, Map<String, Object> data) {
        if (templateContent == null || templateContent.trim().isEmpty()) {
            log.warn("模板内容为空");
            return "";
        }

        if (!velocityInitialized) {
            initVelocity();
        }

        // 转换模板语法：{{variableName}} -> ${variableName}
        // 支持Mustache/Handlebars风格的模板兼容Velocity语法
        String velocityTemplate = convertToVelocitySyntax(templateContent);

        VelocityContext context = new VelocityContext();
        if (data != null && !data.isEmpty()) {
            data.forEach(context::put);
        }

        try {
            StringWriter writer = new StringWriter();
            Velocity.evaluate(context, writer, "TemplateRender", velocityTemplate);
            String result = writer.toString();

            log.debug("模板渲染成功，数据量: {}, 内容长度: {}",
                    data != null ? data.size() : 0, result.length());

            return result;
        } catch (Exception e) {
            log.error("模板渲染失败，模板长度: {}", templateContent.length(), e);
            throw new RuntimeException("模板渲染失败: " + e.getMessage(), e);
        }
    }

    /**
     * 将 Mustache/Handlebars 语法 {{variableName}} 转换为 Velocity 语法 ${variableName}
     *
     * @param template 原始模板内容
     * @return 转换后的 Velocity 语法模板
     */
    private String convertToVelocitySyntax(String template) {
        if (template == null) {
            return null;
        }
        // 使用正则表达式替换 {{variable}} 为 ${variable}
        // 匹配 {{ 和 }} 之间的内容（非贪婪模式）
        return template.replaceAll("\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\}\\}", "\\${$1}");
    }
}
