package com.aicheck.parser;

import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.Type;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * Java 类型名工具：转字符串、取简单名、剥离 ActionResult/List 等泛型包装。
 */
public final class TypeNameUtils {
    /** 需要向内层继续剥离的包装类型 */
    private static final Set<String> WRAPPER_TYPES = Set.of(
            "ActionResult", "List", "PageListVO", "Set", "Collection", "Iterable", "Optional"
    );

    private TypeNameUtils() {
    }

    /** Type 转无空白字符串 */
    public static String typeToString(Type type) {
        if (type == null) {
            return "Object";
        }
        return type.toString().replaceAll("\\s+", "");
    }

    /** 取类型简单名，去掉包名与泛型 */
    public static String simpleName(String typeName) {
        if (typeName == null || typeName.isBlank()) {
            return "";
        }
        String cleaned = typeName.replaceAll("\\s+", "");
        int genericStart = cleaned.indexOf('<');
        String base = genericStart >= 0 ? cleaned.substring(0, genericStart) : cleaned;
        int dot = base.lastIndexOf('.');
        return dot >= 0 ? base.substring(dot + 1) : base;
    }

    /** 从 Type AST 收集实际业务类型简单名（穿透包装泛型） */
    public static Set<String> peelDirectTypeNames(Type type) {
        Set<String> result = new LinkedHashSet<>();
        collectPeelTargets(type, result);
        return result;
    }

    /** 从类型字符串收集实际业务类型简单名 */
    public static Set<String> peelDirectTypeNames(String typeName) {
        Set<String> result = new LinkedHashSet<>();
        collectPeelTargets(typeName, result);
        return result;
    }

    /** 递归收集：包装类型则进入泛型参数，否则记录简单名 */
    private static void collectPeelTargets(Type type, Set<String> result) {
        if (type == null) {
            return;
        }
        if (type.isClassOrInterfaceType()) {
            ClassOrInterfaceType classType = type.asClassOrInterfaceType();
            String name = simpleName(classType.getNameAsString());
            if (WRAPPER_TYPES.contains(name) && classType.getTypeArguments().isPresent()) {
                for (Type arg : classType.getTypeArguments().get()) {
                    collectPeelTargets(arg, result);
                }
                return;
            }
            result.add(name);
            return;
        }
        result.add(simpleName(typeToString(type)));
    }

    /** 字符串版递归收集 */
    private static void collectPeelTargets(String typeName, Set<String> result) {
        String cleaned = typeName.replaceAll("\\s+", "");
        int genericStart = cleaned.indexOf('<');
        if (genericStart < 0) {
            result.add(simpleName(cleaned));
            return;
        }
        String outer = simpleName(cleaned.substring(0, genericStart));
        String inner = cleaned.substring(genericStart + 1, cleaned.lastIndexOf('>'));
        if (WRAPPER_TYPES.contains(outer)) {
            for (String part : splitGenericArgs(inner)) {
                collectPeelTargets(part, result);
            }
            return;
        }
        result.add(outer);
    }

    /** 按逗号分割泛型参数，支持嵌套 <> */
    private static List<String> splitGenericArgs(String inner) {
        List<String> parts = new java.util.ArrayList<>();
        int depth = 0;
        StringBuilder current = new StringBuilder();
        for (char ch : inner.toCharArray()) {
            if (ch == '<') {
                depth++;
            } else if (ch == '>') {
                depth--;
            } else if (ch == ',' && depth == 0) {
                parts.add(current.toString().trim());
                current.setLength(0);
                continue;
            }
            current.append(ch);
        }
        if (current.length() > 0) {
            parts.add(current.toString().trim());
        }
        return parts;
    }
}
