using BlazorBootstrap;
using ClosedXML.Excel;
//using System.Drawing;
using ClosedXML.Excel;
using DevExpress.DataAccess.Native.Web;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using MigraDocCore.DocumentObjectModel;
using Newtonsoft.Json;
using Serialize.Linq.Serializers;
using System.Globalization;
using System.Linq.Expressions;
using System.Net.Http.Headers;
using System.Text;
using tsDocumentos;


namespace GestionPersonalWeb.Models
{
    public class Utilidades
    {
        private static IConfiguration Conf { get; set; }
        public static string RemoveDiacritics(string text)
        {
            var normalizedString = text.Normalize(NormalizationForm.FormD);
            var stringBuilder = new StringBuilder(capacity: normalizedString.Length);

            for (int i = 0; i < normalizedString.Length; i++)
            {
                char c = normalizedString[i];
                var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
                if (unicodeCategory != UnicodeCategory.NonSpacingMark)
                {
                    stringBuilder.Append(c);
                }
            }

            return stringBuilder
                .ToString()
                .Normalize(NormalizationForm.FormC);
        }
        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 string NullDatetoString(string date)
        {
            if (date == "01/01/0001")
            {
                return "";
            }
            else {
                return date;
                    }
        }
        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)
        {
            try
            {
                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);
                }
            }
            catch (Exception ex)
            {
                var mess = ex.ToString();
                return default(T);
            }
        }
        public static async Task<T> NuevoObjeto<T>(HttpClient cliente, String uri, T objeto, List<ToastMessage> mensajes = null)
        {
            try
            {
                // Limpiar propiedades de navegación
                VaciarPropiedadesDeNavegacion(objeto);

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

                if (response.IsSuccessStatusCode)
                {
                    if (mensajes != null)
                    {
                        mensajes.Add(new ToastMessage
                        {
                            Type = ToastType.Success,
                            Message = $"Guardado Correctamente.",
                        });
                    }
                    var resultContent = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<T>(resultContent);
                }
                else
                {
                    if (mensajes != null)
                    {
                        mensajes.Add(new ToastMessage
                        {
                            Type = ToastType.Danger,
                            Message = $"{response}",
                            AutoHide = false
                        });
                    }
                    return default(T);
                }

            }
            catch (Exception ex)
            {
                var mess = ex.ToString();
                if (mensajes != null)
                {
                    mensajes.Add(new ToastMessage
                    {
                        Type = ToastType.Success,
                        Message = $"{mess}",
                        AutoHide = false
                    });
                }
        
                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);
        //    }
        //}
        public static async Task<String> ActualizarObjeto<T>(HttpClient cliente, String uri, T objeto, List<ToastMessage> mensajes = null)
        {
            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);

                    if (mensajes != null)
                    {
                        mensajes.Add(new ToastMessage
                        {
                            Type = ToastType.Success,
                            Message = $"Guardado Correctamente.",
                        });
                    }
                    return "Ok";
                }
                else
                {
                    //Console.WriteLine($"Error al actualizar: {response.StatusCode}, {await response.Content.ReadAsStringAsync()}");
                    //return default(T);

                    if (mensajes != null)
                    {
                        mensajes.Add(new ToastMessage
                        {
                            Type = ToastType.Danger,
                            Message = $"{response}",
                            AutoHide = false
                        });
                    }
                    return $"Error al actualizar: {response.StatusCode}, {await response.Content.ReadAsStringAsync()}";
                }
            }
            catch (Exception ex)
            {
                var mess = ex.ToString();
                return mess;
            }
        }
        public static async Task ExportarExcelEnBrowser<T>(IJSRuntime js, IEnumerable<T> datos, byte[] logoBytes, XLColor headerColor, string nombreFichero)
        {
            using var ms = tsDocumentos.TablaExportador
                .GenerarExcelEnMemoria(datos, logoBytes, headerColor);
            var bytes = ms.ToArray();
            var b64 = Convert.ToBase64String(bytes);
            await js.InvokeVoidAsync("saveAsFile", nombreFichero, b64);
        }
        public static async Task ExportarPdfEnBrowser<T>(IJSRuntime js, IEnumerable<T> datos, byte[] logoBytes, Color headerColor, string nombreFichero)
        {
            using var ms = tsDocumentos.TablaExportador
                .GenerarPdfEnMemoria(datos, logoBytes, headerColor);
            var bytes = ms.ToArray();
            var b64 = Convert.ToBase64String(bytes);
            await js.InvokeVoidAsync("saveAsFile", nombreFichero, b64);
        }
        // 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.");
                    }
                }
            }
        }

        public static string Encriptar(object valor) {
            return tsUtilidades.crypt.FEncS(valor.ToString(),
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*",
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*",
                875421649);
        }
        public static string Desencriptar(object valor) {
            return tsUtilidades.crypt.FEncS(valor.ToString(),
                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*",
                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*",
                    -875421649);
        }

        public static string ListaErroresHtml(IEnumerable<String> lista) {
            var html = "";
            html += "Revise los errores antes de guardar:";
            foreach (string m in lista)
            {
                html += "\n" + m + ". ";
            }
            return html;
        }

        public static T ClonarObjeto<T>(T objeto)
        {
            var json = System.Text.Json.JsonSerializer.Serialize(objeto);
            return System.Text.Json.JsonSerializer.Deserialize<T>(json);
        }

    }

}
