package com.ruoyi.erp.request;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.http.HttpUtils;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * ERP请求基类（支持开放平台签名规范）
 */
public abstract class ERPRequestBase {
    private static final Logger log = LoggerFactory.getLogger(ERPRequestBase.class);

    protected String url;
    protected String sign;
    protected IERPAccount erpAccount;
    @Setter
    protected JSONObject requestBody;
    protected long timestamp; // 统一时间戳字段

    public ERPRequestBase(String url, IERPAccount erpAccount) {
        this.url = url;
        this.erpAccount = erpAccount;
    }

    /**
     * 生成MD5签名（兼容官方示例）
     * @param str 需要签名的原始字符串
     * @return 十六进制小写MD5值
     */
    public String genMd5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
            StringBuilder result = new StringBuilder();
            for (byte b : digest) {
                result.append(String.format("%02x", b & 0xff)); // 保证小写十六进制
            }
            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            log.error("MD5算法初始化失败", e);
            throw new RuntimeException("MD5算法初始化失败", e);
        }
    }

    /**
     * 生成请求签名（与官方示例保持完全一致的拼接逻辑）
     */
    public void genSign(long timestamp) {
        this.timestamp = timestamp;
        String jsonStr = getRequestBody(); // 使用getRequestBody()方法
        String data = erpAccount.getApiKey() + "," + genMd5(jsonStr) + "," + timestamp + "," + erpAccount.getApiKeySecret();
        this.sign = genMd5(data);
    }
    /**
     * 获取带签名的请求URL
     * @return 包含签名参数的完整URL
     */
    public String getRequestUrl() {
        return url + "?appid=" + erpAccount.getApiKey() + "&timestamp=" + timestamp + "&sign=" + sign;
    }

    /**
     * 获取请求体内容（空时返回空对象）
     * @return JSON字符串格式的请求体
     */
    public String getRequestBody() {
        return requestBody != null ? requestBody.toJSONString() : "{}";
    }

    /**
     * 执行HTTP请求并获取响应
     * @return 接口返回的原始JSON字符串
     */
    public String getResponseBody() {
        try {
            long timestamp = System.currentTimeMillis() / 1000;
            genSign(timestamp);
            String requestUrl = getRequestUrl();
            String body = getRequestBody();

            System.out.println("请求地址: " + requestUrl);
            System.out.println("请求体: " + body);

            // 统一通过自定义 SSL 通道发起请求，提升与开放平台的 TLS 兼容性
            return HttpUtils.sendSSLPost(requestUrl, body, org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
        } catch (Exception e) {
            log.error("HTTP请求失败: {}", e.getMessage(), e);
            throw new RuntimeException("ERP接口调用失败: " + e.getMessage(), e);
        }
    }
}
