package click.kamil.springstatemachineexporter.analysis.service;

import click.kamil.springstatemachineexporter.analysis.model.EntryPoint;
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
import lombok.RequiredArgsConstructor;
import org.eclipse.jdt.core.dom.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequiredArgsConstructor
public class InterceptorDetector {
    private final CodebaseContext context;

    public List<EntryPoint> detect(CompilationUnit cu) {
        List<EntryPoint> entryPoints = new ArrayList<>();
        cu.accept(new ASTVisitor() {
            @Override
            public boolean visit(TypeDeclaration node) {
                if (isInterceptor(node)) {
                    processInterceptor(node, entryPoints);
                }
                return super.visit(node);
            }
        });
        return entryPoints;
    }

    private boolean isInterceptor(TypeDeclaration node) {
        if (node.getSuperclassType() != null) {
            // Check for common adapter/base classes if needed
        }
        for (Object interfaceType : node.superInterfaceTypes()) {
            String name = interfaceType.toString();
            if (name.contains("HandlerInterceptor") || name.contains("Filter") || name.contains("WebRequestInterceptor")) {
                return true;
            }
        }
        return false;
    }

    private void processInterceptor(TypeDeclaration node, List<EntryPoint> entryPoints) {
        String fqn = context.getFqn(node);
        for (MethodDeclaration method : node.getMethods()) {
            String methodName = method.getName().getIdentifier();
            if (isInterceptorMethod(methodName)) {
                Map<String, String> metadata = new HashMap<>();
                metadata.put("interceptorType", getInterceptorType(node));

                entryPoints.add(EntryPoint.builder()
                        .type(EntryPoint.Type.CUSTOM)
                        .name("INTERCEPTOR: " + node.getName().getIdentifier() + "." + methodName)
                        .className(fqn)
                        .methodName(methodName)
                        .metadata(metadata)
                        .build());
            }
        }
    }

    private boolean isInterceptorMethod(String name) {
        return name.equals("preHandle") || name.equals("postHandle") || name.equals("afterCompletion") || name.equals("doFilter");
    }

    private String getInterceptorType(TypeDeclaration node) {
        for (Object interfaceType : node.superInterfaceTypes()) {
            String name = interfaceType.toString();
            if (name.contains("HandlerInterceptor")) return "Spring MVC Interceptor";
            if (name.contains("Filter")) return "Servlet Filter";
        }
        return "Generic Interceptor";
    }
}
