package com.example.backend.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 钉钉 accessToken 缓存管理器（本地缓存版）
 */
@Component
public class AccessTokenManager {
    private static final Logger log = LoggerFactory.getLogger(AccessTokenManager.class);

    private static class TokenInfo {
        private final String accessToken;
        private final long expireAt;
        public TokenInfo(String accessToken, long expireAt) {
            this.accessToken = accessToken;
            this.expireAt = expireAt;
        }
        public String getAccessToken() { return accessToken; }
        public long getExpireAt() { return expireAt; }
    }

    // key: appKey/clientId, value: token信息
    private final ConcurrentHashMap<String, TokenInfo> tokenCache = new ConcurrentHashMap<>();

    /**
     * 获取 accessToken，自动缓存与续期
     * @param appKey 应用唯一标识
     * @param appSecret 应用密钥
     * @param fetcher 实际获取token的回调（如调用钉钉API）
     * @return accessToken
     */
    public synchronized String getAccessToken(String appKey, String appSecret, AccessTokenFetcher fetcher) {
        TokenInfo tokenInfo = tokenCache.get(appKey);
        long now = System.currentTimeMillis();
        if (tokenInfo != null && tokenInfo.getExpireAt() > now) {
            log.debug("accessToken 命中缓存，appKey={}", appKey);
            return tokenInfo.getAccessToken();
        }
        // 重新获取
        log.info("accessToken 过期或未命中，appKey={}，重新获取", appKey);
        String newToken = fetcher.fetch(appKey, appSecret);
        long expireAt = now + 7200_000 - 60_000; // 提前1分钟过期
        tokenCache.put(appKey, new TokenInfo(newToken, expireAt));
        return newToken;
    }

    /**
     * 获取token的回调接口
     */
    @FunctionalInterface
    public interface AccessTokenFetcher {
        String fetch(String appKey, String appSecret);
    }
} 