package com.zanxiang.game.module.sdk.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.zanxiang.game.module.base.pojo.enums.HttpStatusEnum;
import com.zanxiang.game.module.sdk.constant.RedisKeyConstant;
import com.zanxiang.game.module.sdk.enums.ExpireTimeEnum;
import com.zanxiang.game.module.sdk.enums.SmsTypeEnum;
import com.zanxiang.game.module.sdk.pojo.dto.UserDTO;
import com.zanxiang.game.module.sdk.pojo.param.SmsCheckParam;
import com.zanxiang.game.module.sdk.pojo.param.SmsSendParam;
import com.zanxiang.game.module.sdk.pojo.param.UserData;
import com.zanxiang.game.module.sdk.service.ISmsService;
import com.zanxiang.game.module.sdk.service.IUserService;
import com.zanxiang.game.module.sdk.util.RedisUtil;
import com.zanxiang.game.module.sdk.util.RegexUtil;
import com.zanxiang.module.sms.pojo.SendResult;
import com.zanxiang.module.sms.service.impl.AliSmsService;
import com.zanxiang.module.util.pojo.ResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author : lingfeng
 * @time : 2022-06-09
 * @description : 手机短信逻辑
 */
@Slf4j
@Service
public class SmsServiceImpl implements ISmsService {

    @Autowired
    private IUserService userService;

    @Autowired
    private RedisUtil<String> redisUtil;

    @Autowired
    private AliSmsService aliSmsService;

    @Override
    public ResultVO<Boolean> smsSend(SmsSendParam smsSendParam, UserData userData) {
        //类型
        Integer type = smsSendParam.getType();
        //手机号码
        String mobile = smsSendParam.getMobile();
        //根据手机号获取用户信息
        UserDTO userDTO = userService.getUserInfoByMobile(mobile, userData.getGameId());
        //找回密码获取
        if (Objects.equals(type, SmsTypeEnum.SMS_FIND_PWD.getType())) {
            //手机号对应用户信息不存在
            if (userDTO == null) {
                return ResultVO.fail(HttpStatusEnum.USERNAME_NOT_EXISTS.getMsg());
            }
        }
        //验证手机号
        if (!RegexUtil.checkPhone(mobile)) {
            return ResultVO.fail(HttpStatusEnum.PHONE_ERROR.getMsg());
        }
        //验证类型
        SmsTypeEnum smsTypeEnum = SmsTypeEnum.getByType(type);
        if (smsTypeEnum == null) {
            return ResultVO.fail(HttpStatusEnum.CODE_TYPE_ERROR.getMsg());
        }
        //判断是否已经发送
        String cache = redisUtil.getCache(this.smsKey(mobile, type));
        if (Strings.isNotBlank(cache)) {
            return ResultVO.fail(HttpStatusEnum.PHONE_HAS_SEND.getMsg());
        }
        //发送验证码
        String randomCode = this.randomCode();
        SendResult sendResult = aliSmsService.sendCode(randomCode, mobile);
        //发送成功设置缓存, 时效5分钟
        if (sendResult.isSuccess()) {
            redisUtil.setCache(this.smsKey(mobile, type), randomCode, ExpireTimeEnum.FIVE_MIN.getTime());
        }
        return ResultVO.ok(Boolean.TRUE);
    }

    @Override
    public ResultVO<Boolean> smsCheck(SmsCheckParam smsCheckParam) {
        //校验短信验证码
        HttpStatusEnum httpStatusEnum = this.smsCheck(smsCheckParam.getType(), smsCheckParam.getMobile(), smsCheckParam.getCode());
        //验证失败
        if (!Objects.equals(httpStatusEnum, HttpStatusEnum.SUCCESS)) {
            return ResultVO.fail(httpStatusEnum.getMsg());
        }
        //返回
        return ResultVO.ok(Boolean.TRUE);
    }

    @Override
    public HttpStatusEnum smsCheck(Integer type, String mobile, String code) {
        //验证类型
        SmsTypeEnum smsTypeEnum = SmsTypeEnum.getByType(type);
        if (smsTypeEnum == null) {
            return HttpStatusEnum.CODE_TYPE_ERROR;
        }
        //验证手机号
        if (!RegexUtil.checkPhone(mobile)) {
            return HttpStatusEnum.PHONE_ERROR;
        }
        //获取缓存中的验证码
        String smsKey = this.smsKey(mobile, type);
        String cache = redisUtil.getCache(smsKey);
        //验证码已过期
        if (Strings.isBlank(cache)) {
            return HttpStatusEnum.CODE_IS_EXPIRED;
        }
        //验证码错误
        if (!Objects.equals(cache, code)) {
            return HttpStatusEnum.CODE_ERROR;
        }
        //验证成功, 删除缓存
        redisUtil.deleteCache(smsKey);
        //返回成功
        return HttpStatusEnum.SUCCESS;
    }

    private String randomCode() {
        return RandomUtil.randomNumbers(6);
    }

    private String smsKey(String mobile, Integer type) {
        return RedisKeyConstant.SMS_PHONE_KEY + "_" + mobile + "_" + type;
    }
}
