using OASystem.Domain.ViewModels.Financial;
using OASystem.Domain.ViewModels.Groups;
using System.Reflection.Metadata;

namespace OASystem.Infrastructure.Tools;

/// <summary>
/// 工具类
/// </summary>
public static class CommonFun
{
    public static string GUID => Guid.NewGuid().ToString("N");
    public static bool IsNull(this string s)
    {
        return string.IsNullOrWhiteSpace(s);
    }
    public static bool NotNull(this string s)
    {
        return !string.IsNullOrWhiteSpace(s);
    }
    public static int GetRandom(int minNum, int maxNum)
    {
        var seed = BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0);
        return new Random(seed).Next(minNum, maxNum);
    }
    public static string GetSerialNumber(string prefix = "")
    {
        return prefix + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GetRandom(1000, 9999).ToString();
    }
    public static string ToJson(this object obj)
    {
        return JsonSerializer.Serialize(obj);
    }
    public static T ToObject<T>(this string json)
    {
        return JsonSerializer.Deserialize<T>(json);
    }
    public static object GetDefaultVal(string typename)
    {
        return typename switch
        {
            "Boolean" => false,
            "DateTime" => default(DateTime),
            "Date" => default(DateTime),
            "Double" => 0.0,
            "Single" => 0f,
            "Int32" => 0,
            "String" => string.Empty,
            "Decimal" => 0m,
            _ => null,
        };
    }
    public static void CoverNull<T>(T model) where T : class
    {
        if (model == null)
        {
            return;
        }
        var typeFromHandle = typeof(T);
        var properties = typeFromHandle.GetProperties();
        var array = properties;
        for (var i = 0; i < array.Length; i++)
        {
            var propertyInfo = array[i];
            if (propertyInfo.GetValue(model, null) == null)
            {
                propertyInfo.SetValue(model, GetDefaultVal(propertyInfo.PropertyType.Name), null);
            }
        }
    }
    public static void CoverNull<T>(List<T> models) where T : class
    {
        if (models.Count == 0)
        {
            return;
        }
        foreach (var model in models)
        {
            CoverNull(model);
        }
    }
    public static bool ToBool(this object thisValue, bool errorvalue = false)
    {
        if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out bool reval))
        {
            return reval;
        }
        return errorvalue;
    }

    #region 文件操作
    public static FileInfo[] GetFiles(string directoryPath)
    {
        if (!IsExistDirectory(directoryPath))
        {
            throw new DirectoryNotFoundException();
        }
        var root = new DirectoryInfo(directoryPath);
        return root.GetFiles();
    }
    public static bool IsExistDirectory(string directoryPath)
    {
        return Directory.Exists(directoryPath);
    }
    public static string ReadFile(string Path)
    {
        string s;
        if (!File.Exists(Path))
            s = "不存在相应的目录";
        else
        {
            var f2 = new StreamReader(Path, Encoding.Default);
            s = f2.ReadToEnd();
            f2.Close();
            f2.Dispose();
        }
        return s;
    }
    public static void FileMove(string OrignFile, string NewFile)
    {
        File.Move(OrignFile, NewFile);
    }
    public static void CreateDir(string dir)
    {
        if (dir.Length == 0) return;
        if (!Directory.Exists(dir))
            Directory.CreateDirectory(dir);
    }
    #endregion

    #region IP
    /// <summary>
    /// 是否为ip
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static bool IsIP(string ip)
    {
        return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
    }
    public static string GetIP(HttpRequest request)
    {
        if (request == null)
        {
            return "";
        }

        var ip = request.Headers["X-Real-IP"].FirstOrDefault();
        if (ip.IsNull())
        {
            ip = request.Headers["X-Forwarded-For"].FirstOrDefault();
        }
        if (ip.IsNull())
        {
            ip = request.HttpContext?.Connection?.RemoteIpAddress?.ToString();
        }
        if (ip.IsNull() || !IsIP(ip))
        {
            ip = "127.0.0.1";
        }

        return ip;
    }
    #endregion

    #region 随机数

    /// <summary>
    /// 根据自定义随机包含的字符获取指定长度的随机字符
    /// </summary>
    /// <param name="length">随机字符长度</param>
    /// <returns>随机字符</returns>
    public static string GetRandomStr(int length)
    {
        string a = "ABCDEFGHJKLMNPQRSTUVWXYZ012356789";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++)
        {
            sb.Append(a[new Random(Guid.NewGuid().GetHashCode()).Next(0, a.Length - 1)]);
        }

        return sb.ToString();
    }

    /// <summary>
    /// 根据自定义随机包含的字符获取指定长度的随机字符
    /// </summary>
    /// <param name="length">随机字符长度</param>
    /// <returns>随机字符</returns>
    public static string GetRandomAllStr(int length)
    {
        string a = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjklmnpqrstuvwxyz012356789";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++)
        {
            sb.Append(a[new Random(Guid.NewGuid().GetHashCode()).Next(0, a.Length - 1)]);
        }

        return sb.ToString();
    }

    #endregion

    #region decimal 截取
    /// <summary>
    /// 
    /// </summary>
    /// <param name="d"></param>
    /// <param name="n"></param>
    /// <returns></returns>
    public static decimal CutDecimalWithN(decimal d, int n)
    {
        string strDecimal = d.ToString();
        int index = strDecimal.IndexOf(".");
        if (index == -1 || strDecimal.Length < index + n + 1)
        {
            strDecimal = string.Format("{0:F" + n + "}", d);
        }
        else
        {
            int length = index;
            if (n != 0)
            {
                length = index + n + 1;
            }
            strDecimal = strDecimal.Substring(0, length);
        }
        return Decimal.Parse(strDecimal);
    }

    public static decimal CutDecimalWithN(decimal? d, int n)
    {
        if (d == null)
        {
            return Decimal.MinValue;
        }
        return CutDecimalWithN(Convert.ToDecimal(d), n);
    }

    #endregion

    #region 团组模块 - 汇率相关存储解析
    /// <summary>
    /// 团组模块 - 汇率相关 To List
    /// </summary>
    /// <param name="rateStr"></param>
    /// <returns></returns>
    public static List<CurrencyInfo> GetCurrencyChinaToList(string? rateStr)
    {
        List<CurrencyInfo> currencyInfos = new List<CurrencyInfo>();

        if (string.IsNullOrEmpty(rateStr)) return currencyInfos;

        if (rateStr.Contains("|"))
        {
            string[] currencyArr = rateStr.Split("|");
            foreach (string currency in currencyArr)
            {
                string[] currency1 = currency.Split(":");
                string[] currency2 = currency1[0].Split("(");

                CurrencyInfo rateInfo = new CurrencyInfo()
                {
                    CurrencyCode = currency2[1].Replace(")", "").TrimEnd(),
                    CurrencyName = currency2[0],
                    Rate = decimal.Parse(currency1[1]),
                };
                currencyInfos.Add(rateInfo);
            }
        }
        return currencyInfos;
    }

    /// <summary>
    /// 团组模块 - 汇率相关存储解析 To String
    /// </summary>
    /// <param name="rates"></param>
    /// <returns></returns>
    public static string  GetCurrencyChinaToString(List<CurrencyInfo> rates)
    {
        
        string rateStr = string.Empty;

        if (rates.Count <= 0) return rateStr;

        foreach (CurrencyInfo rate in rates)
        {
            //存储方式： 美元(USD):6.2350|.......|墨西哥比索(MXN):1.0000
            rateStr += string.Format("{0}({1}):{2}|", rate.CurrencyName, rate.CurrencyCode, rate.Rate);
        }

        if (rateStr.Length > 0)
        {
            rateStr = rateStr.Substring(0, rateStr.Length - 1);
        }

        return rateStr;
    }
    #endregion

    #region 验证身份证号码
    /// <summary>
    /// 正则表达式
    /// 验证身份证号码
    /// </summary>
    /// <param name="idNumber"></param>
    /// <returns></returns>
    public static bool ValidateIdNumber(this string idNumber)
    {
        string pattern = @"^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])\d{3}(\d|X)$";
        Regex regex = new Regex(pattern);
        return regex.IsMatch(idNumber);
    }
    #endregion
}
