using SWRIS.Dtos;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Media.Imaging;

namespace SWRIS.Extensions
{
    public static class TypeExtension
    {
        public static string ToLogString(this Exception ex)
        {
            string result;
            if (ex == null)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("  >>异常消息（Message）：").AppendLine(ex.Message);
                stringBuilder.Append("  >>异常来源（Source）：").AppendLine(ex.Source);
                stringBuilder.Append("  >>异常类型（ExceptionType）：").AppendLine(ex.GetType().ToString());
                stringBuilder.Append("  >>原生异常类型（BaseExceptionType）：").AppendLine(ex.GetBaseException().GetType().ToString());
                stringBuilder.Append("  >>出错的方法签名（TargetSite）：").Append(ex.TargetSite);
                if (ex.Data.Count > 0)
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append("  >>自定义数据（Data）：");
                    StringBuilder stringBuilder2 = new StringBuilder();
                    foreach (object obj in ex.Data)
                    {
                        DictionaryEntry dictionaryEntry = (DictionaryEntry)obj;
                        stringBuilder2.Append(string.Concat(new object[]
                        {
                            "Key：",
                            dictionaryEntry.Key,
                            "，Value：",
                            dictionaryEntry.Value,
                            "; "
                        }));
                    }
                    stringBuilder.Append(stringBuilder2);
                }
                if (!string.IsNullOrEmpty(ex.StackTrace))
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append("  >>堆栈信息（StackTrace）：");
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(ex.StackTrace);
                }
                if (ex.InnerException != null)
                {
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(">>========================== 内部异常（InnerException）==========================");
                    stringBuilder.Append(Environment.NewLine);
                    stringBuilder.Append(ex.InnerException.ToLogString());
                }
                result = stringBuilder.ToString();
            }
            return result;
        }
        public static bool IsInvalid<T>(this IEnumerable<T> source)
        {
            return !source.IsValid<T>();
        }
        public static bool IsValid<T>(this IEnumerable<T> source)
        {
            return source != null && source.Any<T>();
        }
        public static bool IsNullOrEmpty(this string value)
        {
            return string.IsNullOrEmpty(value);
        }

        public static bool IsNullOrEmptyOrWhiteSpace(this string value)
        {
            bool flag = value.IsNullOrEmpty();
            if (!flag)
            {
                flag = value.Trim().IsNullOrEmpty();
            }
            return flag;
        }
        public static byte[] TranslateToBytes(this string hexString)
        {
            try
            {
                if (!Regex.IsMatch(hexString, @"^[0-9A-Fa-f]+H?$", RegexOptions.IgnoreCase))
                    throw new ArgumentException("无效的十六进制格式");

                hexString = hexString.TrimEnd('H', 'h');
                if (hexString.Length != 4)
                    throw new ArgumentException("字符串长度不正确");

                return (GetBigEndianBytes(Convert.ToUInt16(hexString, 16), 2));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"识别码或序列号转化字节数组失败: {ex.Message}");
                return null;
            }
        }
        public static byte[] GetBigEndianBytes(uint value, int byteCount)
        {
            byte[] bytes = new byte[byteCount];
            for (int i = 0; i < byteCount; i++)
            {
                bytes[i] = (byte)(value >> (8 * (byteCount - 1 - i)));
            }
            return bytes;
        }
        /// <summary>
        /// 计算校验和（所有字节相加之和，取8位，溢出不计）
        /// </summary>
        public static byte CalculateChecksum(this byte[] data)
        {
            byte checksum = 0;
            foreach (byte b in data)
            {
                unchecked { checksum += b; }
            }
            return checksum;
        }
        /// <summary>
        /// 计算校验和（所有字节相加之和，取8位，溢出不计）
        /// </summary>
        public static byte CalculateChecksum(this IEnumerable<byte> data)
        {
            byte checksum = 0;
            foreach (byte b in data)
            {
                unchecked { checksum += b; }
            }
            return checksum;
        }

        public static void AddRange<T>(this ICollection<T> @this, IEnumerable<T> values)
        {
            foreach (T item in values)
            {
                @this.Add(item);
            }
        }
        public static BitmapImage ConvertBitmapToBitmapImage(this Bitmap bitmap)
        {
            MemoryStream stream = new MemoryStream();
            bitmap.Save(stream, ImageFormat.Bmp);
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            image.StreamSource = stream;
            image.EndInit();
            return image;
        }
        public static bool? ShowDialog(this Window window, bool isMaskVisible)
        {
            bool? result = null;
            if (window != null)
            {
                if (isMaskVisible)
                {
                    MainWindow mainWindow = Application.Current.MainWindow as MainWindow;
                    mainWindow.IsMaskVisible = true;
                    result = window.ShowDialog();
                    mainWindow.IsMaskVisible = false;
                }
                else
                {
                    result = window.ShowDialog();
                }
            }
            return result;
        }
        public static string GetDescription(this Enum @this)
        {
            return _CacheDescriptions.GetOrAdd(@this, delegate (Enum key)
            {
                Type type = key.GetType();
                FieldInfo field = type.GetField(key.ToString());
                return (field == null) ? key.GetDescriptions(",") : GetDescription(field);
            });
        }
        public static string GetDescriptions(this Enum @this, string separator = ",")
        {
            string[] array = @this.ToString().Split(new char[]
            {
                ','
            });
            string[] array2 = new string[array.Length];
            Type type = @this.GetType();
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo field = type.GetField(array[i].Trim());
                if (!(field == null))
                {
                    array2[i] = GetDescription(field);
                }
            }
            return string.Join(separator, array2);
        }
        public static string GetDefaultValue(this Enum @this)
        {
            return _CacheDefaultValues.GetOrAdd(@this, delegate (Enum key)
            {
                Type type = key.GetType();
                FieldInfo field = type.GetField(key.ToString());
                return (field == null) ? key.GetDefaultValues(",") : GetDefaultValue(field);
            });
        }

        public static string GetDefaultValues(this Enum @this, string separator = ",")
        {
            string[] array = @this.ToString().Split(new char[]
            {
                ','
            });
            string[] array2 = new string[array.Length];
            Type type = @this.GetType();
            for (int i = 0; i < array.Length; i++)
            {
                FieldInfo field = type.GetField(array[i].Trim());
                if (!(field == null))
                {
                    array2[i] = GetDefaultValue(field);
                }
            }
            return string.Join(separator, array2);
        }
        public static ObservableCollection<T> ConvertToObservableCollection<T>(this IEnumerable<T> from)
        {
            ObservableCollection<T> to = new ObservableCollection<T>();
            if (from != null)
            {
                foreach (var f in from)
                {
                    to.Add(f);
                }
            }
            return to;
        }
        public static List<KeyAndValueDto> ToKeyAndDescriptionList(this Type type)
        {
            if (type.IsEnum)
            {
                List<KeyAndValueDto> list = new List<KeyAndValueDto>();
                Array _enumValues = Enum.GetValues(type);
                foreach (Enum value in _enumValues)
                {
                    list.Add(new KeyAndValueDto()
                    {
                        Key = Convert.ToInt32(value),
                        Value = GetDescription(value)
                    });
                }
                return list;
            }
            return null;
        }
        private static string GetDefaultValue(FieldInfo field)
        {
            Attribute customAttribute = Attribute.GetCustomAttribute(field, typeof(DefaultValueAttribute), false);
            return (customAttribute == null) ? string.Empty : ((DefaultValueAttribute)customAttribute).Value.ToString();
        }
        private static string GetDescription(FieldInfo field)
        {
            Attribute customAttribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute), false);
            return (customAttribute == null) ? string.Empty : ((DescriptionAttribute)customAttribute).Description;
        }
        private static readonly ConcurrentDictionary<Enum, string> _CacheDescriptions = new ConcurrentDictionary<Enum, string>();
        private static readonly ConcurrentDictionary<Enum, string> _CacheDefaultValues = new ConcurrentDictionary<Enum, string>();
    }
}

