package org.dromara.zjk.zwy.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.zjk.zwy.properties.EncryptProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
@RequiredArgsConstructor
public class EncryptTokenClient {

    private final EncryptProperties properties;
    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();

    private String cachedToken;
    private long cachedTime = 0;
    private final long TOKEN_VALID_DURATION = 25 * 60 * 1000L; // 提前 5 分钟更新

    public String getAppToken() {
        if (cachedToken != null && System.currentTimeMillis() - cachedTime < TOKEN_VALID_DURATION) {
            return cachedToken;
        }
        return refreshToken();
    }

    // 定时刷新 token（可选）
    @Scheduled(fixedDelay = 20 * 60 * 1000L) // 每 20 分钟刷新一次
    public void scheduledRefreshToken() {
        try {
            refreshToken();
        } catch (Exception e) {
            log.warn("定时刷新Token失败: {}", e.getMessage());
        }
    }

    private synchronized String refreshToken() {
        String url = properties.getServerUrl() + "/appToken/v1/getAppToken";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("appId", properties.getAppId());
        headers.set("timestamp", String.valueOf(System.currentTimeMillis()));
        headers.set("nonce", UUID.randomUUID().toString().replaceAll("-", ""));

        Map<String, String> body = Map.of("secretKey", properties.getSecretKey());
        HttpEntity<Map<String, String>> entity = new HttpEntity<>(body, headers);

        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        try {
            String token = objectMapper
                .readTree(response.getBody())
                .path("data")
                .path("token")
                .asText();
            if (token != null && !token.isBlank()) {
                this.cachedToken = token;
                this.cachedTime = System.currentTimeMillis();
            }
            return token;
        } catch (Exception e) {
            throw new RuntimeException("Token 获取或解析失败", e);
        }
    }
}
