package com.m2pool.lease.aspect;

import com.m2pool.common.security.utils.SecurityUtils;
import com.m2pool.lease.annotation.EncryptedField;
import com.m2pool.lease.annotation.LedgerLog;
import com.m2pool.lease.annotation.LedgerLogParam;
import com.m2pool.lease.annotation.LedgerLogTag;
import com.m2pool.lease.dto.Result;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

@Aspect
@Component
public class OperationLogAspect {
    @Autowired
    private LedgerLogService ledgerLogService;

    @Pointcut("@annotation(com.m2pool.lease.annotation.LedgerLog)")
    public void operationPointcut() {}

    @AfterReturning(pointcut = "operationPointcut()", returning = "result")
    public void afterOperation(JoinPoint joinPoint, Object result) {
        // 获取当前登录用户
        String address = "";

        // 获取操作类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LedgerLog annotation = method.getAnnotation(LedgerLog.class);
        //获取操作信息
        StringBuilder ledgerLog = new StringBuilder();
        for (Object arg : joinPoint.getArgs()) {
            if (arg != null) {
                Field[] fields = arg.getClass().getDeclaredFields();
                for (Field field : fields) {
                    try {
                        if (field.isAnnotationPresent(LedgerLogParam.class)) {
                                field.setAccessible(true);
                                Object value = field.get(arg);
                                ledgerLog.append(field.getAnnotation(LedgerLogParam.class).value())
                                        .append("=")
                                        .append(value)
                                        .append("; ");

                        }else if (field.isAnnotationPresent(LedgerLogTag.class)){
                            field.setAccessible(true);
                            address = (String) field.get(arg);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        if (result != null){
            // 添加手续费值的特殊处理(手续不准在请求参数中传递,只能通过返回获取)
            if (result instanceof Result) {
                ledgerLog.append(((Result<?>) result).getData()).append("; ");
            }
            ledgerLog.append("\n结果:").append(result);
        }
        // 记录日志
        ledgerLogService.logOperation(address, annotation.value(), ledgerLog.toString());
    }

    @AfterThrowing(pointcut = "operationPointcut()", throwing = "ex")
    public void afterOperationError(JoinPoint joinPoint, Exception ex) {
        // 获取当前登录用户
        String username = SecurityUtils.getUsername();
        String operation = joinPoint.getSignature().getName();
        ledgerLogService.logOperation(username, operation, "操作失败: " + ex.getMessage());
    }
}
