package com.fs.company.util;

import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 基于Java对象的文本占位符替换工具类
 * 支持替换 ${属性名} 或 ${属性名:默认值} 格式的占位符
 */
@Component
public class ObjectPlaceholderResolver {

    // 正则匹配 ${xxx} 或 ${xxx:默认值} 格式的占位符
    private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("\\$\\{([^}:]+)(?::([^}]*))?\\}");

    /**
     * 替换文本中的占位符为指定对象的属性值
     * @param targetObject 提供属性值的目标对象（不能为null）
     * @param text 包含占位符的原始文本
     * @return 替换后的文本
     */
    public String resolvePlaceholders(Object targetObject, String text) {
        // 容错：对象为空或文本为空，直接返回原文本
        if (targetObject == null || text == null || text.isEmpty()) {
            return text;
        }

        Matcher matcher = PLACEHOLDER_PATTERN.matcher(text);
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            // 提取占位符中的属性名（如 ${name} → name）
            String propName = matcher.group(1);
            // 提取默认值（如 ${hobby:打篮球} → 打篮球）
            String defaultValue = matcher.group(2);

            // 核心：通过反射获取对象的属性值
            Object propValue = getPropertyValue(targetObject, propName);

            // 确定最终替换值：有属性值→用属性值 → 无则用默认值 → 都无则保留原占位符
            String replaceValue = null;
            if (propValue != null) {
                replaceValue = propValue.toString();
            } else if (defaultValue != null) {
                replaceValue = defaultValue;
            } else {
                replaceValue = matcher.group(0); // 保留原占位符
            }

            // 替换（处理特殊字符，避免替换失败）
            matcher.appendReplacement(result, Matcher.quoteReplacement(replaceValue));
        }
        matcher.appendTail(result);

        return result.toString();
    }

    /**
     * 反射获取对象的属性值（通过Getter方法）
     * 规则：属性名name → Getter方法getName()
     * @param obj 目标对象
     * @param propName 属性名
     * @return 属性值（不存在则返回null）
     */
    private Object getPropertyValue(Object obj, String propName) {
        try {
            // 拼接Getter方法名：首字母大写，比如 name → getName
            String methodName = "get" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
            // 获取Getter方法
            Method getterMethod = obj.getClass().getMethod(methodName);
            // 执行方法获取属性值（设置可访问，兼容私有方法）
            getterMethod.setAccessible(true);
            return getterMethod.invoke(obj);
        } catch (Exception e) {
            // 捕获所有反射异常（方法不存在、执行失败等），返回null
            return null;
        }
    }
}