package com.supServer.project.service.impl;

import cn.com.flaginfo.sdk.cmc.api.ApiProvider;
import cn.com.flaginfo.sdk.cmc.api.request.ApiConfig;
import cn.com.flaginfo.sdk.cmc.api.result.ComResult;
import cn.com.flaginfo.sdk.cmc.api.sms.dynsend.DynSMSAPI;
import cn.com.flaginfo.sdk.cmc.api.sms.dynsend.DynSMSSendDataResult;
import cn.com.flaginfo.sdk.cmc.api.sms.dynsend.DynSMSSendRequest;
import cn.com.flaginfo.sdk.cmc.common.ApiEnum;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.exceptions.ClientException;
import com.supServer.common.exception.ServiceException;
import com.supServer.common.utils.SmsUtil;
import com.supServer.common.utils.StringUtils;
import com.supServer.framework.web.domain.AjaxResult;
import com.supServer.project.service.SmsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * @description：
 * @Author:
 * @Date:
 */
@Service
public class SmsServiceImpl implements SmsService {

    @Value("${sms.templates.login}")
    private String templateId;
    @Value("${sms.verificationCode.bitNum}")
    private Integer codeBit;
    @Value("${sms.verificationCode.effectiveSecond}")
    private Integer effectiveSecond;
    @Value("${sms.verificationCode.intervalSecond}")
    private Integer intervalSecond;
    @Value("${sms.redisNamespace}")
    private String redisNamespace;
    @Value("${sms.spcode}")
    private String spcode;
    @Value("${sms.appKey}")
    private String appKey;
    @Value("${sms.appSecret}")
    private String appSecret;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    private static ApiProvider provider;
    private String sendServer = "https://api.ums86.com";

    @Override
    public void sendSMS(String phone, String code) {
        ApiConfig apiConfig = new ApiConfig(spcode, appKey, appSecret);
        provider = ApiProvider.getInstance(apiConfig);
        //请求接口
//        SMSApi api = (SMSApi) provider.getApi(ApiEnum.SENDSMS);
        DynSMSAPI api = (DynSMSAPI) provider.getApi(ApiEnum.SENDDYNSMS);
        api.setRequestUrl(sendServer+"/api/sms-var/send");

        //请求参数
//        SMSSendRequest sendRequest = new SMSSendRequest();
//        sendRequest.setMessageContent(code);
//        //模板编号
//        sendRequest.setTemplateId(templateId);
//        sendRequest.setUserNumber(phone);
//        sendRequest.setSerialNumber("20210801120000123456"); 流水号
//        ComResult<SMSSendDataResult> request = api.request(sendRequest);

        DynSMSSendRequest sendRequest = new DynSMSSendRequest();
        sendRequest.setTemplateId(templateId);
        sendRequest.setDynData(new String[][]{{"手机号码", "验证码"}, {phone, code}});
//        sendRequest.setSerialNumber("20210804120000123457");
        ComResult<DynSMSSendDataResult> result = api.request(sendRequest);

        System.out.println(JSON.toJSONString(result));
    }

    @Override
    public AjaxResult sendCode(String phone, String codeType) {

        final String key = "system:smsCode:" + redisNamespace + ":" + templateId + ":" + phone;

        if (this.stringRedisTemplate.hasKey(key) && (effectiveSecond - this.stringRedisTemplate.getExpire(key)) < intervalSecond ) {
            throw new ServiceException("60秒内不能重复获取验证码");
        }
        String code = StringUtils.getRandomNumber(codeBit);
        //短信发送
//        sendSMS(phone, code);
        HashMap<String, String> map = new HashMap<>();
        map.put("code", code);
        try {
            boolean sendSms = SmsUtil.sendSms(phone, "SMS_181860796", map);
            this.stringRedisTemplate.opsForValue().set(key, code, effectiveSecond, TimeUnit.SECONDS);
            if(sendSms){
                return AjaxResult.success("短信发送成功");
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return AjaxResult.success("短信发送失败");
    }

    @Override
    public boolean validateCode(String phone, String code) {
        final String key = "system:smsCode:" + redisNamespace + ":" + templateId + ":" + phone;
        // 验证成功
        if (code.equalsIgnoreCase(this.stringRedisTemplate.opsForValue().get(key))) {
            this.stringRedisTemplate.delete(key);
            return true;
        }
        // 验证失败
        final String errKey = "system:smsCodeError:" + redisNamespace + ":" + templateId + ":" + phone;
        if (!this.stringRedisTemplate.hasKey(errKey)) {
            this.stringRedisTemplate.opsForValue().set(errKey, "1", effectiveSecond, TimeUnit.SECONDS);
        }else{
            // 验证错误超过10次自动删除这个验证码
            Integer errCount = Integer.valueOf(this.stringRedisTemplate.opsForValue().get(errKey));
            if (errCount > 10) {
                this.stringRedisTemplate.delete(key);
                this.stringRedisTemplate.delete(errKey);
                return false;
            }
            this.stringRedisTemplate.opsForValue().set(errKey, String.valueOf(errCount+1), effectiveSecond, TimeUnit.SECONDS);
        }
        return false;
    }

}
