using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using QRCoder;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace ASHermed.SinoInterface.Tools
{
    /// <summary>
    /// 工具类
    /// </summary>
    public static class Tools
    {
        public static long? ToLong(this string str, long? defaultVal = 0)
        {
            long? retInt = defaultVal;
            try
            {
                long i;
                long.TryParse(str, out i);
                retInt = i;
            }
            catch
            {
            }
            return retInt;
        }
        public static int ToInt(this int? str)
        {
            int retInt = 0;
            try
            {
                if (str != null)
                {
                    retInt = Convert.ToInt32(str);
                }
            }
            catch
            {
            }
            return retInt;
        }
        /// <summary>
        /// 验证非空
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string source)
        {
            if (string.IsNullOrEmpty(source))
                return true;
            return false;
        }

        /// <summary>
        /// 验证邮箱
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsEmail(this string source)
        {
            if (string.IsNullOrEmpty(source))
                return false;
            //Regex r = new Regex("^\\s*([A-Za-z0-9_-]+(\\.\\w+)*@(\\w+\\.)+\\w{2,5})\\s*$");
            
            if (source.Contains("@"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //1.验证用户名和密码：（"^[a-zA-Z]\w{5,15}$"）正确格式："[A-Z][a-z]_[0-9]"组成,并且第一个字必须为字母6 ~16位；

        //2.验证电话号码：（"^(\d{3.4}-)\d{7,8}$"）正确格式：xxx/xxxx-xxxxxxx/xxxxxxxx；

        //3.验证身份证号（15位或18位数字）：（"^\d{15}|\d{18}$"）；

        //4.验证Email地址：("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$")；

        //5.只能输入由数字和26个英文字母组成的字符串：("^[A-Za-z0-9]+$") ;

        //6.整数或者小数：^[0-9]+\.{0,1}[0-9]{0,2}$

        //7.只能输入数字："^[0-9]*$"。

        //8.只能输入n位的数字："^\d{n}$"。

        //9.只能输入至少n位的数字："^\d{n,}$"。

        //10.只能输入m ~n位的数字：。"^\d{m,n}$"

        //11.只能输入零和非零开头的数字："^(0|[1-9][0-9]*)$"。

        //12.只能输入有两位小数的正实数："^[0-9]+(.[0-9]{2})?$"。

        //13.只能输入有1 ~3位小数的正实数："^[0-9]+(.[0-9]{1,3})?$"。

        //14.只能输入非零的正整数："^\+?[1-9][0-9]*$"。

        //15.只能输入非零的负整数："^\-[1-9][]0-9"*$。

        //16.只能输入长度为3的字符："^.{3}$"。

        //17.只能输入由26个英文字母组成的字符串："^[A-Za-z]+$"。

        //18.只能输入由26个大写英文字母组成的字符串："^[A-Z]+$"。

        //19.只能输入由26个小写英文字母组成的字符串："^[a-z]+$"。

        //20.验证是否含有^%&',;=?$\"等字符："[^%&',;=?$\x22]+"。

        //21.只能输入汉字："^[\u4e00-\u9fa5]{0,}$"

        //22.验证URL："^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"。

        //23.验证一年的12个月："^(0?[1-9]|1[0-2])$"正确格式为："01"～"09"和"1"～"12"。

        //24.验证一个月的31天："^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为；"01"～"09"和"1"～"31"。

        /// <summary>
        /// 验证手机号码
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsPhoneNumber(this string source)
        {
            if (string.IsNullOrEmpty(source))
                return true;
            Regex r = new Regex(@"^1[3456789]\d{9}$");

            if (r.IsMatch(source))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static string GetIP(this HttpContext request)
        {
            return request.Connection.RemoteIpAddress.ToString();
        }

        public static bool IsChinese(this string source)
        {
            Regex r = new Regex(@"^[\u4e00-\u9fa5]{0,}$");
            if (r.IsMatch(source))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static int GetAgeByBirth(this DateTime birthDay)
        {
            int age;
            if (DateTime.Now < birthDay)
            {
                return -1;
            }
            int yearNow = DateTime.Now.Year;  //当前年份
            int monthNow = DateTime.Now.Month;  //当前月份
            int dayOfMonthNow = DateTime.Now.Day; //当前日期
            int yearBirth = birthDay.Year;
            int monthBirth = birthDay.Month;
            int dayOfMonthBirth = birthDay.Day;
            age = yearNow - yearBirth;   //计算整岁数
            if (monthNow <= monthBirth)
            {
                if (monthNow == monthBirth)
                {
                    if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
                }
                else
                {
                    age--;//当前月份在生日之前，年龄减一
                }
            }
            return age;
        }

        /// <summary>
        /// Json文本转对象,泛型方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string ToJson<T>(this T type)
        {
            try
            {
                return ToJson(type, Formatting.None);
            }
            catch (Exception ex)
            {
                throw new Exception("TypeExtensions.ToJson: " + ex.Message);
            }
        }

        /// <summary>
        /// Json文本转对象,泛型方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <returns></returns>
        public static string ToJson<T>(this T type, Formatting formatting, JsonSerializerSettings jsonSerializerSettings = null)
        {
            try
            {
                if (jsonSerializerSettings == null)
                {
                    jsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
                }

                return Newtonsoft.Json.JsonConvert.SerializeObject(type, formatting, jsonSerializerSettings);
            }
            catch (Exception ex)
            {
                throw new Exception("TypeExtensions.ToJson: " + ex.Message);
            }
        }


        /// <summary>
        /// 解压Gzip文件，返回字符串
        /// </summary>
        /// <param name="fileName">文件全路径</param>
        /// <returns>字符串</returns>
        public static string ReadGzipFromFile(string fileName)
        {
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (GZipStream decompressedStream = new GZipStream(fileStream, CompressionMode.Decompress))
                {
                    StreamReader reader = new StreamReader(decompressedStream);
                    string result = reader.ReadToEnd();//重点
                    reader.Close();
                    return result;
                }
            }
        }

        /// <summary>
        /// 去除字符串中的表情字符
        /// </summary> 
        /// <param name="sourceString"></param>
        /// <returns></returns>
        public static string RemoveEmoji(this string sourceString)
        {
            var chars = sourceString.Select(itemChar => new
            {
                itemChar,
                bytes = Encoding.UTF32.GetBytes(itemChar.ToString())
            })
                .Where(x => x.bytes[0].ToString() == "253" && x.bytes[1].ToString() == "255")
                .Select(x => x.itemChar);

            return chars.Aggregate(sourceString, (current, itemChar) => current.Replace(itemChar.ToString(), ""));
        }

        /// <summary>
        /// 姓名脱敏
        /// 中文——三字以下：显示最后一个字
        /// 中文——其他字数：显示首尾两个字
        /// 英文：不做处理
        /// 飞书：https://ufqa3nb6yx.feishu.cn/docs/doccnkYwOhb509m4tHh39i5zFpJ
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string Desensitization(this string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                return name;
            }

            return name.IsExistEnglishChar()
                ? name
                : name.HideSensitiveInfo(name.Length > 2 ? 1 : 0, 1);
        }

        /// <summary>
        /// 是否包含英文字符
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsExistEnglishChar(this string str) 
        {
            return Regex.Matches(str, "[a-zA-Z]").Count > 0;
        }

        /// <summary>
        /// 隐藏敏感信息
        /// </summary>
        /// <param name="suorceString">源信息</param>
        /// <param name="left">左边保留的字符数</param>
        /// <param name="right">右边保留的字符数</param>
        /// <param name="basedOnLeft">当长度异常时，是否显示左边 </param>
        /// <returns></returns>
        public static string HideSensitiveInfo(this string suorceString, int left, int right, bool basedOnLeft = true)
        {
            if (string.IsNullOrEmpty(suorceString))
            {
                return "";
            }

            var builder = new StringBuilder();
            var hiddenCharCount = suorceString.Length - left - right;
            if (hiddenCharCount > 0)
            {
                string prefix = suorceString.Substring(0, left), suffix = suorceString.Substring(suorceString.Length - right);
                builder.Append(prefix);
                for (var i = 0; i < hiddenCharCount; i++)
                {
                    builder.Append("*");
                }
                builder.Append(suffix);
            }
            else
            {
                if (basedOnLeft)
                {
                    if (suorceString.Length > left && left > 0)
                    {
                        builder.Append(suorceString.Substring(0, left) + "****");
                    }
                    else
                    {
                        builder.Append(suorceString.Substring(0, 1) + "****");
                    }
                }
                else
                {
                    if (suorceString.Length > right && right > 0)
                    {
                        builder.Append("****" + suorceString.Substring(suorceString.Length - right));
                    }
                    else
                    {
                        builder.Append("****" + suorceString.Substring(suorceString.Length - 1));
                    }
                }
            }
            return builder.ToString();
        }

        //public static string GetQRCodeBmp(string link)
        //{


        //    QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
        //    qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
        //    qrCodeEncoder.QRCodeScale = 4;
        //    qrCodeEncoder.QRCodeVersion = 0;
        //    qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
        //    System.Drawing.Bitmap bmp = qrCodeEncoder.Encode(link);//, Encoding.UTF8
        //    MemoryStream ms = new MemoryStream();
        //    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        //    byte[] arr = new byte[ms.Length];
        //    ms.Position = 0;
        //    ms.Read(arr, 0, (int)ms.Length);
        //    ms.Close();
        //    return Convert.ToBase64String(arr);
        //}


    }
}
