package com.nbport.zgwl.seal.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.nbport.zgwl.seal.config.SealConfig;
import com.nbport.zgwl.seal.utils.HMacSHA256Util;
import com.nbport.zgwl.seal.utils.SeaHttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 签章平台Token管理服务
 *
 * @author xiaofengzhou
 */
@Service
public class SealTokenService {

    private static final Logger log = LoggerFactory.getLogger(SealTokenService.class);

    @Autowired
    private SealConfig sealConfig;

    private volatile String cachedToken;

    private volatile long tokenExpireTime = 0;

    private final ReentrantLock lock = new ReentrantLock();

    private static final long TOKEN_EXPIRE_SECONDS = 7200;

    private static final long REFRESH_BEFORE_SECONDS = 300;

    public String getAccessToken() {
        long now = System.currentTimeMillis();
        if (cachedToken != null && now < tokenExpireTime - REFRESH_BEFORE_SECONDS * 1000) {
            return cachedToken;
        }

        try {
            lock.lock();
            if (cachedToken != null && now < tokenExpireTime - REFRESH_BEFORE_SECONDS * 1000) {
                return cachedToken;
            }
            refreshToken();
            return cachedToken;
        } finally {
            lock.unlock();
        }
    }

    public String forceRefreshToken() {
        try {
            lock.lock();
            refreshToken();
            return cachedToken;
        } finally {
            lock.unlock();
        }
    }

    private void refreshToken() {
        try {
            String appKey = sealConfig.getAppKey();
            String appSecret = sealConfig.getAppSecret();
            long timestamp = System.currentTimeMillis();

            JSONObject signData = new JSONObject();
            signData.put("appKey", appKey);
            signData.put("timestamp", timestamp);
            String signatureStr = JSON.toJSONString(signData);

            String signature = HMacSHA256Util.encrypt(signatureStr, appSecret);
            log.debug("签章平台Token请求 - 签名原文: {}, 签名值: {}", signatureStr, signature);

            JSONObject requestBody = new JSONObject();
            requestBody.put("appKey", appKey);
            requestBody.put("timestamp", timestamp);
            requestBody.put("signature", signature);

            String url = sealConfig.getBaseUrl() + "/saas/api/token/getAccessToken";
            log.info("请求签章平台获取Token, URL: {}", url);
            String response = SeaHttpUtils.sendPost(url, requestBody.toJSONString(), MediaType.APPLICATION_JSON_VALUE);

            JSONObject result = JSON.parseObject(response);
            if (result.getBooleanValue("isSuccess")) {
                JSONObject data = result.getJSONObject("data");
                cachedToken = data.getString("access_token");
                long expiresIn = data.getLongValue("expires_in", TOKEN_EXPIRE_SECONDS);
                tokenExpireTime = System.currentTimeMillis() + expiresIn * 1000;
                log.info("签章平台Token获取成功, 有效期: {}秒", expiresIn);
            } else {
                String msg = result.getString("msg");
                log.error("签章平台Token获取失败: {}", msg);
                throw new RuntimeException("获取签章平台Token失败: " + msg);
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取签章平台Token异常", e);
            throw new RuntimeException("获取签章平台Token异常: " + e.getMessage(), e);
        }
    }

    public void clearToken() {
        try {
            lock.lock();
            cachedToken = null;
            tokenExpireTime = 0;
        } finally {
            lock.unlock();
        }
    }
}
