package com.bonus.zlpt.system.service.impl;

import com.bonus.zlpt.common.core.exception.ServiceException;
import com.bonus.zlpt.common.core.utils.StringUtils;
import com.bonus.zlpt.common.redis.service.RedisService;
import com.bonus.zlpt.system.api.constants.RedisConstants;
import com.bonus.zlpt.system.config.SmsComponent;
import com.bonus.zlpt.system.service.ISmsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Description: 短信发送接口实现
 *
 * @Author 阮世耀
 * @Create 2023/12/6 15:05
 * @Version 1.0
 */
@Service
public class ISmsServiceImpl implements ISmsService {

    @Resource
    SmsComponent smsComponent;

    @Resource
    private RedisService redisCache;

    /**
     * @param phone     给手机号发送验证码
     * @param leastTime 短信有效时间
     * @return 消息
     * @throws ServiceException 异常信息
     */
    @Override
    public String sendCode(String phone, int leastTime,Integer type) {

        if (phone == null || phone.isEmpty()) {
            throw new ServiceException("手机号为空");
        }
        String mobileRegEx = "^1[3,4,5,6,7,8,9][0-9]{9}$";
        Pattern pattern = Pattern.compile(mobileRegEx);

        Matcher matcher = pattern.matcher(phone);

        if (!matcher.matches()) {
            throw new ServiceException("手机号格式错误");
        }
        //从redis获取有效时间 如果相差小于1分钟不可以重新发送
        long expire = redisCache.getExpire(RedisConstants.REDIS_PHONE_CODE_KEY + phone);

        if (redisCache.hasKey(RedisConstants.REDIS_PHONE_CODE_KEY+phone) && (expire != -1 && leastTime - expire < 60000)) {

                 throw new ServiceException("发送频率过高");
         }

        String code = getSixBitCode();  // 生成新的验证码
        //存储 phone -> code到Redis中
        redisCache.setCacheObject(RedisConstants.REDIS_PHONE_CODE_KEY + phone, code, Long.parseLong(leastTime+""), TimeUnit.MILLISECONDS);
        smsComponent.sendCode(phone, code,"",type);
        return "已发送验证码 " + phone;
    }

    /**
     * 随机生成6位验证码
     */
    private String getSixBitCode() {
        //随机数
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(rand.nextInt(10));
        }
        return sb.toString();
    }


    /**
     * 判断验证码是否存在Redis中
     *
     * @param phone 手机号码
     * @param code  验证码
     * @return 校验结果
     * @throws ServiceException 异常信息
     */
    @Override
    public boolean checkCode(String phone, String code) {

         String redisCode = redisCache.getCacheObject(RedisConstants.REDIS_PHONE_CODE_KEY + phone);
         if (StringUtils.isEmpty(redisCode)) {
             throw new ServiceException("验证码失效");
         }
         if (!StringUtils.equals(redisCode.split("_")[0], code)) {
             throw new ServiceException("验证码错误");
         } else {
             redisCache.deleteObject(RedisConstants.REDIS_PHONE_CODE_KEY + phone);
            return true;
        }
    }
}
