package cn.sh.stc.sict.cloud.common.core.util;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.sh.stc.sict.cloud.common.core.constant.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
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.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @description: xxx短信验证发送工具类
 * @author: template from A-LI-Cloud
 * @create: 2019/5/9 15:16
 */
@Slf4j
@Component
@RefreshScope
public class SmsSendUtil {

    @Autowired
    private StringRedisTemplate redisService;

    @Value("${ali.signName:test}")
    private String signName;

    private String regionId = "";

    @Value("${ali.accesskeyId:ak}")
    private String accesskeyId;

    @Value("${ali.accessKeySecret:sk}")
    private String accessKeySecret;

    /**
     * 身份验证验证码
     */
    @Value("${ali.templateCode:SMS_165540176}")
    private String templateCode6;

    /**
     * 登录确认验证码
     */
    @Value("${ali.templateCode:SMS_165540175}")
    private String templateCode5;

    /**
     * 登录异常验证码
     */
    @Value("${ali.templateCode:SMS_165540174}")
    private String templateCode4;

    /**
     * 用户注册验证码
     */
    @Value("${ali.templateCode:SMS_165540173}")
    private String templateCode3;

    /**
     * 修改密码验证码
     */
    @Value("${ali.templateCode:SMS_165540172}")
    private String templateCode2;

    /**
     * 信息变更验证码
     */
    @Value("${ali.templateCode:SMS_165540171}")
    private String templateCode1;

    /**
     * cache前缀
     */
    private final static String VERIFICATION_PRE = "SMS:";
    /**
     * 过期时间/s
     */
    private final static Long EXPIRE_TIME_SECOND = 7200L;

    public String getActive() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        String[] activeProfiles = context.getEnvironment().getActiveProfiles();
        return activeProfiles.length > 0 ? activeProfiles[0] : "";
    }

    /**
     * 发送短信验证码
     *  type: 1-登录验证码 2-注册验证码
     * @param phoneNumber 手机号
     * @return
     */
    public String sendSMS(String phoneNumber, Integer type) {
        if (!Validator.isMobile(phoneNumber)) {
            return "手机号不合法";
        }
        String active = getActive();
        log.error("sms active = {}", active);
        if (StrUtil.equalsIgnoreCase(active, SecurityConstants.ACTIVE_DEV)) {
            return sendUatSMS(phoneNumber, type);
        }
        return this.sendProdSMS(phoneNumber, type);
    }

    private String sendUatSMS(String phoneNumber, Integer type) {
        String key = VERIFICATION_PRE + type + phoneNumber;
        String code = RandomStringUtils.random(6, false, true);
        redisService.opsForValue().set(key, code, EXPIRE_TIME_SECOND, TimeUnit.SECONDS);
        log.info("手机号码为:{}的用户收到验证码:{}", phoneNumber, code);
        return "dev环境发送成功：" + code;
    }

    private String sendProdSMS(String phoneNumber, Integer type) {
        String templateCode = templateCode6;
        if (type != null) {
            Map<Integer, String> templateCodeMap = new ConcurrentHashMap<>();
            templateCodeMap.put(1, templateCode1);
            templateCodeMap.put(2, templateCode2);
            templateCodeMap.put(3, templateCode3);
            templateCodeMap.put(4, templateCode4);
            templateCodeMap.put(5, templateCode5);
            templateCodeMap.put(6, templateCode6);
            if (StringUtils.isNotEmpty(templateCodeMap.get(type))) {
                templateCode = templateCodeMap.get(type);
            }
        }

        // 检查是否重复发送
        String key = VERIFICATION_PRE + type + phoneNumber;
//        if (StrUtil.isNotBlank(redisService.opsForValue().get(key))) {
//            return "发送成功";
//        }

        /**
         * 002.使用线程安全的集合，防止在并发条件下的污染问题
         */
        Map hashMap = new ConcurrentHashMap();
        hashMap.put("code", RandomStringUtils.random(6, false, true));
//        DefaultProfile profile = DefaultProfile.getProfile(regionId, accesskeyId, accessKeySecret);
//        IAcsClient client = new DefaultAcsClient(profile);
//        CommonRequest request = new CommonRequest();
//        request.setMethod(MethodType.POST);
//        request.setDomain("dysmsapi.aliyuncs.com");
//        request.setVersion("2017-05-25");
//        request.setAction("SendSms");
//        request.putQueryParameter("RegionId", regionId);
//        request.putQueryParameter("SignName", signName);
//        request.putQueryParameter("TemplateCode", templateCode);
//        request.putQueryParameter("PhoneNumbers", phoneNumber);
//        request.putQueryParameter("TemplateParam", JSONUtil.toJsonStr(hashMap));
//        try {
//            CommonResponse commonResponse = client.getCommonResponse(request);
//            JSONObject jsonObject = JSONUtil.parseObj(commonResponse.getData());
//            if (commonResponse.getHttpStatus() == 200 && jsonObject.get("Message").equals("OK")) {
//                redisService.opsForValue().set(key, hashMap.get("code").toString(), EXPIRE_TIME_SECOND, TimeUnit.SECONDS);
//                log.info("手机号码为:{}的用户收到验证码:{}", phoneNumber, hashMap.get("code"));
//                hashMap.clear();
//                return "发送成功";
//            }
//            if (jsonObject.get("Message").toString().equals("触发分钟级流控Permits:1")
//                    || jsonObject.get("Message").toString().equals("触发小时级流控Permits:5")) {
//                return "发送短信过于频繁,请您稍后再试";
//            }
//        } catch (Exception e) {
//            log.error(e.getMessage(), e);
//        }
        return "发送短信过于频繁,请您稍后再试";
    }

    /**
     * 校验验证码
     *
     * @param phone
     * @param code
     */
    public Boolean checkCode(String phone, Integer type, String code) {
        String key = VERIFICATION_PRE + type + phone;
//        String redisCode = redisService.opsForValue().get(key);
//        if (StringUtils.isNotEmpty(redisCode) && redisCode.equals(code)) {
//            redisService.delete(key);
//            return true;
//        }
        return false;
    }
}