package com.zsElectric.boot.core.pay.WFT;

import cn.hutool.core.util.StrUtil;
import com.zsElectric.boot.core.pay.WFT.WFTConstants;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 威富通支付工具类
 *
 * @author zsElectric
 * @since 2025-12-29
 */
@Slf4j
public class WFTPayUtils {

    private static final MediaType XML_MEDIA_TYPE = MediaType.parse("application/xml; charset=utf-8");
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build();

    /**
     * 构建XML请求体
     *
     * @param params 参数Map
     * @return XML字符串
     */
    public static String buildXmlRequest(Map<String, String> params) {
        StringBuilder xml = new StringBuilder("<xml>");
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (StrUtil.isNotEmpty(entry.getValue())) {
                xml.append("<").append(entry.getKey()).append(">")
                        .append("<![CDATA[").append(entry.getValue()).append("]]>")
                        .append("</").append(entry.getKey()).append(">");
            }
        }
        xml.append("</xml>");
        return xml.toString();
    }

    /**
     * 解析XML响应
     *
     * @param xml XML字符串
     * @return 参数Map
     * @throws Exception 解析异常
     */
    public static Map<String, String> parseXmlResponse(String xml) throws Exception {
        Map<String, String> result = new HashMap<>();

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 防止XXE攻击
        factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
        factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
        Document doc = builder.parse(is);

        NodeList nodeList = doc.getDocumentElement().getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) node;
                result.put(element.getNodeName(), element.getTextContent());
            }
        }

        return result;
    }

    /**
     * 发送POST请求
     *
     * @param url     请求URL
     * @param xmlData XML数据
     * @return 响应XML字符串
     * @throws Exception 请求异常
     */
    public static String sendPostRequest(String url, String xmlData) throws Exception {
        RequestBody body = RequestBody.create(xmlData, XML_MEDIA_TYPE);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();

        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new RuntimeException("HTTP请求失败，状态码：" + response.code());
            }
            ResponseBody responseBody = response.body();
            if (responseBody == null) {
                throw new RuntimeException("响应体为空");
            }
            return responseBody.string();
        }
    }

}
