package com.bio.bio_backend.global.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
public class MethodExecutionLoggingAspect {
    
    @Around("@annotation(logExecution)")
    public Object logExecution(ProceedingJoinPoint pjp, com.bio.bio_backend.global.annotation.LogExecution logExecution) throws Throwable {
        String message = logExecution.value().isEmpty() ? 
            pjp.getSignature().getName() : logExecution.value();
        
        String className = pjp.getTarget().getClass().getSimpleName();
        String methodName = pjp.getSignature().getName();
        
        String userInfo = getCurrentUser();
        
        long startTime = System.currentTimeMillis();
        log.info("[START] {} | 호출경로: {}.{} | 사용자: {}", 
                message, className, methodName, userInfo);
        
        try {
            Object result = pjp.proceed();
            long duration = System.currentTimeMillis() - startTime;
            log.info("[SUCCESS] {} | 호출경로: {}.{} | 사용자: {} | 시간: {}ms", 
                    message, className, methodName, userInfo, duration);
            return result;
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("[FAILED] {} | 호출경로: {}.{} | 사용자: {} | 시간: {}ms | 오류: {}", 
                    message, className, methodName, userInfo, duration, e.getMessage());
            throw e;
        }
    }
    
    private String getCurrentUser() {
        try {
            Authentication auth = SecurityContextHolder.getContext().getAuthentication();
            if (auth != null && auth.isAuthenticated() && !"anonymousUser".equals(auth.getName())) {
                return auth.getName();
            }
            return "인증되지 않은 사용자";
        } catch (Exception e) {
            return "알 수 없는 사용자";
        }
    }
}
