using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace GxPress.Common.Tools
{
    public static class StringUtils
    {
        private static string AddressUrl = ConfigHelper.GetValue("ServiceAddress:AddressUrl");
        public static bool EqualsIgnoreCase(string a, string b)
        {
            if (a == b) return true;
            if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b)) return false;

            return a.Equals(b, StringComparison.OrdinalIgnoreCase);
        }
        public static DateTime SqlMinValue { get; } = new DateTime(1754, 1, 1, 0, 0, 0, 0);

        public static DateTime ToDateTime(string dateTimeStr)
        {
            var datetime = SqlMinValue;
            if (!string.IsNullOrEmpty(dateTimeStr))
            {
                if (!DateTime.TryParse(dateTimeStr.Trim(), out datetime))
                {
                    datetime = SqlMinValue;
                }
            }
            if (datetime < SqlMinValue)
            {
                datetime = SqlMinValue;
            }
            return datetime;
        }
        /// <summary>
        /// 移除Emoji
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string RemoveEmoji(string str)
        {
            if (string.IsNullOrWhiteSpace(str))
                return string.Empty;
            foreach (var a in str)
            {
                byte[] bts = Encoding.UTF32.GetBytes(a.ToString());

                if (bts[0].ToString() == "253" && bts[1].ToString() == "255")
                {
                    str = str.Replace(a.ToString(), "");
                }
            }
            return str;
        }
        public static T ToEnum<T>(this string value, T defaultValue) where T : struct
        {
            if (string.IsNullOrEmpty(value))
            {
                return defaultValue;
            }

            return Enum.TryParse<T>(value, true, out var result) ? result : defaultValue;
        }

        public static int ToInt(string value)
        {
            return int.TryParse(value, out var result) ? result : 0;
        }

        public static IEnumerable<string> StringCollectionToStringList(string collection, char split = ',')
        {
            var list = new List<string>();
            if (!string.IsNullOrEmpty(collection))
            {
                var array = collection.Split(split);
                foreach (var s in array)
                {
                    list.Add(s);
                }
            }
            return list;
        }

        public static IEnumerable<int> StringCollectionToIntList(string collection, char split = ',')
        {
            var list = new List<int>();
            if (!string.IsNullOrEmpty(collection))
            {
                var array = collection.Split(split);
                foreach (var s in array)
                {
                    list.Add(Convert.ToInt32(s));
                }
            }
            return list;
        }

        public static string ObjectCollectionToString(IEnumerable<string> collection)
        {
            var builder = new StringBuilder();
            if (collection != null)
            {
                foreach (var obj in collection)
                {
                    builder.Append(obj.Trim()).Append(",");
                }
                if (builder.Length != 0) builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }


        public static string ObjectCollectionToString(IEnumerable<string> collection, int length)
        {
            var builder = new StringBuilder();
            if (collection != null)
            {
                int i = 0;
                foreach (var obj in collection)
                {
                    builder.Append(obj.Trim()).Append(",");
                    if (i >= length)
                        break;
                        i++;
                }
                if (builder.Length != 0) builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }
        public static string ObjectCollectionToString(IEnumerable<string> collection, string charValue)
        {
            if (collection.Count() == 0)
                return string.Empty;
            var builder = new StringBuilder();
            if (collection != null)
            {
                foreach (var obj in collection)
                {
                    if (!string.IsNullOrWhiteSpace(obj))
                        builder.Append(obj.Trim()).Append(charValue);
                }
                if (builder.Length != 0) builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }
        public static string ObjectCollectionToString(IEnumerable<int> collection)
        {
            var builder = new StringBuilder();
            if (collection != null)
            {
                foreach (var obj in collection)
                {
                    builder.Append(obj).Append(",");
                }
                if (builder.Length != 0) builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }

        public static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings
        {
            //ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter>
            {
                new IsoDateTimeConverter {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"}
            }
        };

        public static string JsonSerialize(object obj)
        {
            try
            {
                //var settings = new JsonSerializerSettings
                //{
                //    ContractResolver = new CamelCasePropertyNamesContractResolver()
                //};
                //var timeFormat = new IsoDateTimeConverter {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"};
                //settings.Converters.Add(timeFormat);

                return JsonConvert.SerializeObject(obj, JsonSettings);
            }
            catch
            {
                return string.Empty;
            }
        }

        public static T JsonDeserialize<T>(string json, T defaultValue = default(T))
        {
            try
            {
                //var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
                //var timeFormat = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
                //settings.Converters.Add(timeFormat);

                return JsonConvert.DeserializeObject<T>(json, JsonSettings);
            }
            catch
            {
                return defaultValue;
            }
        }

        public static string GetWebRootPath(string webRootPath)
        {
            if (string.IsNullOrWhiteSpace(webRootPath))
            {
                webRootPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
            }

            return webRootPath;
        }

        public static bool IsGuid(string val)
        {
            return !string.IsNullOrWhiteSpace(val) && Guid.TryParse(val, out _);
        }

        public static string ShortGuid(string guid)
        {
            if (!IsGuid(guid))
            {
                guid = Guid.NewGuid().ToString();
            }
            long i = 1;
            foreach (var b in Guid.Parse(guid).ToByteArray())
            {
                i *= b + 1;
            }
            return $"{i - DateTime.Now.Ticks:x}";
        }

        public static bool IsDomain(string url)
        {
            if (string.IsNullOrEmpty(url)) return false;
            return Uri.IsWellFormedUriString(url, UriKind.Absolute);
        }

        public static string RemoveDomain(string url)
        {
            if (string.IsNullOrEmpty(url)) return string.Empty;
            return IsDomain(url) ? new Uri(url).PathAndQuery : url;
        }

        public static string AddDomain(string url)
        {
            if (string.IsNullOrEmpty(url)) return string.Empty;
            return IsDomain(url) ? url : $"{AddressUrl}" + url;
        }

        public static string AddDomainMin(string url, int width = 50)
        {
            if (string.IsNullOrEmpty(url)) return $"{AddressUrl}/cache/20191123/ff2a342a68fb4c3dbdcdac877b8b3727.png";
            var urlSpl = url.Split('.');
            var imgType = urlSpl[urlSpl.Length - 1];
            var imageName = $"_{width}_{width}.{imgType}";
            url = url.Replace($".{imgType}", imageName);
            url = IsDomain(url) ? url : $"{AddressUrl}" + url;
            return url.Replace("///", "/");
        }

        public static string GetPreviewDocUrl(string url)
        {
            return $"http://ow365.cn/?i=20124&furl={AddDomain(url)}";
        }

        public static int GetDate(DateTime? dateTime)
        {
            return dateTime.HasValue ? ToInt(dateTime.Value.ToString("yyyyMMdd")) : ToInt(DateTime.Now.ToString("yyyyMMdd"));
        }

        public static string GetFlowNo(DateTime? createdDate, int flowId)
        {
            return (createdDate ?? DateTime.Now).ToString("yyyyMMddHHmmss") + flowId.ToString().PadLeft(4, '0');
        }

        /// <summary>
        /// 计算文件大小函数(保留两位小数),Size为字节大小
        /// </summary>
        /// <param name="Size">初始文件大小</param>
        /// <returns></returns>
        public static string CountSize(long Size)
        {
            string m_strSize = "";
            long FactSize = 0;
            FactSize = Size;
            if (FactSize < 1024.00)
                m_strSize = FactSize.ToString("F2") + " Byte";
            else if (FactSize >= 1024.00 && FactSize < 1048576)
                m_strSize = (FactSize / 1024.00).ToString("F2") + " K";
            else if (FactSize >= 1048576 && FactSize < 1073741824)
                m_strSize = (FactSize / 1024.00 / 1024.00).ToString("F2") + " M";
            else if (FactSize >= 1073741824)
                m_strSize = (FactSize / 1024.00 / 1024.00 / 1024.00).ToString("F2") + " G";
            return m_strSize;
        }
    }
}
