package com.jeequan.jeepay.bizcommons.manage.sms;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.cache.RedisUtil;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.smsconfig.AbstractSmsConfig;
import com.jeequan.jeepay.core.model.smsconfig.MocktestSmsConfig;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizDiyContentModel;
import com.jeequan.jeepay.core.model.smsconfig.SmsBizVercodeModel;
import com.jeequan.jeepay.core.sms.ISmsHandler;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.service.impl.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/***
* 短信相关
*
* @author terrfly
* @date 2023/8/18 10:05
*/
@Component
@Slf4j
public class SmsManager {

    @Autowired private SysConfigService sysConfigService;

    /** 获取短信验证码 **/
    public String genSmsCode(){
        return String.valueOf(RandomUtil.getSecureRandom().nextInt(899999) + 100000);
    }

    /**
     * 功能描述:  发送短信验证码 （默认5分钟）
     *
     * @param phoneNo
     * @param smsBizType 业务类型
     * @Return: void
     * @Author: terrfly
     * @Date: 2023/8/18 10:06
     */
    public void sendSmsVercode(String phoneNo, String smsBizType) {

       // 默认 5分钟
       this.sendSmsVercode(phoneNo, smsBizType, 5);

    }

    /**
     * 功能描述:  发送短信验证码
     *
     * @param phoneNo
     * @param smsBizType 业务类型
     * @param expiredMin 过期时间： 分钟
     * @Return: void
     * @Author: terrfly
     * @Date: 2023/8/18 10:06
     */
    public void sendSmsVercode(String phoneNo, String smsBizType, int expiredMin) {

        // 0. 验证手机号是否正确， 如果不正确将抛业务异常！
        if (!AbstractSmsConfig.checkMobileNumber(phoneNo)){
            throw new BizException("手机号格式有误");
        }

        // 1. 获取配置的哪个通道
        MutablePair<String, String> smsConfigInfo = sysConfigService.getSmsConfigInfo();

        String smsProviderType = smsConfigInfo.getLeft();

        // 2. 获取发送短信接口
        ISmsHandler iSmsHandler = SpringBeansUtil.getBean(smsProviderType + "SmsHandler", ISmsHandler.class);

        if(iSmsHandler == null){
            throw new BizException("短信渠道不存在");
        }

        // 3. 生成短信验证码
        AbstractSmsConfig smsConfig = AbstractSmsConfig.getSmsConfig(smsProviderType, smsConfigInfo.getRight());

        String verifyCode = this.genSmsCode();

        // mock通道
        if(CS.SMS_PROVIDER_TYPE_API_ENUM.SMS_PROVIDE_KEY_MOCKTEST.equals(smsProviderType)){
            verifyCode = ((MocktestSmsConfig)smsConfig).getMockCode();
        }

        // 4. 构建短信信息
        SmsBizVercodeModel smsVercodeModel = SmsBizVercodeModel.builder()
                .phoneNo(phoneNo).smsVercode(verifyCode).smsBizType(smsBizType).expiredMin(expiredMin)
                .build();

        log.info("即将发送手机号:{},短信验证码:{}", phoneNo, verifyCode);

        iSmsHandler.sendVercode(smsVercodeModel, smsConfig);

        // 5. 放置Redis 缓存 短信验证码缓存时间: xx 分钟
        RedisUtil.setString(CS.getCacheKeySmsCode(phoneNo), smsVercodeModel.toJSONString(), expiredMin * 60);

    }

    /** 自定义内容的发送 **/
    public void sendDiyContentSms(SmsBizDiyContentModel smsBizDiyContentModel) {

        try {

            // 0. 验证手机号是否正确， 如果不正确将抛业务异常！
            if (!AbstractSmsConfig.checkMobileNumber(smsBizDiyContentModel.getPhoneNo())){
                throw new BizException("手机号格式有误");
            }

            // 1. 获取配置的哪个通道
            MutablePair<String, String> smsConfigInfo = sysConfigService.getSmsConfigInfo();
            String smsProviderType = smsConfigInfo.getLeft();


            // 2. 调用发送短信接口
            ISmsHandler iSmsHandler = SpringBeansUtil.getBean(smsProviderType + "SmsHandler", ISmsHandler.class);

            if(iSmsHandler == null){
                throw new BizException("短信渠道不存在");
            }

            iSmsHandler.sendDiyContent(smsBizDiyContentModel, AbstractSmsConfig.getSmsConfig(smsConfigInfo.getLeft(), smsConfigInfo.getRight()));

        }catch (Exception e){
            log.error("短信发送失败", e);

        }
    }


    /** 判断验证码是否正确 **/
    public void checkSmsVercodeThrowBizEx(String phoneNo, String smsVercode, String smsBizType){

        String codeJsonStr = RedisUtil.getString(CS.getCacheKeySmsCode(phoneNo));
        if (StringUtils.isEmpty(codeJsonStr)) {
            throw new BizException("验证码已过期，请重新点击发送验证码！");
        }
        SmsBizVercodeModel smsVercodeModel = JSONObject.parseObject(codeJsonStr, SmsBizVercodeModel.class);

        if(smsVercodeModel == null){
            throw new BizException("验证码已过期，请重新点击发送验证码！");
        }

        if(StringUtils.isEmpty(smsVercodeModel.getSmsVercode()) || !smsVercodeModel.getSmsVercode().equalsIgnoreCase(smsVercode)){
            throw new BizException("验证码错误！");
        }

        if(StringUtils.isEmpty(smsVercodeModel.getSmsBizType()) || !smsVercodeModel.getSmsBizType().equalsIgnoreCase(smsBizType)){
            throw new BizException("验证码类型错误！");
        }

    }


    /**
     * 功能描述:  查询短信相关内容（比如余额等）
     *
     * @param bizQueryType 查询的业务类型
     * @Return: String
     * @Author: yr
     * @Date: 2023/8/18 10:06
     */
    public String querySmsInfo(String bizQueryType) {
        // 1. 获取配置的哪个通道
        MutablePair<String, String> smsConfigInfo = sysConfigService.getSmsConfigInfo();
        String smsProviderType = smsConfigInfo.getLeft();

        // 2. 调用短信查询接口
        ISmsHandler iSmsHandler = SpringBeansUtil.getBean(smsProviderType + "SmsHandler", ISmsHandler.class);

        if(iSmsHandler == null){
            throw new BizException("短信渠道不存在");
        }
        return iSmsHandler.querySmsInfo(AbstractSmsConfig.getSmsConfig(smsConfigInfo.getLeft(), smsConfigInfo.getRight()), bizQueryType);
    }

}
