using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Common
{
    /// <summary>
    /// 类型帮助类
    /// </summary>
    public static class ConvertHelper
    {
        #region 字符串转换

        /// <summary>
        /// 获取非空字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetString(object obj, string str = "")
        {
            return (obj == null) ? str : obj.ToString();
        }

        /// <summary>
        /// 如果不是有效字符串就变成null
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EmptyAsNull(string str)
        {
            if (!ValidateHelper.IsPlumpStringAfterTrim(str))
            {
                return null;
            }
            return str;
        }
        #endregion

        #region base64
        /// <summary>
        /// 获取base64字符串
        /// </summary>
        public static string GetBase64String(string str, Encoding encoding = null)
        {
            if (encoding == null) { encoding = Encoding.Default; }
            return GetBase64String(encoding.GetBytes(str));
        }

        /// <summary>
        /// 获取base64字符串
        /// </summary>
        public static string GetBase64String(byte[] bs)
        {
            return Convert.ToBase64String(bs);
        }

        /// <summary>
        /// base64字符串转为普通字符串
        /// </summary>
        public static string GetStringFromBase64String(string str, Encoding encoding = null)
        {
            var bs = GetBytesFromBase64String(str);
            return encoding.GetString(bs);
        }
        /// <summary>
        /// base64字符串转为byte[]
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static byte[] GetBytesFromBase64String(string str)
        {
            return Convert.FromBase64String(str);
        }
        #endregion

        #region 数字转换
        /// <summary>
        /// 转换为int类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static int GetInt(object obj, int? deft = default(int))
        {
            if (int.TryParse(GetString(obj), out int res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }
        /// <summary>
        /// 转换为int64类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static Int64 GetInt64(object obj, Int64? deft = default(Int64))
        {
            if (Int64.TryParse(GetString(obj), out var res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }
        /// <summary>
        /// 获取float类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static float GetFloat(object obj, float? deft = default(float))
        {
            if (float.TryParse(GetString(obj), out var res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }
        /// <summary>
        /// 获取long类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static long GetLong(object obj, long? deft = default(long))
        {
            if (long.TryParse(GetString(obj), out var res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }
        /// <summary>
        /// 获取double类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static double GetDouble(object obj, double? deft = default(double))
        {
            if (double.TryParse(GetString(obj), out var res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }
        /// <summary>
        /// 获取decimal类型，常常用于货币
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static decimal GetDecimal(object obj, decimal? deft = default(decimal))
        {
            if (decimal.TryParse(GetString(obj), out var res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }
        #endregion

        #region 日期转换

        /// <summary>
        /// 转换为日期格式
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static DateTime GetDateTime(object obj, DateTime? deft)
        {
            if (DateTime.TryParse(GetString(obj), out var res))
            {
                return res;
            }
            return deft ?? throw new ArgumentException($"{obj}无法转为{res.GetType()}");
        }

        /// <summary>
        /// 转换为日期格式
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DateTime GetDateTime(object obj)
        {
            return GetDateTime(obj, DateTime.Now);
        }

        #endregion


        #region 其他转换
        /// <summary>
        /// 把ilist转换为list
        /// 不返回null
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static List<T> NotNullList<T>(IEnumerable<T> list) => list?.ToList() ?? new List<T>() { };

        [Obsolete]
        public static List<T> NotNullEnumerable<T>(IEnumerable<T> list) => ConvertHelper.NotNullList(list);
        #endregion

        #region 通用转换
        /// <summary>
        /// 通用数据转换
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="deft"></param>
        /// <returns></returns>
        public static T ChangeType<T>(object obj, T deft = default(T))
        {
            try
            {
                var o = Convert.ChangeType(obj, typeof(T));
                if (o is T re)
                {
                    return re;
                }
                //强转
                return (T)o;
            }
            catch
            {
                return deft;
            }
        }
        #endregion

        /// <summary>
        /// 从集合中删除元素
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="value"></param>
        public static void Remove<T>(this IEnumerable<T> collection, T value)
        {
            (collection as List<T>).Remove(value);
        }
    }
}
