package com.gree.mall.manager.config.aop;

import org.apache.commons.lang3.StringUtils;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.AdminUser;
import com.gree.mall.manager.plus.entity.OperationLog;
import com.gree.mall.manager.plus.service.AdminUserService;
import com.gree.mall.manager.plus.service.OperationLogService;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.utils.IpUtil;
import com.gree.mall.manager.utils.JwtUtils;
import com.gree.mall.manager.utils.RedisUtil;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 *  操作日志
 *  created by lijh
 *  2020-06-03
 */
@Aspect
@Component
@Slf4j
@Order(3)
public class OperationLogAspect {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    OperationLogService operationLogService;
    @Autowired
    AdminUserService adminUserService;
    @Autowired
    CommonLogic commonLogic;

    @Pointcut("@annotation(io.swagger.annotations.ApiOperation)")
    public void auth() {}

    @Before("auth()")
    public void doBefore(JoinPoint joinPoint){
        try{
            start(joinPoint);
        }catch(Exception e){
            log.error("操作日志记录失败,{}",e.getMessage());
        }

    }


    private void start(JoinPoint joinPoint){
        //不记录的模块
        List<String> modules = Arrays.asList("小程序API","公共API");

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String adminUserId = CommonUtils.getUserId(request);
        String nickName = CommonUtils.getNickName(request);
        Method sourceMethod = getSourceMethod(joinPoint);
        //只记录post请求的增删改操作
        PostMapping annotation = sourceMethod.getAnnotation(PostMapping.class);
        if (annotation != null) {
            ApiOperation ApiOperation = sourceMethod.getAnnotation(ApiOperation.class);
            //方法上的注解为具体操作
            String value = ApiOperation.value();
            //类上的api注解为模块
            String moduleName = joinPoint.getTarget().getClass().getAnnotation(Api.class).value();
            if(StringUtils.isBlank(moduleName) || modules.contains(moduleName)){
                return;
            }
            //登录接口获取不到token，写死
            if(value.equals("登录")){
                String userName = request.getParameter("userName");
                AdminUser adminUser = adminUserService.lambdaQuery().eq(AdminUser::getUserName, userName).one();
                nickName = adminUser.getNickName();
                adminUserId = adminUser.getAdminUserId();
            }
            //当前时间
            Date date = new Date();
            String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
            //获取登录用户的企业微信id
            AdminUserCom adminUser = commonLogic.getAdminUser(request);
            //记录
            OperationLog operationLog = new OperationLog();
            operationLog.setContent(nickName + "于" + dateStr + value);
            operationLog.setModuleName(moduleName);
            operationLog.setAdminUserId(adminUserId);
            operationLog.setUserName(nickName);
            operationLog.setNickName(nickName);
            operationLog.setIp(IpUtil.getIpAddr(request));
            operationLog.setCreateTime(new Date());
            operationLog.setCompanyWechatId(adminUser.getCompanyWechatId());
            operationLog.setCompanyName(adminUser.getCompanyName());
            operationLogService.save(operationLog);
        }
    }

    private Method getSourceMethod(JoinPoint jp) {
        Method proxyMethod = ((MethodSignature) jp.getSignature()).getMethod();
        try {
            return jp.getTarget().getClass().getMethod(proxyMethod.getName(), proxyMethod.getParameterTypes());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return null;
    }

}
