package com.YuyeTech.TPlat.utils;

import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.json.JSONUtil;
import com.YuyeTech.TPlat.constant.RankingConstant;
import com.YuyeTech.TPlat.constant.RedisConstant;
import com.YuyeTech.TPlat.enums.RedisType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.YuyeTech.TPlat.sys.syssetting.service.SysSettingService;
import com.YuyeTech.TPlat.sys.syssetting.vo.SysSettingVo;
import com.YuyeTech.TPlat.sys.syssettinglimit.service.SysSettingLimitService;
import com.YuyeTech.TPlat.sys.syssettinglimit.vo.SysSettingLimitVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 *
 * 存储对应的配置
 * @author:slambb
 * @date:2022/4/19
 */

@Component
public class RedisSettingMap {
    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SysSettingService sysSettingService;

    @Autowired
    private SysSettingLimitService sysSettingLimitService;
    

    //动态设置一个RSA key保存
    private String rsaPublicKey = ":rsa:public";
    private String rsaPrivateKey = ":rsa:private";
    //update 一次rsa数据
    public void updateRSAMap(){
        RSA rsa = new RSA();
        String privateKeyBase64 = rsa.getPrivateKeyBase64();
        String publicKeyBase64 = rsa.getPublicKeyBase64();
        redisTemplate.opsForValue().set(applicationName.concat(rsaPublicKey), JSONUtil.toJsonStr(publicKeyBase64));
        redisTemplate.opsForValue().set(applicationName.concat(rsaPrivateKey), JSONUtil.toJsonStr(privateKeyBase64));
    }
    //从redis 获取系统设置 rsa 设置
    public String getRSAPublicKeyBase64(){
        if (redisTemplate.hasKey(applicationName.concat(rsaPublicKey))) {
            return  redisTemplate.opsForValue().get(applicationName.concat(rsaPublicKey));
        } else {
            RSA rsa = new RSA();
            String privateKeyBase64 = rsa.getPrivateKeyBase64();
            String publicKeyBase64 = rsa.getPublicKeyBase64();
            redisTemplate.opsForValue().set(applicationName.concat(rsaPublicKey), JSONUtil.toJsonStr(publicKeyBase64));
            redisTemplate.opsForValue().set(applicationName.concat(rsaPrivateKey), JSONUtil.toJsonStr(privateKeyBase64));
            return publicKeyBase64;
        }
    }
    public String getRSAPrivateKeyBase64(){
        if (redisTemplate.hasKey(applicationName.concat(rsaPrivateKey))) {
            return  redisTemplate.opsForValue().get(applicationName.concat(rsaPrivateKey));
        } else {
            RSA rsa = new RSA();
            String privateKeyBase64 = rsa.getPrivateKeyBase64();
            String publicKeyBase64 = rsa.getPublicKeyBase64();
            redisTemplate.opsForValue().set(applicationName.concat(rsaPublicKey), JSONUtil.toJsonStr(publicKeyBase64));
            redisTemplate.opsForValue().set(applicationName.concat(rsaPrivateKey), JSONUtil.toJsonStr(privateKeyBase64));
            return privateKeyBase64;
        }
    }

    //系统设置key
    private String sysSettingKey = ":sys:setting";
    //update 一次redis数据
    public void updateSysSettingMap(){
        SysSettingVo sysSettingVo = sysSettingService.get("1").getData();
        redisTemplate.opsForValue().set(applicationName.concat(sysSettingKey), JSONUtil.toJsonStr(sysSettingVo));
    }
    //从redis 获取系统设置 sysSettingMap
    public SysSettingVo getSysSettingMap(){
        SysSettingVo sysSettingVo;
        if (redisTemplate.hasKey(applicationName.concat(sysSettingKey))) {
            sysSettingVo = JSON.parseObject(redisTemplate.opsForValue().get(applicationName.concat(sysSettingKey)),new TypeReference<SysSettingVo>(){});
        } else {
            sysSettingVo = sysSettingService.get("1").getData();
            redisTemplate.opsForValue().set(applicationName.concat(sysSettingKey), JSONUtil.toJsonStr(sysSettingVo));
        }
        return sysSettingVo;
    }
    //redis 设置 sysSettingMap
    public void setSysSettingMap(SysSettingVo sysSettingVo){
        redisTemplate.opsForValue().set(applicationName.concat(sysSettingKey), JSONUtil.toJsonStr(sysSettingVo));
    }

    //限制登录ip key
    private String sysSettingLimitKey = ":sys:settingLimit";
    //update 一次redis数据
    public void updateSysSettingLimitMap(){
        SysSettingLimitVo sysSettingLimitVo = sysSettingLimitService.get("1").getData();
        redisTemplate.opsForValue().set(applicationName.concat(sysSettingLimitKey), JSONUtil.toJsonStr(sysSettingLimitVo));;
    }
    //从redis 获取系统设置 sysSettingLimitMap
    public SysSettingLimitVo getSysSettingLimitMap(){
        SysSettingLimitVo sysSettingLimitVo;
        if (redisTemplate.hasKey(applicationName.concat(sysSettingLimitKey))) {
            sysSettingLimitVo = JSON.parseObject(redisTemplate.opsForValue().get(applicationName.concat(sysSettingLimitKey)),new TypeReference<SysSettingLimitVo>(){});
        } else {
            sysSettingLimitVo = sysSettingLimitService.get("1").getData();
            redisTemplate.opsForValue().set(applicationName.concat(sysSettingLimitKey), JSONUtil.toJsonStr(sysSettingLimitVo));
        }
        return sysSettingLimitVo;
    }
    //设置SysSettingTask到Map
    public void setSysSettingLimitMap(SysSettingLimitVo sysSettingLimitVo){
        redisTemplate.opsForValue().set(applicationName.concat(sysSettingLimitKey), JSONUtil.toJsonStr(sysSettingLimitVo));
    }


    /**
     * ranking 排行榜相关操作
     */
    /**
     * 获取城市key
     * @param cityCode
     * @param gameId
     * @return
     */
    public String getCityKey(String cityCode,String gameId){
        return  applicationName.concat(":city:").concat(String.format(RankingConstant.cityKey, cityCode.substring(0, 4), gameId));
    }

    /**
     * 获取全国key
     * @param gameId
     * @return
     */
    public String getChinaKey(String gameId){
        return applicationName.concat(":china:").concat(String.format(RankingConstant.chinaKey, gameId));
    }

    /**
     * token相关操作
     */
    /**
     * 根据token生成对应的key
     * @param token
     * @return
     */
    public String getTokenKey(String token){
        return applicationName.concat(":").concat(String.format(RedisConstant.TOKEN_PREFIX, token));
    }
    /**
     * 对应token存放 map 信息
     * @param token
     * @param tokenMap
     */
    public void putToken(String token, Map<String, String> tokenMap){
        Integer expire = RedisConstant.EXPIRE;//过期时间
        redisTemplate.opsForHash().putAll(getTokenKey(token), tokenMap);
        redisTemplate.expire(getTokenKey(token), expire, TimeUnit.SECONDS);
    }


    /**
     * SMS相关操作
     */
    /**
     * 短信key
     * @param key
     * @return
     */
    public String getSMSKey(String key){
       return applicationName.concat(":").concat(String.format(RedisConstant.SMS_PREFIX, key));
    }

    /**
     * 设置短信缓存
     * @param key
     * @param code
     */
    public void setSMS(String key,String code){
        Integer expire = RedisConstant.CODE_EXPIRE;//过期时间
        redisTemplate.opsForValue().set(getSMSKey(key), code, expire, TimeUnit.SECONDS);
    }


    /**
     * 根据类型获取缓存值
     * @param redisType
     * @param key
     * @return
     */
    public String getValue(RedisType redisType,String key){
        switch (redisType){
            case SMS:
                /**
                 * 获取短信key对应的值
                 */
                 return redisTemplate.opsForValue().get(getSMSKey(key));
            case TOKEN:
                /**
                 * 获取token的key对应userId
                 */
                return redisTemplate.opsForHash().get(getTokenKey(key), "userId").toString();
            default: return null;
        }
    }

    /**
     * 根据类型删除缓存值
     * @param redisType
     * @param key
     * @return
     */
    public Boolean deleteValue(RedisType redisType,String key){
        switch (redisType){
            case SMS:
                /**
                 * 删除短信key的值
                 */
                return redisTemplate.delete(getSMSKey(key));
            default: return null;
        }
    }
}
