using ComputerShopContracts.ViewModels;
using ComputerShopDatabaseImplement.Models;
using ComputerShopDataModels.Models;
using Newtonsoft.Json;
using System.Data;
using System.Net.Http.Headers;
using System.Text;

namespace ComputerShopImplementerApp
{
	public class APIUser
	{
		private static readonly HttpClient _user = new HttpClient { Timeout = TimeSpan.FromMinutes(10) };

        public static UserViewModel? User { get; set; } = null;

        public static void Connect(IConfiguration configuration)
        {
            _user.BaseAddress = new Uri(configuration["IPAddress"]);
            _user.DefaultRequestHeaders.Accept.Clear();
            _user.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }

        public static T? GetRequest<T>(string requestUrl)
        {
            var response = _user.GetAsync(requestUrl);
            var result = response.Result.Content.ReadAsStringAsync().Result;
            if (response.Result.IsSuccessStatusCode)
            {
    //            var settings = new JsonSerializerSettings
    //            {
    //                TypeNameHandling = TypeNameHandling.All
				//};

				//return JsonConvert.DeserializeObject<T>(result, settings);
				return JsonConvert.DeserializeObject<T>(result);
			}
            else
            {
                throw new Exception(result);
            }
        }

		public static async Task<T?> GetRequestAsync<T>(string requestUrl)
		{
			var response = await _user.GetAsync(requestUrl);
			var result = await response.Content.ReadAsStringAsync();
			if (response.IsSuccessStatusCode)
			{
				return JsonConvert.DeserializeObject<T>(result);
			}
			else
			{
				throw new Exception(result);
			}
		}

		public static async Task<T?> GetRequestShipmentAsync<T>(string requestUrl)
		{
			var response = await _user.GetAsync(requestUrl);
			var result = await response.Content.ReadAsStringAsync();
			if (response.IsSuccessStatusCode)
			{
				var settings = new JsonSerializerSettings
				{
					Converters = new List<JsonConverter> { new OrderConverter() }
				};

				return JsonConvert.DeserializeObject<T>(result, settings);
			}
			else
			{
				throw new Exception(result);
			}
		}

		public static async Task<T?> GetRequestRequestAsync<T>(string requestUrl)
		{
			var response = await _user.GetAsync(requestUrl);
			var result = await response.Content.ReadAsStringAsync();
			if (response.IsSuccessStatusCode)
			{
				var settings = new JsonSerializerSettings
				{
					Converters = new List<JsonConverter> { new RequestConverter(), new AssemblyConverter() }
				};

				return JsonConvert.DeserializeObject<T>(result, settings);
			}
			else
			{
				throw new Exception(result);
			}
		}

		public static void PostRequest<T>(string requestUrl, T model)
        {
            var json = JsonConvert.SerializeObject(model);
            var data = new StringContent(json, Encoding.UTF8, "application/json");

            var response = _user.PostAsync(requestUrl, data);

            var result = response.Result.Content.ReadAsStringAsync().Result;
            if (!response.Result.IsSuccessStatusCode)
            {
                throw new Exception(result);
            }
        }

		public static async Task PostRequestAsync<T>(string requestUrl, T model)
		{
			var json = JsonConvert.SerializeObject(model);
			var data = new StringContent(json, Encoding.UTF8, "application/json");

			var response = await _user.PostAsync(requestUrl, data);

			var result = await response.Content.ReadAsStringAsync();
			if (!response.IsSuccessStatusCode)
			{
				throw new Exception(result);
			}
		}
	}

	public class OrderConverter : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(IOrderModel);
			//return true;
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			return serializer.Deserialize<Order>(reader);
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			serializer.Serialize(writer, value);
		}
	}

	public class RequestConverter : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(IRequestModel);
			//return true;
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			return serializer.Deserialize<Request>(reader);
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			serializer.Serialize(writer, value);
		}
	}

	public class AssemblyConverter : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(IAssemblyModel);
			//return true;
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			return serializer.Deserialize<Assembly>(reader);
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			serializer.Serialize(writer, value);
		}
	}
}