package com.malk.mc.aspect;

import com.alibaba.fastjson.JSONObject;
import com.malk.mc.entity.McRequestRecord;
import com.malk.mc.mapper.McRequestRecordMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class RequestLoggingAspect {

    @Autowired
    private McRequestRecordMapper mcRequestRecordMapper;

    private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

    @Around("execution(* com.malk.mc.controller..*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        if(request.getRequestURI().contains("/api/mc/project/")||request.getRequestURI().contains("/api/mc/bot/")){
            return joinPoint.proceed();
        }


        long startTime = System.currentTimeMillis();

        // 捕获请求参数
//        Map<String, String[]> parameterMap = request.getParameterMap();
        // 获取请求参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Map<String, Object> parameterMap = getParameters(joinPoint, method);
        String parameters=JSONObject.toJSONString(parameterMap);
//        String parameters = parameterMap.entrySet().stream()
//                .map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
//                .reduce((a, b) -> a + ", " + b).orElse("");

        Object result = joinPoint.proceed();

        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        // 创建请求记录对象
        McRequestRecord requestRecord = new McRequestRecord();
        requestRecord.setRequestUri(request.getRequestURI());
        requestRecord.setRequestMethod(request.getMethod());
        requestRecord.setRequestBody(parameters);
        requestRecord.setResponseBody(JSONObject.toJSONString(result));
        requestRecord.setTimestamp(LocalDateTime.now());
        requestRecord.setDuration(duration);
        requestRecord.setPid(request.getHeader("pid"));

        // 保存请求记录
        mcRequestRecordMapper.insert(requestRecord);

        return result;
    }

    private Map<String, Object> getParameters(JoinPoint joinPoint, Method method) {
        Object[] args = joinPoint.getArgs();
        Map<String, Object> params = new HashMap<>();

        // 获取方法参数名称
        String[] paramNames = parameterNameDiscoverer.getParameterNames(method);

        for (int i = 0; i < paramNames.length; i++) {
            if (method.isAnnotationPresent(RequestBody.class)) {
                // 如果方法上有 @RequestBody 注解，则获取请求体参数
                if (i == 0) { // 假设只有一个 @RequestBody 参数
                    params.put(paramNames[i], args[i]);
                }
            } else {
                // 如果方法上没有 @RequestBody 注解，则获取普通参数
                params.put(paramNames[i], args[i]);
            }
        }
        return params;
    }
}