package com.clx.performance.aspect;

import cn.hutool.json.JSONUtil;
import com.clx.performance.annotation.ResetPassword;
import com.clx.performance.component.SendMessageMachineCheckComponent;
import com.clx.performance.constant.RedisConstants;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.param.app.CheckMobileParam;
import com.clx.performance.param.app.InformationParam;
import com.clx.performance.param.app.ResetPasswordParam;
import com.clx.performance.param.app.SendMobileCaptchaParam;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.result.Result;
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.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
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.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
@Aspect
public class ResetPasswordAnnotationAop {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private SendMessageMachineCheckComponent sendMessageMachineCheckComponent;

    @Pointcut("@annotation(com.clx.performance.annotation.ResetPassword)")
    private void annotationPointCut() {
    }

    @Around("annotationPointCut()")
    public Object annotationAround(ProceedingJoinPoint jp) throws Throwable {
        //获取方法
        Method method = ((MethodSignature) jp.getSignature()).getMethod();
        // 获取AspectAnnotation注解
        ResetPassword aspectAnnotation = method.getAnnotation(ResetPassword.class);
        String mobile = "";
        String token = "";
        String redisVal = "";
        switch (aspectAnnotation.name()) {
            case "checkMobile":
                CheckMobileParam checkMobileParam = JSONUtil.toBean(JSONUtil.parse(jp.getArgs()[0]).toString(), CheckMobileParam.class);
                mobile = checkMobileParam.getMobile();
                token = checkMobileParam.getToken();
                redisVal = redisTemplate.opsForValue().get(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile);
                if (!StringUtils.equals(token, redisVal)) {
                    throw new ServiceSystemException(PerformanceResultEnum.TOKEN_IS_FAIL);
                }
                break;
            case "sendMobileCaptcha":
                SendMobileCaptchaParam sendMobileCaptchaParam = JSONUtil.toBean(JSONUtil.parse(jp.getArgs()[0]).toString(), SendMobileCaptchaParam.class);
                ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                HttpServletRequest request = sra.getRequest();
                sendMessageMachineCheckComponent.sendMessageMachineSelectCheck(request, sendMobileCaptchaParam);
                mobile = sendMobileCaptchaParam.getMobile();
                String content = redisTemplate.opsForValue().get(RedisConstants.MESSAGE_MOBILE_CAPTCHA + mobile);
                if (StringUtils.isNoneBlank(content)) {
                    token = UUID.randomUUID().toString();
                    redisTemplate.opsForValue().set(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile, token);
                    redisTemplate.expire(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile, 60, TimeUnit.SECONDS);

                    return Result.ok(token);
                }

                break;
            case "checkBusinessLicenseNumber":
                InformationParam informationParam = JSONUtil.toBean(JSONUtil.parse(jp.getArgs()[0]).toString(), InformationParam.class);
                mobile = informationParam.getMobile();
                token = informationParam.getToken();
                redisVal = redisTemplate.opsForValue().get(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile);
                if (!StringUtils.equals(token, redisVal)) {
                    throw new ServiceSystemException(PerformanceResultEnum.TOKEN_IS_FAIL);
                }
                break;
            case "resetPassword":
                ResetPasswordParam resetPasswordParam = JSONUtil.toBean(JSONUtil.parse(jp.getArgs()[0]).toString(), ResetPasswordParam.class);
                mobile = resetPasswordParam.getMobile();
                token = resetPasswordParam.getToken();
                redisVal = redisTemplate.opsForValue().get(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile);
                if (!StringUtils.equals(token, redisVal)) {
                    throw new ServiceSystemException(PerformanceResultEnum.TOKEN_IS_FAIL);
                }
                break;
            default:
                throw new RuntimeException();
        }


        //执行方法前
        Object returnVal = null;

        returnVal = jp.proceed();
        if (!StringUtils.equals(aspectAnnotation.name(), "resetPassword")) {
            Result result = JSONUtil.toBean(JSONUtil.parse(returnVal).toString(), Result.class);

            redisTemplate.opsForValue().set(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile, result.getData().toString());
            redisTemplate.expire(RedisConstants.MESSAGE_RESET_PASSWORD_TOKEN + mobile, 60, TimeUnit.SECONDS);
        }

        return returnVal;

    }

}
