package com.red.circle.external.inner.service.binance.impl;

import com.binance.connector.client.common.ApiClient;
import com.binance.connector.client.common.ApiResponse;
import com.binance.connector.client.common.auth.BinanceAuthenticationFactory;
import com.binance.connector.client.common.configuration.ClientConfiguration;
import com.binance.connector.client.common.configuration.SignatureConfiguration;
import com.binance.connector.client.wallet.rest.api.CapitalApi;
import com.binance.connector.client.wallet.rest.model.DepositHistoryResponse;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.red.circle.external.infra.props.BinanceProperties;
import com.red.circle.external.inner.service.binance.BinanceClientService;
import com.red.circle.tool.core.collection.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * minimax  实现.
 *
 * @author pengliang on 2023/7/12
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class BinanceClientServiceImpl implements BinanceClientService {

    private final BinanceProperties binanceProperties;


    @Override
    public String depositHistory(String txId) {
        if (StringUtils.isBlank(txId)) {
            return "";
        }
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setUrl(binanceProperties.getUrl());
        SignatureConfiguration signatureConfiguration = new SignatureConfiguration();
        signatureConfiguration.setApiKey(binanceProperties.getApiKey());
        signatureConfiguration.setSecretKey(binanceProperties.getSecretKey());
        clientConfiguration.setSignatureConfiguration(signatureConfiguration);
        ApiClient apiClient = new ApiClient(clientConfiguration, new BinanceAuthenticationFactory());
        CapitalApi api = new CapitalApi(apiClient);
        // 获取当前时间戳（毫秒级）
        long currentTimeStamp = System.currentTimeMillis();

        // 计算24小时前的时间戳（毫秒级）
        long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L;
        long twentyFourHoursAgoTimeStamp = currentTimeStamp - twentyFourHoursInMillis;

        ApiResponse<DepositHistoryResponse> depositHistoryResponseApiResponse =
                api.depositHistory(true, "USDT", 1L, twentyFourHoursAgoTimeStamp, currentTimeStamp, 0L, 1000L, 5000L, txId);
        try {
            return depositHistoryResponseApiResponse.getData().get(0).getAmount();
        } catch (Exception e) {
            return "";
        }

    }

    @Override
    public String transactions(String orderId)
            throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
        long currentTimeStamp = System.currentTimeMillis();

        long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L;
        long twentyFourHoursAgoTimeStamp = currentTimeStamp - twentyFourHoursInMillis;

        Map<String, String> params = new HashMap<>();
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("recvWindow", "5000");
        params.put("startTime", String.valueOf(twentyFourHoursAgoTimeStamp));
        params.put("endTime", String.valueOf(currentTimeStamp));

        List<String> sortedKeys = new ArrayList<>(params.keySet());
        Collections.sort(sortedKeys);
        StringBuilder queryString = new StringBuilder();
        for (String key : sortedKeys) {
            if (!queryString.isEmpty()) {
                queryString.append("&");
            }
            queryString.append(java.net.URLEncoder.encode(key, "UTF-8"))
                    .append("=")
                    .append(java.net.URLEncoder.encode(params.get(key), "UTF-8"));
        }

        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(binanceProperties.getSecretKey().getBytes("UTF-8"), "HmacSHA256");
        hmacSha256.init(secretKey);
        byte[] signatureBytes = hmacSha256.doFinal(queryString.toString().getBytes("UTF-8"));
        String signature = Hex.encodeHexString(signatureBytes);

        OkHttpClient client = new OkHttpClient();
        String finalUrl = binanceProperties.getUrl() + "/sapi/v1/pay/transactions" + "?" + queryString + "&signature=" + signature;
        Request request = new Request.Builder()
                .url(finalUrl)
                .addHeader("X-MBX-APIKEY", binanceProperties.getApiKey())
                .build();

        try (Response response = client.newCall(request).execute()) {
            assert response.body() != null;
            String string = response.body().string();
            Map<String, String> map = parseOrderIdAndAmount(string);
            return CollectionUtils.isEmpty(map) ? "" : map.get(orderId);
        } catch (IOException e) {
            return "";
        }
    }

    public static Map<String, String> parseOrderIdAndAmount(String responseBody) {
        Map<String, String> orderMap = new HashMap<>();

        try {
            // 创建ObjectMapper实例
            ObjectMapper objectMapper = new ObjectMapper();

            // 解析JSON
            JsonNode rootNode = objectMapper.readTree(responseBody);

            // 获取data数组
            JsonNode dataNode = rootNode.get("data");

            // 检查data是否存在且是数组
            if (dataNode != null && dataNode.isArray()) {
                // 遍历数组中的每个元素
                for (JsonNode node : dataNode) {
                    // 提取orderId
                    JsonNode orderIdNode = node.get("orderId");
                    // 提取amount
                    JsonNode amountNode = node.get("amount");

                    // 只有当两个字段都存在且为字符串类型时才添加到Map
                    if (orderIdNode != null && orderIdNode.isTextual() &&
                            amountNode != null && amountNode.isTextual()) {
                        orderMap.put(orderIdNode.asText(), amountNode.asText());
                    }
                }
            }
        } catch (Exception e) {
            return orderMap;
        }
        return orderMap;
    }

    public static void main(String[] args) {
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setUrl("https://api.binance.com");
        SignatureConfiguration signatureConfiguration = new SignatureConfiguration();
        signatureConfiguration.setApiKey("币安的Key");
        signatureConfiguration.setSecretKey("币安的密钥");
        clientConfiguration.setSignatureConfiguration(signatureConfiguration);

        ApiClient apiClient = new ApiClient(clientConfiguration, new BinanceAuthenticationFactory());

        CapitalApi api = new CapitalApi(apiClient);

        // 获取当前时间戳（毫秒级）
        long currentTimeStamp = System.currentTimeMillis();

        // 计算24小时前的时间戳（毫秒级）
        long twentyFourHoursInMillis = 24 * 60 * 60 * 1000L;
        long twentyFourHoursAgoTimeStamp = currentTimeStamp - twentyFourHoursInMillis;


        System.out.println("currentTimeStamp: " + currentTimeStamp);
        System.out.println("twentyFourHoursAgoTimeStamp: " + twentyFourHoursAgoTimeStamp);

        ApiResponse<DepositHistoryResponse> depositHistoryResponseApiResponse =
                api.depositHistory(true, "USDT", 1L, twentyFourHoursAgoTimeStamp, currentTimeStamp, 0L, 1000L, 5000L, "");

        System.out.println(depositHistoryResponseApiResponse.getStatusCode());
        System.out.println(depositHistoryResponseApiResponse.getData().get(0).getAmount());


    }

}
