package com.kym.miniapp.aspect;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSON;

import com.kym.common.annotation.ApiLog;
import com.kym.common.utils.HttpContextUtils;
import com.kym.common.utils.IDGenerator;
import com.kym.common.utils.IPUtils;
import com.kym.entity.AppLog;
import com.kym.service.AppLogService;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


/**
 * APP日志，切面处理类
 *
 * @author skyline
 */
@Aspect
@Component
public class AppLogAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppLogAspect.class);
    private final AppLogService appLogService;
    IDGenerator idGenerator;

    AppLogAspect(AppLogService appLogService) {
        this.idGenerator = new IDGenerator();
        this.appLogService = appLogService;
    }

    /**
     * 切点
     */
    @Pointcut("@annotation(com.kym.common.annotation.ApiLog)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        var startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        var executeTime = System.currentTimeMillis() - startTime;
        saveApiLog(joinPoint, executeTime);
        return result;
    }


    private void saveApiLog(ProceedingJoinPoint joinPoint, long executeTime) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        var appLog = new AppLog();
        appLog.setId(idGenerator.nextId());
        var apiLog = method.getAnnotation(ApiLog.class);
        if (apiLog != null) {
            //注解上的描述
            appLog.setOperation(apiLog.value());
        }

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        appLog.setMethod(className + "." + methodName + "()");
        //请求的参数
        Object[] args = joinPoint.getArgs();

        if (!apiLog.ignoreParams()) {
            String params = JSON.toJSON(args).toString();
            appLog.setRequestParam(params);
        }
        //获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        //设置IP地址
        appLog.setIp(IPUtils.getIpAddr(request));
        //用户名、公司id、后台用户id
        if (!apiLog.value().contains("推送") && !apiLog.value().contains("拉取") && !apiLog.value().contains("回调")) {
            appLog.setUserId(StpUtil.getSession().getLong("userId"));
            appLog.setCompanyId(StpUtil.getSession().getLong("companyId"));
            appLog.setUsername(StpUtil.getSession().getString("username"));
            appLog.setExecuteTime(executeTime);
        }

        //保存系统日志
        appLogService.save(appLog);
    }


}
