using System.Net.Http.Headers;
using Newtonsoft.Json;
using System.Linq.Expressions;
using Serialize.Linq.Serializers;
using System.Text;


namespace GestionaDenunciasAN.Models
{
    public class Utilidades
    {









        private static IConfiguration Conf { get; set; }
        public static string urlSwagger()
        {
            Conf = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
            string swagger = Conf.GetSection("SwaggerCC").Value;
            return swagger;
        }
        public static string urlSwagger2()
        {
            Conf = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
            string swagger = Conf.GetSection("SwaggerVB").Value;
            return swagger;
        }

        public static HttpClient ObtenerCliente(String token, IHttpClientFactory clientFactory)
        {
            var client = clientFactory.CreateClient();
            client.BaseAddress = new Uri(Utilidades.urlSwagger());
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            return client;
        }

        public static async Task<T> ObtenerObjeto<T>(HttpClient cliente, String uri)
        {
            var response = await cliente.GetAsync(uri);

            if (response.IsSuccessStatusCode)
            {
                var resultContent = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<T>(resultContent);
            }
            else
            {
                return default(T);
            }
        }
        public static async Task<T> ObtenerObjeto<T>(HttpClient cliente, String uri, Expression filtro)
        {
            var serializer = new ExpressionSerializer(new Serialize.Linq.Serializers.JsonSerializer());
            var serializedExpression = serializer.SerializeText(filtro);

            var jsonContent = JsonConvert.SerializeObject(new { Expression = serializedExpression });
            var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
            var response = await cliente.PostAsync(uri, content);
            if (response.IsSuccessStatusCode)
            {
                var resultContent = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<T>(resultContent);
            }
            else
            {
                return default(T);
            }
        }

        public static async Task<T> NuevoObjeto<T>(HttpClient cliente, String uri, T objeto)
        {
            try
            {
                // Limpiar propiedades de navegación
                VaciarPropiedadesDeNavegacion(objeto);

                var response = await cliente.PostAsJsonAsync(uri, objeto);

                if (response.IsSuccessStatusCode)
                {
                    var resultContent = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<T>(resultContent);
                }
                else
                {
                    return default(T);
                }
            }
            catch (Exception ex)
            {
                var mess = ex.ToString();
                return default(T);
            }

        }
        public static async Task<T> ActualizarObjeto<T>(HttpClient cliente, String uri, T objeto)
        {
            try
            {
                // Limpiar propiedades de navegación
                VaciarPropiedadesDeNavegacion(objeto);

                // Realizar la solicitud PUT
                var response = await cliente.PutAsJsonAsync(uri, objeto);

                if (response.IsSuccessStatusCode)
                {
                    var resultContent = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<T>(resultContent);
                }
                else
                {
                    Console.WriteLine($"Error al actualizar: {response.StatusCode}, {await response.Content.ReadAsStringAsync()}");
                    return default(T);
                }
            }
            catch (Exception ex)
            {
                var mess = ex.ToString();
                return default(T);
            }
        }

        // Método para limpiar las propiedades de navegación
        private static void VaciarPropiedadesDeNavegacion<T>(T objeto)
        {
            // Obtener todas las propiedades del objeto
            var propiedades = typeof(T).GetProperties();

            foreach (var propiedad in propiedades)
            {
                // Verificar si la propiedad es de tipo de navegación
                if (propiedad.PropertyType.IsClass && propiedad.PropertyType != typeof(string))
                {
                    // Vaciar la propiedad estableciéndola en null
                    if (propiedad.CanWrite)
                    {
                        propiedad.SetValue(objeto, null);
                        Console.WriteLine($"Propiedad de navegación '{propiedad.Name}' vaciada.");
                    }
                }
            }
        }

    }
}
