using System.Reflection;
using System.Text;

namespace DataSharing.Share.Dtos
{
    /// <summary>
    /// 
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public abstract class AbstractValidateAttribute : Attribute
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="objValue"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public abstract bool Validate(object objValue, out string strError);
    }

    /// <summary>
    /// 必填验证
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class VRequiredAttribute : AbstractValidateAttribute
    {
        public override bool Validate(object objValue, out string strError)
        {
            strError = "";
            if (objValue == null || string.IsNullOrEmpty(objValue.ToString()))
            {
                strError = "不能为空";
                return false;
            }

            return true;
        }
    }

    /// <summary>
    /// 长度验证
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class VStringLengthAttribute : AbstractValidateAttribute
    {
        private readonly int m_nMin;

        private readonly int m_nMax;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="min"></param>
        /// <param name="max"></param>
        public VStringLengthAttribute(int min, int max)
        {
            m_nMin = min;
            m_nMax = max;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetStrLength(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return 0;
            }

            return Encoding.Default.GetBytes(str).Length;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="objValue"></param>
        /// <param name="strError"></param>
        /// <returns></returns>
        public override bool Validate(object objValue, out string strError)
        {
            strError = "";
            if (objValue == null)
            {
                if (m_nMin != 0)
                {
                    strError = "不能为空";
                    return false;
                }
            }
            else
            {
                int strLength = GetStrLength(objValue.ToString());
                if (strLength < m_nMin || strLength > m_nMax)
                {
                    strError = $"长度不能小于{m_nMin} 也不能大于{m_nMax}";
                    return false;
                }
            }

            return true;
        }
    }

    /// <summary>
    /// 描述
    /// </summary>
    public class MDisplayNameAttribute : Attribute
    {
        private readonly string m_strRemark;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strRemark"></param>
        public MDisplayNameAttribute(string strRemark)
        {
            m_strRemark = strRemark;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public virtual string GetRemark()
        {
            return m_strRemark;
        }
    }

    /// <summary>
    /// 数据验证
    /// </summary>
    public static class AOPExtend
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string Validate<T>(this T t) where T : class, new()
        {
            PropertyInfo[] properties = t.GetType().GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                if (!propertyInfo.IsDefined(typeof(AbstractValidateAttribute), inherit: true))
                {
                    continue;
                }

                object value = propertyInfo.GetValue(t);
                string empty = string.Empty;
                if (propertyInfo.IsDefined(typeof(MDisplayNameAttribute), inherit: true))
                {
                    MDisplayNameAttribute mDisplayNameAttribute = (MDisplayNameAttribute)propertyInfo.GetCustomAttribute(typeof(MDisplayNameAttribute), inherit: true);
                    empty = "『" + mDisplayNameAttribute.GetRemark() + "』";
                }
                else
                {
                    empty = "『" + propertyInfo.Name + "未设置描述』";
                }

                string strError = string.Empty;
                object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(AbstractValidateAttribute), inherit: true);
                for (int j = 0; j < customAttributes.Length; j++)
                {
                    if (!((AbstractValidateAttribute)customAttributes[j]).Validate(value, out strError))
                    {
                        return empty + strError;
                    }
                }
            }

            return "";
        }

    }

}
