using Hotline.Share.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace TianQue.Sdk;
public class SignUtils
{
    private static readonly string SIGN_KEY = "_sign";
    private static readonly HashSet<string> SKIP_SIGN_PARAMS = new HashSet<string> { SIGN_KEY };

    public static string Sign(string appSecret, Dictionary<string, object> headers, string body)
    {
        var sorted = BuildSignSortedMap(headers, body);
        var stringBuilder = new StringBuilder();
        stringBuilder.Append(appSecret);
        string result = string.Join("",
            sorted.SelectMany(
                kvp => kvp.Value.Select(value => $"{kvp.Key}{value}")
            )
        );
        stringBuilder.Append(result);
        stringBuilder.Append(appSecret);
        var str = stringBuilder.ToString();
        return MD5Hex(str);
    }

    public static SortedDictionary<string, SortedSet<string>> BuildSignSortedMap(Dictionary<string, object> keyValueParams, string body)
    {
        var sortedMap = new SortedDictionary<string, SortedSet<string>>();

        if (keyValueParams != null && keyValueParams.Count > 0)
        {
            foreach (var entry in keyValueParams)
            {
                if (entry.Key != SIGN_KEY)
                {
                    sortedMap[entry.Key] = new SortedSet<string>
                    {
                        entry.Value.ToString()
                    };
                }
            }
        }

        if (!string.IsNullOrEmpty(body))
        {
            var a = new SortedSet<string>
            {
                body
            };
            sortedMap["_body"] = a;
        }

        return sortedMap;
    }

    private static string MD5Hex(string data)
    {
        using (var md5 = MD5.Create()) // 使用 MD5 哈希算法
        {
            byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(data)); // 将字符串转换为字节并计算哈希
            return BitConverter.ToString(bytes).Replace("-", "").ToLowerInvariant(); // 转换为十六进制字符串（小写）
        }
    }

    public static string GenerateNonce()
    {
        // 生成随机 UUID 字符串
        string uuid = Guid.NewGuid().ToString();

        // 生成 10 个随机字符（包含字母和数字）
        string randomString = GenerateRandomString(10);

        // 使用 HMAC-SHA256 计算哈希值
        return ComputeHmacSha256(uuid, randomString);
    }

    private static string GenerateRandomString(int length)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        var random = new Random();
        var result = new StringBuilder(length);
        for (int i = 0;i < length;i++)
        {
            result.Append(chars[random.Next(chars.Length)]);
        }
        return result.ToString();
    }

    private static string ComputeHmacSha256(string key, string data)
    {
        // 将密钥和数据转换为字节数组
        byte[] keyBytes = Encoding.UTF8.GetBytes(key);
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);

        // 使用 HMACSHA256 生成 HMAC 值
        using (HMACSHA256 hmac = new HMACSHA256(keyBytes))
        {
            byte[] hashBytes = hmac.ComputeHash(dataBytes);

            // 将字节数组转换为十六进制字符串
            StringBuilder hex = new StringBuilder(hashBytes.Length * 2);
            foreach (byte b in hashBytes)
            {
                hex.AppendFormat("{0:x2}", b);
            }
            return hex.ToString();
        }
    }
}
