package com.storlead.framework.common.util.sso;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @program: storlead-centre-platform
 * @description:
 * @author: chenkq
 * @create: 2025-11-21 16:03
 */
public class CryptoZipUtil {

    private static final String AES_CIPHER = "AES/CBC/PKCS5Padding";
    private static final String IV = "1234567890abcdef"; // 16字节固定 IV
    public static final String SALT_KEY = "G4YfTqX6Kh8cHQy5";



    // ====================================
    // Map → URL 参数 → GZIP → AES → Base64
    // ====================================
    public static String encryptParams(Map<String, String> params, String key) {
        StringBuilder sb = new StringBuilder();
        params.forEach((k, v) -> {
            try {
                sb.append(URLEncoder.encode(k, "UTF-8"))
                        .append("=")
                        .append(URLEncoder.encode(v, "UTF-8"))
                        .append("&");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        String paramString = sb.substring(0, sb.length() - 1);

        // 1. GZIP 压缩
        byte[] gzipData = gzip(paramString.getBytes(StandardCharsets.UTF_8));

        // 2. AES 加密
        byte[] encryptedBytes = aesEncrypt(gzipData, key);

        // 3. Base64 URL 安全编码
        return Base64.getUrlEncoder().encodeToString(encryptedBytes);
    }

    // ====================================
    // Base64 → AES 解密 → GZIP 解压 → Map
    // ====================================
    public static Map<String, String> decryptParams(String encrypted, String key) {
        try {
            byte[] encryptedBytes = Base64.getUrlDecoder().decode(encrypted);

            // 1. AES 解密
            byte[] gzipBytes = aesDecrypt(encryptedBytes, key);

            // 2. GZIP 解压
            String decrypted = new String(gunzip(gzipBytes), StandardCharsets.UTF_8);

            // 3. URL 参数解析
            Map<String, String> map = new HashMap<>();
            for (String pair : decrypted.split("&")) {
                String[] kv = pair.split("=");
                if (kv.length == 2) {
                    map.put(
                            URLDecoder.decode(kv[0], "UTF-8"),
                            URLDecoder.decode(kv[1], "UTF-8")
                    );
                }
            }
            return map;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // GZIP 压缩
    private static byte[] gzip(byte[] data) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try (GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
                gzip.write(data);
            }
            return bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("GZIP 压缩失败", e);
        }
    }

    // GZIP 解压
    private static byte[] gunzip(byte[] data) {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            GZIPInputStream gis = new GZIPInputStream(new java.io.ByteArrayInputStream(data));
            byte[] buffer = new byte[1024];
            int len;
            while ((len = gis.read(buffer)) > 0) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("GZIP 解压失败", e);
        }
    }

    // AES 加密
    private static byte[] aesEncrypt(byte[] content, String key) {
        try {
            Cipher cipher = Cipher.getInstance(AES_CIPHER);
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec iv = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            return cipher.doFinal(content);
        } catch (Exception e) {
            throw new RuntimeException("AES 加密失败", e);
        }
    }

    // AES 解密
    private static byte[] aesDecrypt(byte[] encrypted, String key) {
        try {
            Cipher cipher = Cipher.getInstance(AES_CIPHER);
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec iv = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            return cipher.doFinal(encrypted);
        } catch (Exception e) {
            throw new RuntimeException("AES 解密失败", e);
        }
    }
}

