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

namespace Fuel.Payment.Service.UnionPayProcessor
{
    public class Utils
    {
        public static string GetNonce()
        {
            string uuid = Guid.NewGuid().ToString().Replace("-", "");
            return uuid;
        }

        public static string GetAuthorization(string appid, string appkey, string body)
        {
            SHA256 sha256 = new SHA256CryptoServiceProvider();
            byte[] retVal = sha256.ComputeHash(Encoding.UTF8.GetBytes(body));
            var sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }

            var encoding = new ASCIIEncoding();
            byte[] keyByte = encoding.GetBytes(appkey);
            string authorization;
            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
                string nonce = GetNonce();
                byte[] messageBytes = encoding.GetBytes(appid + timestamp + nonce + sb.ToString());
                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
                string signature = Convert.ToBase64String(hashmessage);
                authorization = $"OPEN-BODY-SIG AppId=\"{appid}\", Timestamp=\"{timestamp}\", Nonce=\"{nonce}\", Signature=\"{signature}\"";
            }
            return authorization;
        }

        public static string Sha256WithLowerHexstr(string content, string charset)
        {
            var hexStr = new StringBuilder();
            var sha = SHA256.Create();
            byte[] data = Encoding.GetEncoding(charset).GetBytes(content);
            byte[] hashData = sha.ComputeHash(data);
            foreach (byte b in hashData)
            {
                hexStr.AppendFormat("{0:x2}", b);
            }
            return hexStr.ToString();
        }

        public static string Sign(string signingStr, string key, string charset)
        {
            byte[] signingBytes = Encoding.GetEncoding(charset).GetBytes(signingStr);
            byte[] keyBytes = Encoding.GetEncoding(charset).GetBytes(key);
            byte[] hashmessage = null;
            using (var hmacsha256 = new HMACSHA256(keyBytes))
            {
                hashmessage = hmacsha256.ComputeHash(signingBytes);
            }
            string signature = Convert.ToBase64String(hashmessage);
            return signature;
        }
    }
}
