package org.dromara.zjk.zwy.client;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;

import lombok.extern.slf4j.Slf4j;
import org.dromara.zjk.zwy.properties.EncryptProperties;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.UUID;

/**
 * 加密服务，使用aop的方式
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class EncryptClient {

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

    public String encrypt(String plainText) {
        try {
            String base64Plaintext = Base64.getEncoder().encodeToString(plainText.getBytes(StandardCharsets.UTF_8));

            MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
            formData.add("keyId", properties.getKeyId());
            formData.add("plaintext", base64Plaintext);

            HttpHeaders headers = buildHeaders(formData);
            HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(formData, headers);
            String url = properties.getServerUrl() + "/key/v3/encrypt";

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

            String responseBody = response.getBody();

            JsonNode root = objectMapper.readTree(responseBody);
            int code = root.path("code").asInt();
            String msg = root.path("msg").asText();

            if (code != 0) {
                throw new RuntimeException("调用加密服务失败，code=" + code + "，msg=" + msg);
            }

            String cipherText = root.path("data").path("CiphertextBlob").asText();
            if (cipherText == null || cipherText.isEmpty()) {
               throw new RuntimeException("加密服务响应中 CiphertextBlob 字段为空");
            }

            return cipherText;
        } catch (Exception e) {
            log.error("调用加密服务失败，明文内容：{}", plainText, e);
            throw new RuntimeException("调用加密服务失败", e);
        }
    }



    private HttpHeaders buildHeaders(MultiValueMap<String, String> params) {
        String appId = properties.getAppId();

        // 生成 timestamp 和 nonce
        String timestamp = String.valueOf(System.currentTimeMillis());
        String nonce = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);

        // 获取应用 Token（从缓存或刷新）
        String gateWayToken = encryptTokenClient.getAppToken();

        // 构造 Headers
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("appId", appId);
        headers.add("timestamp", timestamp);
        headers.add("nonce", nonce);
        headers.add("gateWayToken", gateWayToken);

        // 打印调试日志
        log.debug("构建请求 Headers: appId={}, timestamp={}, nonce={}, gateWayToken={}", appId, timestamp, nonce, gateWayToken);

        return headers;
    }


}

