package com.jumeirah.api.app.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.jumeirah.api.app.service.AppSmsService;
import com.jumeirah.api.app.vo.SmsCode;
import com.jumeirah.common.service.AppUserService;
import com.jumeirah.common.vo.AppUserQueryVo;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Arrays;

@Service
@Slf4j
public class AppSmsServiceImpl implements AppSmsService {
    @Autowired
    private AppUserService appUserService;

    /**
     * 获取当前环境
     */
    @Value("${spring.profiles.active}")
    private String profiles;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 测试环境
     */
    private static final String DEV_PROFILE = "dev";

    /**
     * 测试环境默认短信验证码
     */
    private static final String DEFAULT_DEV_SMS_CODE = "666666";

    /**
     * 注册 短信验证码redis的key值
     */
    private static final String SMS_REGIEST = "sms:app:register:%s_%s";
    /**
     * 修改 短信验证码redis的key值
     */
    private static final String SMS_UPDATE = "sms:app:update:%s_%s";

    /**
     * 短信验证码redis的key值
     */
    private static final String SMS_LOGIN = "sms:app:login:%s_%s";

    @Override
    public void deleteRegisterCode(String area, String number) {
        redisTemplate.delete(String.format(SMS_REGIEST, area, number));
    }

    @Override
    public void deleteUpdatePhoneCode(String area, String number) {

        redisTemplate.delete(String.format(SMS_UPDATE, area, number));


    }

    @Override
    public ApiResult<Object> registerOrLoginCode(String area, String number) {
        return getSmsCodeApiResult(String.format(SMS_REGIEST, area, number), area, number);
    }

    @Override
    public ApiResult<Object> updatePhoneCode() throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        AppUserQueryVo appUserById = appUserService.getAppUserById(jwtToken.getUserId());
        return getSmsCodeApiResult(String.format(SMS_UPDATE, appUserById.getPhoneArea(), appUserById.getPhone()), appUserById.getPhoneArea(), appUserById.getPhone());
    }

    private ApiResult<Object> getSmsCodeApiResult(String key, String area, String number) {
        String randomCode = getRandomCode();

        // 过期时间(秒)
        long expire = 120L;

        Duration expireDuration = Duration.ofSeconds(expire);

        redisTemplate.opsForValue().set(key, randomCode, expireDuration);

        SmsCode smsCode = new SmsCode();
        smsCode.setSmsCode(randomCode);
        log.info(area + "," + number + ":" + randomCode);

        // TODO 需要补充调用短信平台发送短信代码 2020年09月30日09:48:42

        return ApiResult.ok(null);
    }

    @Override
    public ApiResult LoginType(String area, String number) {
        return getSmsCodeApiResult(String.format(SMS_LOGIN, area, number), area, number);
    }

    @Override
    public boolean equalsRegisterCode(String area, String number, String code) {
        return equalsSms(SMS_REGIEST, area, number, code);
    }

    @Override
    public boolean equalsUpdatePhoneCode(String area, String number, String code) {
        return equalsSms(SMS_UPDATE, area, number, code);
    }

    private boolean equalsSms(String type, String area, String number, String code) {
        String formatKey = String.format(type, area, number);

        Object key = redisTemplate.opsForValue().get(formatKey);

        if (key == null) {
            return false;
        }

        return String.valueOf(key).equals(code);
    }

    @Override
    public boolean equalsLoginCode(String area, String number, String code) {
        return equalsSms(SMS_LOGIN, area, number, code);
    }

    /**
     * 生成验证码code
     *
     * @return
     */
    String getRandomCode() {
        // 如果为测试环境则生成默认
        if (profiles.equals(DEV_PROFILE) || profiles.equals("test")) {
            return DEFAULT_DEV_SMS_CODE;
        } else {
            return Arrays.toString(RandomUtil.randomInts(6));
        }
    }


}
