using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using static BaroSeeSDK.BaroSeeService;

namespace BaroSeeSDK
{
    internal class ApiCaller
    {
        private string scheme = "Bearer";
        private string token = "";
        public ApiCaller(string token)
        {
            this.token = token;
        }

        public static T Execute<T>( ApiEntry entry, object data, ErrorHandler[] errorHanders = null, string contentType = "application/json", bool keepContext = false)
        {
            ApiCaller caller = new ApiCaller(null);
            return caller.Execute<T>(entry.Method, entry.Link, data, errorHanders, contentType);
        }

        public static T Execute<T>(string token, ApiEntry entry, object data, ErrorHandler[] errorHanders = null, string contentType = "application/json", bool keepContext = false)
        {
            ApiCaller caller = new ApiCaller(token);                                    
            return caller.Execute<T>(entry.Method, entry.Link, data, errorHanders, contentType);
        }

        public T Execute<T>(HttpMethod method, string url, object data, ErrorHandler[] errorHanders = null, string contentType = "application/json", bool keepContext = false)
        {
            HttpResponseMessage response = ExecuteAsync(method, url, data, contentType).Result;
            try
            {
                T result = default(T);                
                if (response.IsSuccessStatusCode)
                {
                    string json = response.Content.ReadAsStringAsync().Result;
                    result = new JavaScriptSerializer().Deserialize<T>(json);
                }
                return result;
            }catch(Exception ex)
            {
                if (errorHanders != null)
                    foreach (var handler in errorHanders) handler.Invoke("ApiCaller", response.StatusCode, response.Content.ToString());
            }
            return default(T);
        }
        
        public async Task<HttpResponseMessage> ExecuteAsync(HttpMethod method, string url, object data = null, string contentType = "application/json", bool keepContext = false)
        {
            HttpClient client = new HttpClient();
            var requestMessage = new HttpRequestMessage(method, url);
            
            if (!string.IsNullOrEmpty(token))
                requestMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(scheme, token);
           
            HttpContent content = null;
            if (data != null)
            {
                if (contentType == "application/json")
                {
                    var json = new JavaScriptSerializer().Serialize(data);
                    content = new StringContent(json);
                    content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                    requestMessage.Content = content;
                }else
                if (contentType == "application/x-www-form-urlencoded")
                {
                    content = new FormUrlEncodedContent((IEnumerable<KeyValuePair<string, string>>) data);
                    content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
                    requestMessage.Content = content;
                }
            }            
            return await client.SendAsync(requestMessage).ConfigureAwait(keepContext);                                           
        }
       
    }
}
