using FspWebApp.Entity.Client;
using Newtonsoft.Json;
using RestSharp;
using System;
using System.Threading.Tasks;

namespace FspWebApp
{
    public class Client
    {
        private static NLog.Logger logger = NLog.LogManager.LoadConfiguration("NLog.config").GetLogger("FspWebApp");

        private static readonly Client instance = new Client();

        public static Client Default => instance;

        public string Token
        { get; set; }

        public async Task<string> GetAuthToken(string authServiceBaseUrl, string userName, string password)
        {
            var client = new RestClient();
            var request = new RestRequest(authServiceBaseUrl, Method.POST);
            request.AddHeader("Content-Type", "application/json");
            request.AddParameter("application/x-www-form-urlencoded",
                String.Format("grant_type=password&username={0}&password={1}", userName, password), ParameterType.RequestBody);

            var tokenResponse = await client.ExecuteTaskAsync<AccessToken>(request);

            if (tokenResponse == null || !tokenResponse.IsSuccessful)
                return string.Empty;
            return "bearer " + tokenResponse.Data.access_token;
        }

        public async Task<string> ChangeFuelPrice(string transactionServiceBaseUrl, string deviceSn, PosItem data)
        {
            var client = new RestClient();
            var request = new RestRequest(transactionServiceBaseUrl, Method.POST);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("Authorization", Token);
            request.AddHeader("DeviceSN", deviceSn);

            request.AddJsonBody(data);
            var response = await client.ExecuteTaskAsync(request);
            logger.Debug("Response: " + response.Content);

            return response.StatusDescription;
        }

        /// <summary>
        /// async call will not block, can use this as `fire and go`.
        /// </summary>
        /// <param name="deviceSerialNumber"></param>
        /// <param name="data"></param>
        /// <param name="callback"></param>
        /// <param name="httpMethod"></param>
        /// <returns></returns>
        public RestRequestAsyncHandle UploadDataAsync(PumpUploadData data,
            Action<IRestResponse, RestRequestAsyncHandle> callback, string deviceServiceUrl)
        {
            var resourceRelativeUrl = "api/DeviceData";
            var client = new RestClient(deviceServiceUrl);

            var request = new RestRequest(resourceRelativeUrl, Method.POST);
            //request.AddHeader("Content-Type", "application/json;charset=utf-8");
            string jsonObj = ConvertFrom(data);
            logger.Debug("Upload device data: " + jsonObj);
            request.AddJsonBody(data);
            return client.ExecuteAsyncPost(request, callback, "POST");//.Execute<Configuration>(request);
        }

        private string ConvertFrom(object localUploadData)
        {
            //var ser = new RestSharp.Serializers.JsonSerializer();

            return JsonConvert.SerializeObject(localUploadData);
        }
    }
}