package nckd.jxccl.base.common.utils;

import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
 * 字符串格式化工具类
 * @author W.Y.C
 * @date 2025/6/11 14:41
 * @version 1.1
 */
public class StrFormatter {

	// 常量定义
	private static final char BACKSLASH = '\\';
	private static final String EMPTY_JSON = "{}";
	private static final String NULL_STRING = "null";
	public static final String LINE_SEPARATOR = "\r\n";

	/**
	 * 格式化字符串（使用默认占位符 {}）
	 *
	 * 示例：
	 *   format("姓名：{}，年龄：{}", "张三", 25)
	 *   -> "姓名：张三，年龄：25"
	 *
	 * @param strPattern 包含占位符 {} 的字符串模板
	 * @param argArray   参数列表（按顺序替换占位符）
	 * @return 格式化后的字符串
	 */
	public static String format(String strPattern, Object... argArray) {
		return formatWith(strPattern, EMPTY_JSON, argArray);
	}

	/**
	 * 带自定义占位符的格式化方法
	 *
	 * 示例：
	 *   formatWith("姓名：%，年龄：%", "%", "张三", 25)
	 *   -> "姓名：张三，年龄：25"
	 *
	 * @param strPattern  字符串模板
	 * @param placeHolder 自定义占位符（如"{}"、"%"等）
	 * @param argArray    参数列表
	 * @return 格式化后的字符串
	 */
	public static String formatWith(String strPattern, String placeHolder, Object... argArray) {
		// 空值检查
		if (StringUtils.isBlank(strPattern) || StringUtils.isBlank(placeHolder) || argArray == null) {
			return strPattern;
		}
		final int patternLen = strPattern.length();
		final int holderLen = placeHolder.length();
		final StringBuilder result = new StringBuilder(patternLen + 50);
		int currentPos = 0;  // 当前处理位置
		int holderIndex;     // 占位符位置

		for (int argIndex = 0; argIndex < argArray.length; argIndex++) {
			holderIndex = strPattern.indexOf(placeHolder, currentPos);

			// 找不到更多占位符
			if (holderIndex == -1) {
				if (currentPos == 0) {
					return strPattern;  // 无占位符直接返回
				}
				// 添加剩余内容后返回
				result.append(strPattern, currentPos, patternLen);
				return result.toString();
			}

			// 处理转义符逻辑
			if (holderIndex > 0 && strPattern.charAt(holderIndex - 1) == BACKSLASH) {
				// 双反斜杠转义（真实占位符）
				if (holderIndex > 1 && strPattern.charAt(holderIndex - 2) == BACKSLASH) {
					result.append(strPattern, currentPos, holderIndex - 1);
					safeAppend(result, argArray[argIndex]);
					currentPos = holderIndex + holderLen;
				}
				// 单反斜杠转义（字面量占位符）
				else {
					result.append(strPattern, currentPos, holderIndex - 1);
					result.append(placeHolder.charAt(0));  // 添加占位符首字符
					currentPos = holderIndex + 1;  // 跳过占位符首字符
					argIndex--;  // 当前参数未使用
				}
			}
			// 正常占位符
			else {
				result.append(strPattern, currentPos, holderIndex);
				safeAppend(result, argArray[argIndex]);
				currentPos = holderIndex + holderLen;
			}
		}

		// 添加最后占位符后的内容
		result.append(strPattern, currentPos, patternLen);
		return result.toString();
	}

	/**
	 * 键值对格式化（使用 {key} 占位符）
	 *
	 * 示例：
	 *   Map<String, Object> map = new HashMap<>();
	 *   map.put("name", "张三");
	 *   map.put("age", 25);
	 *   format("{name}今年{age}岁", map, false)
	 *   -> "张三今年25岁"
	 *
	 * @param template   包含 {key} 占位符的模板
	 * @param map        键值对参数
	 * @param ignoreNull 是否忽略null值（true:跳过 null值，false:将null转为"null"）
	 * @return 格式化后的字符串
	 */
	public static String format(CharSequence template, Map<?, ?> map, boolean ignoreNull) {
		if (template == null) {
            return null;
        }
		if (map == null || map.isEmpty()) {
            return template.toString();
        }

		String result = template.toString();
		for (Map.Entry<?, ?> entry : map.entrySet()) {
			String key = entry.getKey() == null ? NULL_STRING : entry.getKey().toString();
			String value = entry.getValue() == null ?
					(ignoreNull ? null : NULL_STRING) :
					entry.getValue().toString();

			if (value != null) {
				result = result.replace("{" + key + "}", value);
			}
		}
		return result;
	}

	// ============= 私有工具方法 =============

	/**
	 * 安全追加对象字符串（处理null值）
	 */
	private static void safeAppend(StringBuilder sb, Object obj) {
		if (obj == null) {
			sb.append(NULL_STRING);
		} else {
			sb.append(obj.toString());
		}
	}
}