package com.aicheck.parser;

import com.aicheck.model.FieldInfo;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 解析模型类字段：名称、类型、业务说明（注解或 Javadoc）。
 */
public class ClassFieldParser {

    /** 解析指定类的实例字段列表 */
    public List<FieldInfo> parseFields(String source, String expectedClassName) {
        if (source == null || source.isBlank()) {
            return List.of();
        }
        CompilationUnit cu = StaticJavaParser.parse(source);
        ClassOrInterfaceDeclaration classDecl = findClass(cu, expectedClassName);
        if (classDecl == null) {
            return List.of();
        }
        return parseClassFields(classDecl);
    }

    /** 按类名查找类声明，找不到则取第一个类 */
    private ClassOrInterfaceDeclaration findClass(CompilationUnit cu, String expectedClassName) {
        if (expectedClassName != null && !expectedClassName.isBlank()) {
            for (TypeDeclaration<?> type : cu.getTypes()) {
                if (type instanceof ClassOrInterfaceDeclaration) {
                    ClassOrInterfaceDeclaration classDecl = (ClassOrInterfaceDeclaration) type;
                    if (classDecl.getNameAsString().equals(expectedClassName)) {
                        return classDecl;
                    }
                }
            }
        }
        for (TypeDeclaration<?> type : cu.getTypes()) {
            if (type instanceof ClassOrInterfaceDeclaration) {
                return (ClassOrInterfaceDeclaration) type;
            }
        }
        return null;
    }

    /** 提取非 static final 字段，跳过常量 */
    private List<FieldInfo> parseClassFields(ClassOrInterfaceDeclaration classDecl) {
        Map<String, FieldInfo> fields = new LinkedHashMap<>();
        for (FieldDeclaration fieldDecl : classDecl.getFields()) {
            if (fieldDecl.isStatic() && fieldDecl.isFinal()) {
                continue;
            }
            String type = TypeNameUtils.typeToString(fieldDecl.getElementType());
            String description = extractFieldLabel(fieldDecl);
            for (VariableDeclarator variable : fieldDecl.getVariables()) {
                fields.put(variable.getNameAsString(), new FieldInfo(variable.getNameAsString(), type, description));
            }
        }
        return new ArrayList<>(fields.values());
    }

    /**
     * 字段说明：@Schema(description) &gt; @ApiModelProperty &gt; Javadoc，均无则空串。
     */
    String extractFieldLabel(FieldDeclaration fieldDecl) {
        for (AnnotationExpr annotation : fieldDecl.getAnnotations()) {
            String annName = annotation.getNameAsString();
            if ("Schema".equals(annName)) {
                String description = readAnnotationStringValue(annotation, "description");
                if (!description.isEmpty()) {
                    return description;
                }
            }
            if ("ApiModelProperty".equals(annName)) {
                String value = readAnnotationStringValue(annotation, "value");
                if (!value.isEmpty()) {
                    return value;
                }
            }
        }
        return extractJavadoc(fieldDecl);
    }

    /** 读取注解中的字符串属性值 */
    private String readAnnotationStringValue(AnnotationExpr annotation, String attributeName) {
        if (annotation.isNormalAnnotationExpr()) {
            NormalAnnotationExpr normal = annotation.asNormalAnnotationExpr();
            for (var pair : normal.getPairs()) {
                if (pair.getNameAsString().equals(attributeName)) {
                    return literalString(pair.getValue());
                }
            }
            return "";
        }
        if (annotation.isSingleMemberAnnotationExpr()) {
            SingleMemberAnnotationExpr single = annotation.asSingleMemberAnnotationExpr();
            if ("value".equals(attributeName) || "description".equals(attributeName)) {
                return literalString(single.getMemberValue());
            }
        }
        return "";
    }

    /** 提取字符串字面量值 */
    private String literalString(Expression expression) {
        if (expression.isStringLiteralExpr()) {
            return expression.asStringLiteralExpr().getValue().trim();
        }
        return "";
    }

    /** 从字段 Javadoc 提取首段描述 */
    private String extractJavadoc(FieldDeclaration fieldDecl) {
        Optional<JavadocComment> javadoc = fieldDecl.getJavadocComment();
        if (javadoc.isEmpty()) {
            return "";
        }
        String text = javadoc.get().parse().getDescription().toText();
        return text == null ? "" : text.trim().replaceAll("\\s+", " ");
    }
}
