package jnpf.aspect;

import jnpf.attendance.mapper.ApiCallLogMapper;
import jnpf.entity.ApiCallLog;
import jnpf.util.DateUtil;
import jnpf.util.FtbUtil;
import jnpf.util.JsonUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 接口调用记录切面
 *
 * @author yanwenfu
 * @create 2026-01-28
 */
@Aspect
@Component
@Slf4j
public class ApiCallLogAspect {

    @Resource
    private ApiCallLogMapper apiCallLogMapper;

    @Around("@annotation(apiCallLog)")
    public Object around(ProceedingJoinPoint joinPoint, FtbApiCallLog apiCallLog) throws Throwable {

        long startTime = System.currentTimeMillis();
        ApiCallLog logEntity = new ApiCallLog();
        HttpServletRequest request = null;
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            request = attributes.getRequest();
        }
        // ========= 基础信息 =========
        logEntity.setId(FtbUtil.getId());
        logEntity.setApiName(apiCallLog.name());
        logEntity.setDeleteMark(0);
        logEntity.setCreatorTime(DateUtil.getNowDate());
        logEntity.setCreatorUserId(UserProvider.getLoginUserId());
        logEntity.setTenantId(UserProvider.getUser().getTenantId());
        if (request != null) {
            logEntity.setApiPath(request.getRequestURI());
            logEntity.setHttpMethod(request.getMethod());
            logEntity.setIp(getIp(request));
        } else {
            logEntity.setApiPath("UNKNOWN");
            logEntity.setHttpMethod("UNKNOWN");
            logEntity.setIp("UNKNOWN");
        }
        // ========= 请求参数 =========
        try {
            logEntity.setRequestBody(JsonUtil.getObjectToString(joinPoint.getArgs()));
        } catch (Exception e) {
            logEntity.setRequestBody("请求参数序列化失败");
        }
        Object result;
        try {
            result = joinPoint.proceed();
            logEntity.setSuccess(1);
            try {
                logEntity.setResponseBody(JsonUtil.getObjectToString(result));
            } catch (Exception e) {
                logEntity.setResponseBody("返回结果序列化失败");
            }
            return result;
        } catch (Throwable ex) {
            logEntity.setSuccess(0);
            logEntity.setErrorMsg(ex.getMessage());
            throw ex;
        } finally {
            logEntity.setCostTime((int) (System.currentTimeMillis() - startTime));
            try {
                apiCallLogMapper.insert(logEntity);
            } catch (Exception e) {
                log.error("接口调用日志入库失败", e);
            }
        }
    }

    private String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isBlank(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
