using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace P2MSampleApp
{
    public class P2MaddStore

    {
     

        public static Dictionary<string, object> P2MaddStoreParams()
        {
            Dictionary<string, object> addstoreparameters = new Dictionary<string, object>();
            addstoreparameters.Add("displayName", "Prachi");
            addstoreparameters.Add("merchantCategoryCode", "8350");

            //merchantID will be shared for the prod account. The below one is just for test
            addstoreparameters.Add("merchantStoreId", "470000095359490");
            addstoreparameters.Add("mobileNumber", "8860836382");
            addstoreparameters.Add("merchantId", "A2XMNOQAN8MC64");
            long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();
          

            //store id has to be passed based on the store from where the transaction is happening.
            Dictionary<string, string> storeAddressDetails = new Dictionary<String, String>();
            storeAddressDetails.Add("addressLine1", "addressLine1");
            storeAddressDetails.Add("addressLine2", "addressLine2");
            storeAddressDetails.Add("city", "CHENNAI");
            storeAddressDetails.Add("postalCode", "600089");
            storeAddressDetails.Add("state", "MAH");

           
            //convert the map to string for generating right canonical request
            String storeAddressDetailsString = DictionaryToString(storeAddressDetails);
            Console.WriteLine(value: "storeAddressDetailsString=" + storeAddressDetailsString);

            addstoreparameters.Add("storeAddress", storeAddressDetailsString);
            
            return addstoreparameters;
        }


        public static string GetCanonicalRequest(string httpMethod, string url, Dictionary<string, object> payload, Dictionary<string, object> headers)
        {
            Dictionary<string, object> body = payload;
            var canonicalRequest = new StringBuilder();

            canonicalRequest.AppendFormat("{0}\n", httpMethod);
            canonicalRequest.AppendFormat("{0}\n", url);
            canonicalRequest.AppendFormat("{0}\n", "");
            canonicalRequest.AppendFormat("{0}\n",formatParameters(headers));
            canonicalRequest.AppendFormat("{0}", formatParameters(payload));

            Console.WriteLine(canonicalRequest.ToString());
                return canonicalRequest.ToString();
            }


        private static String formatParameters(Dictionary<string, object> parameters) {

            var formattedParams = new StringBuilder();
            Dictionary<string, object> body = parameters;

            IOrderedEnumerable<KeyValuePair<string, object>> orderedParams = body.OrderBy(key => key.Key);
            foreach (KeyValuePair<string, object> data in orderedParams)
            {

                formattedParams.AppendFormat("{0}={1}&", Uri.EscapeDataString(data.Key), Uri.EscapeDataString(data.Value.ToString()));
            }

            if (formattedParams.Length > 0)
            {
                formattedParams.Remove(formattedParams.Length - 1, 1);
            }

            return formattedParams.ToString();

        }
    public static string StringToSign(Dictionary<string,object> payload, Dictionary<string, object> header, string httpMethod,string apiURL)
    {
            Dictionary<string, object> body = payload;
            Dictionary<string, object> headerParam = header;
            string timestamp = headerParam["x-amz-date"].ToString();
            var dateFromstamp = timestamp.Split('T')[0];


            Console.WriteLine(value: "datetime=" + dateFromstamp);

            string stringtosign = "AWS4-HMAC-SHA384" + "\n" +
                                    timestamp + "\n" +
                                    dateFromstamp+ "/eu-west-1/AmazonPay/aws4_request" + "\n" +
                                    getHashedCR(GetCanonicalRequest(httpMethod,apiURL,payload,header));

            return stringtosign;

        }

        private static string getHashedCR(string canonicalRequest)
        {
            string hasedcanoincalRequest = HexEncode(Hash(ToBytes(canonicalRequest)));
            return hasedcanoincalRequest;
        }


        private static byte[] ToBytes(string str)
        {
            return Encoding.UTF8.GetBytes(str.ToCharArray());
        }

        private static string HexEncode(byte[] bytes)
        {
            return BitConverter.ToString(bytes).Replace("-", string.Empty).ToLowerInvariant();
        }


        private static byte[] Hash(byte[] bytes)
        {
            return SHA384.Create().ComputeHash(bytes);
        }

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



        public static Dictionary<string, object> P2Mheaders()
        {

            long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            var datestamp = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(milliseconds.ToString())).UtcDateTime.ToString("yyyyMMddTHHmmssZ");


            Dictionary<string, object> headersParams = new Dictionary<string, object>();

            headersParams.Add("x-amz-client-id", "A2XMNOQAN8MC64");
            headersParams.Add("x-amz-source", "Browser");
            headersParams.Add("x-amz-user-ip", "198.184.0.0");
            headersParams.Add("x-amz-user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
            headersParams.Add("x-amz-algorithm", "AWS4-HMAC-SHA384");
            headersParams.Add("x-amz-date", datestamp);
            headersParams.Add("x-amz-expires", "900");



            return headersParams;

        }


    }

   
}
