package com.cusc.nirvana.user.rnr.fp.service.impl;

import com.alibaba.fastjson.JSON;
import com.cache.CacheFactory;
import com.cache.exception.CacheException;
import com.cusc.nirvana.common.result.Response;
import com.cusc.nirvana.user.rnr.fp.common.ResponseCode;
import com.cusc.nirvana.user.rnr.fp.common.config.SmsPropertyConfig;
import com.cusc.nirvana.user.rnr.fp.common.config.SmsTemplateConfig;
import com.cusc.nirvana.user.rnr.fp.constants.RedisConstant;
import com.cusc.nirvana.user.rnr.fp.dto.SmsRequestDTO;
import com.cusc.nirvana.user.rnr.fp.dto.SmsResponseDTO;
import com.cusc.nirvana.user.rnr.fp.service.ISmsService;
import com.cusc.nirvana.user.rnr.fp.service.ShortMessageCheckService;
import com.cusc.nirvana.user.util.CuscRandomUtils;
import com.cusc.nirvana.user.util.CuscStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
@Slf4j
@RefreshScope
public class ShortMessageCheckServiceImpl implements ShortMessageCheckService {

    @Value("${fp.sms.captcha.expire:1800}")
    private int captchaExpire;

    @Value("${fp.sms.captcha.interval:60}")
    private int captchaIntervalExpire;

    @Resource
    private CacheFactory cacheFactory;

    @Autowired
    private ISmsService smsService;

    @Autowired
    private SmsTemplateConfig templateConfig;

    @Autowired
    private SmsPropertyConfig smsPropertyConfig;


    @Override
    public Response<SmsResponseDTO> sendSmsCaptcha(SmsRequestDTO bean) {
        String smsCaptcha;
        //String intervalKey = getIntervalKey(bean);
        try {
            //判断当前验证码是否达到发送间隔 60s
            /*if (cacheFactory.getExpireStringService().containsKey(intervalKey)) {
                return Response.createError(ResponseCode.SMS_CAPTCHA_INTERVAL_FAIL.getMsg(),
                        ResponseCode.SMS_CAPTCHA_INTERVAL_FAIL.getCode());
            }*/

            //创建随机验证
            smsCaptcha = CuscRandomUtils.randomNumeric(6);

            //获取短信模板
            String template = templateConfig.getSmsTemplates().get(bean.getBizType());
            if (StringUtils.isBlank(template)) {
                return Response.createError(ResponseCode.SMS_TEMPLATE_NULL.getMsg(),
                        ResponseCode.SMS_TEMPLATE_NULL.getCode());
            }

//        smsConfig.setIntervalLimitKey(RedisConstant.SMS_CAPTCHA_SEND_INTERVAL_KEY);
            //发送短信
            Response<SmsResponseDTO> response = smsService.sendSms(bean.getPhone(), smsCaptcha, template);

            if (response.isSuccess() && response.getData() != null) {
                //放到redis
                //cacheFactory.getExpireStringService().setExpireValue(intervalKey, smsCaptcha, captchaIntervalExpire);
                String smsKey = getSmsKey(bean);
                cacheFactory.getExpireStringService().setExpireValue(smsKey, smsCaptcha, captchaExpire);
            }

            return response;
        } catch (CacheException e) {
            log.error("sendSmsCaptcha 存放reids失败：", e);
            return Response.createError(ResponseCode.SMS_CREATE_CAPTCHA_FAIL.getMsg(),
                    ResponseCode.SMS_CREATE_CAPTCHA_FAIL.getCode());
        }
    }

    //发送短信
    @Override
    public Response<SmsResponseDTO> sendUnbindSms(SmsRequestDTO bean, String rnrId, String iccids) {
        log.info("换卡/解绑短信发送入参：{}", JSON.toJSONString(bean));
        Response<SmsResponseDTO> response = sendSms(bean);
        log.info("换卡/解绑短信发送出参：{}", JSON.toJSONString(response));
        return response;
    }

    @Override
    public Response<SmsResponseDTO> sendSms(SmsRequestDTO bean) {
        //获取短信模板
        String template = templateConfig.getSmsTemplates().get(bean.getBizType());
        if (StringUtils.isBlank(template)) {
            return Response.createError(ResponseCode.SMS_TEMPLATE_NULL.getMsg(),
                    ResponseCode.SMS_TEMPLATE_NULL.getCode());
        }
        return smsService.sendSms(bean.getPhone(), bean.getParams(), template);
    }

    @Override
    public Response checkSmsCaptcha(SmsRequestDTO bean) {
        String smsCaptcha;
        try {
            String key = getSmsKey(bean);
            smsCaptcha = cacheFactory.getExpireStringService().getValue(key, String.class);

            if (CuscStringUtils.isEmpty(smsCaptcha) || !smsCaptcha.equals(bean.getCaptcha())) {
                checkSmsCaptchaErrorCount(bean);
                return Response.createError(ResponseCode.SMS_CAPTCHA_INVALID.getMsg(),
                        ResponseCode.SMS_CAPTCHA_INVALID.getCode() + "");
            }
            //验证成功之后清理验证码
            cacheFactory.getExpireStringService().delete(key);
            cacheFactory.getExpireStringService().delete( RedisConstant.SMS_CAPTCHA_ERROR_COUNT_KEY + bean.getPhone() + "_" + bean.getTenantNo() + "_" + bean.getBizType());
        } catch (CacheException e) {
            log.error("checkSmsCaptcha 获取reids失败 ：", e);
            return Response.createError(ResponseCode.SMS_GET_CAPTCHA_FAIL.getMsg(),
                    ResponseCode.SMS_GET_CAPTCHA_FAIL.getCode());
        }

        return Response.createSuccess(true);
    }

    //----------------------私有方法区---------

    /**
     * 短信间隔key
     *
     * @param bean
     * @return
     */
    private String getIntervalKey(SmsRequestDTO bean) {
        return RedisConstant.SMS_RNR_CAPTCHA_SEND_INTERVAL_KEY
                + bean.getPhone() + "_" + bean.getTenantNo() + "_" + bean.getBizType();
    }

    /**
     * 短信间隔key
     *
     * @param bean
     * @return
     */
    private String getSmsKey(SmsRequestDTO bean) {
        return RedisConstant.SMS_CAPTCHA_KEY
                + bean.getPhone() + "_" + bean.getTenantNo() + "_" + bean.getBizType();
    }

    /**
     * Description: 检查短信验证码验证错误次数
     * <br />
     * CreateDate 2022-07-08 19:41:51
     *
     * @author yuyi
     **/
    private void checkSmsCaptchaErrorCount(SmsRequestDTO bean) {
        Integer errorCount;
        try {
            String redisKey =
                    RedisConstant.SMS_CAPTCHA_ERROR_COUNT_KEY + bean.getPhone() + "_" + bean.getTenantNo() + "_" + bean.getBizType();
            errorCount = cacheFactory.getExpireStringService().getValue(redisKey, Integer.class);
            if (errorCount == null) {
                errorCount = 0;
            }
            errorCount++;
            if (errorCount.intValue() > smsPropertyConfig.errorCount.intValue()) {
                //超过错误次数之后清理验证码
                cacheFactory.getExpireStringService().delete(getSmsKey(bean));
                cacheFactory.getExpireStringService().delete(redisKey);
                return;
            }
            cacheFactory.getExpireStringService()
                    .setExpireValue(redisKey, errorCount, RedisConstant.SMS_CAPTCHA_ERROR_COUNT_EXPIRE);
        } catch (CacheException e) {
            log.error("checkSmsCaptchaErrorCount 检查短信验证码验证错误次数 访问redis异常：", e);
        }
    }
}
