using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;

namespace GenrateSignature
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            DateTime dt = DateTime.Now;

            Console.WriteLine("Hello World!");
            string datetime = dt.ToUniversalTime().ToString("yyyyMMdd'T'HHmmssZ");
            Console.WriteLine("datetime=" + datetime);
            Random r = new Random();
            int num = r.Next();
            String chargeID = "AmazonPay-Test" + num;
            // Please open your Amazon Pay app got to Scan and Pay and click on Payment code/Barcode to make payment
            String payment_Code = "4062361486160980";
            String result = GenratePayload(datetime, chargeID, payment_Code);

        }

  
        private static string GenratePayload(string datetime, string chargeID, string payment_Code)
        {

            Dictionary<string, string> headers = new Dictionary<string, string>();
            headers.Add("x-amz-algorithm", "AWS4-HMAC-SHA384");
            headers.Add("x-amz-client-id", "A2XMNOQAN8MC64");
            headers.Add("x-amz-date", datetime);
            headers.Add("x-amz-expires", "900");
            headers.Add("x-amz-source", "Browser");
            headers.Add("x-amz-user-agent", "Postman");
            headers.Add("x-amz-user-ip", "192.168.1.10");


            // Please change the Body Paramters as per the API call.
            var body = new Dictionary<string, string>();

            body.Add("intent", "AuthorizeAndCapture");
            body.Add("merchantId", "A2XMNOQAN8MC64");
            body.Add("chargeId", chargeID);
            body.Add("amount", "0.1");
            body.Add("currencyCode", "INR");
            //body.Add("timeoutInSecs", "900");
            body.Add("attributableProgram", "S2SPay");
            body.Add("customerIdValue", payment_Code);
            body.Add("customerIdType", "Barcode");

            var storeDetail = new Dictionary<string, string>();
            storeDetail.Add("storeIdType", "MERCHANT_STORE_ID");
            storeDetail.Add("storeId", "Test_Store_ID_1");


            String storeDetailinString = DictionaryToString(storeDetail);
            String storeDetailinnner = storeDetailinString.Replace(":", "=");
            storeDetailinnner = Utils.UrlEncode(storeDetailinnner);
            storeDetailinnner = storeDetailinnner.Replace("%20%3D%20", "%3D");


            body.Add("storeDetail", storeDetailinnner);


            AmazonPayHelpers.AmazonPaySigningHelper signingHelper = new AmazonPayHelpers.AmazonPaySigningHelper("3gY1vxWnx_L5bzguJLeZ-Mf3eYOsZxBlnYy6tWptDQMhk4fdW0hV0HwuE6QdipQ2", datetime);


            Console.WriteLine("calling signature");

            //Please change the method arguments as per the API
            string signature = signingHelper.GetSignature("POST", "amazonpay.amazon.in/v1/offline/payments/charge", body, headers);
            Console.WriteLine("Signature =" + signature);


            throw new NotImplementedException();
        }

        public static string DictionaryToString(Dictionary<string, string> dictionary)
        {
            string dictionaryString = "{";
            foreach (KeyValuePair<string, string> keyValues in dictionary)
            {
                dictionaryString += keyValues.Key + " : " + keyValues.Value + ", ";
            }
            return dictionaryString.TrimEnd(',', ' ') + "}";
        }

        private static class Utils
        {
            private const string ValidUrlCharacters =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";

            public static string UrlEncode(string data)
            {
                StringBuilder encoded = new StringBuilder();
                foreach (char symbol in Encoding.UTF8.GetBytes(data))
                {
                    if (ValidUrlCharacters.IndexOf(symbol) != -1)
                    {
                        encoded.Append(symbol);
                    }
                    else
                    {
                        encoded.Append("%").Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)symbol));
                    }
                }
                return encoded.ToString();
            }

            public static byte[] Sha384Hash(string value)
            {
                using (SHA384 sha384 = SHA384.Create())
                {
                    byte[] bytes = sha384.ComputeHash(Encoding.UTF8.GetBytes(value));
                    return bytes;
                }
            }



            public static byte[] Hash(string value)
            {
                return new SHA384CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(value));
            }

            public static byte[] GetKeyedHash(string key, string value)
            {
                return GetKeyedHash(Encoding.UTF8.GetBytes(key), value);
            }

            public static byte[] GetKeyedHash(byte[] key, string value)
            {
                KeyedHashAlgorithm mac = new HMACSHA384(key);
                mac.Initialize();
                return mac.ComputeHash(Encoding.UTF8.GetBytes(value));
            }

            public static string ToHex(byte[] data)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    sb.Append(data[i].ToString("x2", CultureInfo.InvariantCulture));
                }
                return sb.ToString();
            }
        }
    }
}