using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;

namespace System.Common.Helpers
{
    /// <summary>    
    /// 实体转换辅助类    
    /// </summary>    
    public class ModelConvertHelper<T> where T : new()
    {
        public static IList<T> ConvertToModel(DataTable dt)
        {
            // 定义集合    
            IList<T> ts = new List<T>();

            // 获得此模型的类型   
            Type type = typeof(T);
            string tempName = "";

            foreach (DataRow dr in dt.Rows)
            {
                int i = 0;
                T t = new T();
                // 获得此模型的公共属性      
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    if (i >= dr.ItemArray.Length)
                        break;
                    tempName = pi.Name;  // 检查DataTable是否包含此列    

                    //if (dt.Columns.Contains(tempName))
                    //{
                    // 判断此属性是否有Setter      
                    if (!pi.CanWrite) continue;

                    object value = dr[i];//object value = dr[tempName];

                    if (pi.PropertyType.FullName.Contains(typeof(System.Int64).FullName))
                    { pi.SetValue(t, Convert.ToInt64(value), null); }
                    else if (pi.PropertyType.FullName.Contains(typeof(System.Int32).FullName))
                    { pi.SetValue(t, Convert.ToInt32(value), null); }
                    else if (pi.PropertyType.FullName.Contains(typeof(System.Decimal).FullName))
                    { pi.SetValue(t, Convert.ToDecimal(value), null); }
                    else if (pi.PropertyType.FullName.Contains(typeof(System.DateTime).FullName))
                    {
                        if (value != DBNull.Value && value.ToString() != "")
                            pi.SetValue(t, Convert.ToDateTime(value), null);
                        else
                            pi.SetValue(t, null, null);
                    }
                    else
                    if (value != DBNull.Value)
                        pi.SetValue(t, value, null);
                    i++;
                    //}
                }
                ts.Add(t);
            }
            return ts;
        }
        /// <summary>
        /// 带列名的DataTable 转实体对象
        /// </summary>
        /// <param name="dt">带列名的DataTable</param>
        /// <param name="dirList">第一个参数是实体列名【小写格式】，第二个参数是相对应table的列名</param>
        /// <returns></returns>
        public static IList<T> ConvertToModelByColumns(DataTable dt, Dictionary<string, string> dirList)
        {
            // 定义集合    
            IList<T> ts = new List<T>();

            // 获得此模型的类型   
            Type type = typeof(T);
            string tempName = "";

            foreach (DataRow dr in dt.Rows)
            {
                int i = 0;
                T t = new T();
                // 获得此模型的公共属性      
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    if (i >= dr.ItemArray.Length)
                        break;
                    tempName = pi.Name.ToLower();  // 检查DataTable是否包含此列    
                    if (dirList.ContainsKey(tempName))
                    {
                        // 判断此属性是否有Setter      
                        if (!pi.CanWrite) continue;

                        object value = dr[dirList[tempName]];

                        if (pi.PropertyType.FullName.Contains(typeof(System.Int64).FullName))
                        { pi.SetValue(t, Convert.ToInt64(value), null); }
                        else if (pi.PropertyType.FullName.Contains(typeof(System.Int32).FullName))
                        { pi.SetValue(t, Convert.ToInt32(value), null); }
                        else if (pi.PropertyType.FullName.Contains(typeof(System.Decimal).FullName))
                        { pi.SetValue(t, Convert.ToDecimal(value), null); }
                        else if (pi.PropertyType.FullName.Contains(typeof(System.DateTime).FullName))
                        {
                            if (value != DBNull.Value && value.ToString() != "")
                                pi.SetValue(t, Convert.ToDateTime(value), null);
                            else
                                pi.SetValue(t, null, null);
                        }
                        else
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                        i++;
                    }
                }
                ts.Add(t);
            }
            return ts;
        }

        // **//// <summary>
        /// 转换IList<T>为List<T>      //将IList接口泛型转为List泛型类型
        /// </summary>
        /// <typeparam name="T">指定的集合中泛型的类型</typeparam>
        /// <param name="gbList">需要转换的IList</param>
        /// <returns></returns>
        public static List<T> ConvertIListToList<T>(IList<T> gbList) where T : class   //静态方法，泛型转换，
        {
            if (gbList != null && gbList.Count >= 1)
            {
                List<T> list = new List<T>();
                for (int i = 0; i < gbList.Count; i++)  //将IList中的元素复制到List中
                {
                    T temp = gbList[i] as T;
                    if (temp != null)
                        list.Add(temp);
                }
                return list;
            }
            return null;
        }

        /// <summary>
        /// 把DataTable转换成指定类型的List
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static IList<T> ConvertDataTableToList(DataTable dt)
        {
            // 定义集合    
            IList<T> ts = new List<T>();

            string tempName = "";

            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();
                // 获得此模型的公共属性      
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;  // 检查DataTable是否包含此列    

                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter      
                        if (!pi.CanWrite) continue;

                        object value = dr[tempName];
                        if (value != DBNull.Value)
                            pi.SetValue(t, value, null);
                    }
                }
                ts.Add(t);
            }
            return ts;
        }

        /// <summary>
        /// 把泛型List转换成DataTable
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable ConvertListToDataTable(List<T> list)
        {
            DataTable dt = new DataTable();
            // 获得此模型的公共属性      
            PropertyInfo[] propertys = typeof(T).GetProperties();
            foreach (PropertyInfo pi in propertys)
            {
                // 判断此属性是否有Getter      
                if (!pi.CanRead) continue;

                if (pi.PropertyType.FullName.Contains(typeof(System.DateTime).FullName))
                {
                    dt.Columns.Add(pi.Name, typeof(System.DateTime));
                }
                else if (pi.PropertyType.FullName.Contains(typeof(System.Int64).FullName))
                {
                    dt.Columns.Add(pi.Name, typeof(System.Int64));
                }
                else if (pi.PropertyType.FullName.Contains(typeof(System.Int32).FullName))
                {
                    dt.Columns.Add(pi.Name, typeof(System.Int32));
                }
                else if (pi.PropertyType.FullName.Contains(typeof(System.Decimal).FullName))
                {
                    dt.Columns.Add(pi.Name, typeof(System.Decimal));
                }
                else { dt.Columns.Add(pi.Name, pi.PropertyType); }

            }
            foreach (T item in list)
            {
                propertys = item.GetType().GetProperties();
                DataRow newRow = dt.NewRow();
                foreach (PropertyInfo pi in propertys)
                {
                    if (!pi.CanRead) continue;
                    if (pi.GetValue(item) == DBNull.Value || pi.GetValue(item) == null)
                    {
                        newRow[pi.Name] = DBNull.Value;
                    }
                    else { newRow[pi.Name] = pi.GetValue(item); }
                   
                }
                dt.Rows.Add(newRow);
            }
            return dt;
        }


    }
    public class ModelConvertHelper<T, T1> where T : new() where T1 : new()
    {
        /// <summary>
        /// 实体相同属性快速赋值转换  t2赋值给t1
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns>返回第一个参数</returns>
        public static T ModeToModel(T t1, T1 t2)
        {
            PropertyInfo[] t1pList = typeof(T).GetProperties();
            PropertyInfo[] t2pList = typeof(T1).GetProperties();

            foreach (PropertyInfo t2p in t2pList)
            {
                object t2value = t2p.GetValue(t2);
                foreach (var t1p in t1pList)
                {
                    if (t1p.Name == t2p.Name)
                    {
                        t1p.SetValue(t1, t2value, null);
                        break;
                    }
                }
            }
            return t1;
        }

        /// <summary>
        /// 实体相同属性快速赋值转换  t2赋值给t1   不符合赋值规则的则不进行赋值
        /// </summary>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <returns>返回第一个参数</returns>
        public static T ModeToModelDefault(T t1, T1 t2)
        {
            PropertyInfo[] t1pList = typeof(T).GetProperties();
            PropertyInfo[] t2pList = typeof(T1).GetProperties();

            foreach (PropertyInfo t2p in t2pList)
            {
                object t2value = t2p.GetValue(t2);
                foreach (var t1p in t1pList)
                {
                    if (t1p.Name.ToLower() == t2p.Name.ToLower() || t1p.Name.ToUpper() == "F_" + t2p.Name.ToUpper())
                    {
                        if (t2value == DBNull.Value || t2value == null)
                        {

                        }
                        else if (t1p.PropertyType.FullName.Contains(typeof(System.Int64).FullName) || t1p.PropertyType.FullName.Contains(typeof(System.Int32).FullName))
                        {
                            if (t2value.ObjToInt() > 0)
                                t1p.SetValue(t1, t2value, null);
                        }
                        else if (t1p.PropertyType.FullName.Contains(typeof(System.Decimal).FullName))
                        {
                            t1p.SetValue(t1, t2value, null); 
                        }
                        else if (t1p.PropertyType.FullName.Contains(typeof(System.DateTime).FullName))
                        {
                            if (t2value != DBNull.Value && t2value.ToString() != "")
                                t1p.SetValue(t1, Convert.ToDateTime(t2value), null);
                            else
                                t1p.SetValue(t1, null, null);
                        }
                        else
                        {
                            if (t2value.ToString() != "")
                                t1p.SetValue(t1, t2value, null);
                        }
                        break;
                    }
                }
            }
            return t1;
        }
    }


}
