package com.hz.pm.api.user.manage;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.HMac;
import com.hz.pm.api.common.config.AuthCodeProps;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import java.time.Duration;

/**
 * <p>
 * AuthCodeLoginManage
 * </p>
 *
 * @author WendyYang
 * @since 23:59 2023/12/20
 */
@Slf4j
@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(AuthCodeProps.class)
public class AuthCodeLoginManage {

    private final CachePlusOps cachePlusOps;
    private final AuthCodeProps authCodeProps;

    private String generateAuthCode(String userId, boolean checkSign, Long timestamp, String sign) {
        if (checkSign) {
            if (System.currentTimeMillis() - timestamp > 5000) {
                throw BizException.wrap("签名无效");
            }
            HMac hmacMd5 = SecureUtil.hmacMd5(authCodeProps.getSecretKey());
            String digestHex = hmacMd5.digestHex(userId + "#" + timestamp);
            if (!digestHex.equals(sign)) {
                throw BizException.wrap("获取授权码失败：签名错误");
            }
        }
        String authCode = RandomUtil.randomString(authCodeProps.getLength());
        Duration duration = Duration.ofSeconds(authCodeProps.getExpireTime());
        CacheKey key = new CacheKey(authCode, duration);
        cachePlusOps.set(key, userId);
        log.info("生成授权码：{} -> {}", userId, authCode);
        return authCode;
    }

    public String generateAuthCode(String userId, Long timestamp, String sign) {
        return generateAuthCode(userId, true, timestamp, sign);
    }

    public String generateAuthCode(String userId) {
        return generateAuthCode(userId, false, null, null);
    }

    public String getUserIdByAuthCode(String authCode) {
        CacheKey key = new CacheKey(authCode);
        try {
            return cachePlusOps.get(key);
        } finally {
            cachePlusOps.del(key);
        }
    }

}
