package com.fufan.mtsaas.tools;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fufan.mtsaas.util.HttpUtils;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

import javax.crypto.KeyGenerator;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class TokenEncryptor {

    public static String getToken(String model, String network, String input) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();

        // Step 1: 构建 JSON 并 Base64 编码
        Map<String, Object> data = new HashMap<>();
        data.put("model", model);
        data.put("network", network);
        data.put("input", input);
        String json = objectMapper.writeValueAsString(data);
        String base64Json = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8));

        // Step 2: SM4 加密（CBC模式）
        String smIV = getSMIV(); // 16字节IV
        byte[] ivBytes = smIV.getBytes(StandardCharsets.UTF_8);
        byte[] keyBytes = emoonPrivateKey().getBytes(StandardCharsets.UTF_8);

        byte[] encryptedBytes = encryptSM4(base64Json.getBytes(StandardCharsets.UTF_8), keyBytes, ivBytes);
        String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedBytes);

        // Step 3: 构建加密 payload 并 Base64 编码 + 替换字符
        Map<String, Object> payload = new HashMap<>();
        payload.put("encryptedBase64", encryptedBase64);
        payload.put("smIV", smIV);
        payload.put("publicKey", emoonPublicKey());

        String payloadJson = objectMapper.writeValueAsString(payload);
        String finalBase64 = Base64.getEncoder().encodeToString(payloadJson.getBytes(StandardCharsets.UTF_8));
        finalBase64 = finalBase64.replace('+', '-').replace('/', '_');

        // Step 4: 请求接口
        Map<String, String> postPayload = new HashMap<>();
        postPayload.put("information", finalBase64);
        String response = HttpUtils.sendHttpPostByJson(emoonAPI() + "/Apis/getToken", postPayload.toString());

//        Map<String, Object> result = objectMapper.readValue(response, new TypeReference<>() {});
        return "";
    }

    // SM4 CBC加密（带Padding）
    public static byte[] encryptSM4(byte[] input, byte[] key, byte[] iv) throws CryptoException {
        CBCBlockCipher blockCipher = new CBCBlockCipher(new SM4Engine());
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher, new PKCS7Padding());
        cipher.init(true, new ParametersWithIV(new KeyParameter(key), iv));

        byte[] output = new byte[cipher.getOutputSize(input.length)];
        int length = cipher.processBytes(input, 0, input.length, output, 0);
        length += cipher.doFinal(output, length);

        byte[] result = new byte[length];
        System.arraycopy(output, 0, result, 0, length);
        return result;
    }

    // 模拟方法：IV
    public static String getSMIV() {
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);
        return new String(iv, StandardCharsets.UTF_8);
    }

    // 模拟方法：私钥
    public static String emoonPrivateKey() {
        return "1234567890abcdef"; // 16字节密钥
    }

    // 模拟方法：公钥
    public static String emoonPublicKey() {
        return "emoon-public-key";
    }

    // 模拟方法：API地址
    public static String emoonAPI() {
        return "https://api.emoon.cn";
    }

    public static void main(String[] args) {

    }
}

