using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using DbType = SqlSugar.DbType;

namespace DeviceRepair.DataAccess.Data
{
    public class BaseDa
    {
        #region 属性&字段

        private SqlSugarClient deviceDB;
        private SqlSugarClient deviceLogDB;
        private SqlSugarClient sfcDataDB;
        private SqlSugarClient sfcAddOnDB;

        internal OperationModel OperationInfo;

        private IDictionary<string, string> m_ApiParameters;

        /// <summary>
        /// API输入参数
        /// </summary>
        public IDictionary<string, string> ApiParameters
        {
            get { return m_ApiParameters; }
            private set { m_ApiParameters = value; }
        }

        /// <summary>
        /// 设备主表
        /// </summary>
        public SqlSugarClient devMain
        {
            get
            {
                if (deviceDB == null)
                {
                    SqlConnectionStringBuilder TsDevdb =
                        new SqlConnectionStringBuilder(DeviceRepair.Utils.Config.Configurations.Properties.Conn);
                    TsDevdb.InitialCatalog = "DriveMaintenance";

                    deviceDB = new SqlSugarClient(new ConnectionConfig()
                    {
                        ConnectionString = TsDevdb.ConnectionString,
                        DbType = DbType.SqlServer,
                        InitKeyType = InitKeyType.Attribute,
                        IsAutoCloseConnection = true,
                    });
                }

                return deviceDB;
            }
        }

        /// <summary>
        /// 设备日志
        /// </summary>
        public SqlSugarClient devLog
        {
            get
            {
                if (deviceLogDB == null)
                {
                    SqlConnectionStringBuilder TsDevdb =
                        new SqlConnectionStringBuilder(DeviceRepair.Utils.Config.Configurations.Properties.Conn);
                    TsDevdb.InitialCatalog = "DeviceMaintenanceLog";

                    deviceLogDB = new SqlSugarClient(new ConnectionConfig()
                    {
                        ConnectionString = TsDevdb.ConnectionString,
                        DbType = DbType.SqlServer,
                        InitKeyType = InitKeyType.Attribute,
                        IsAutoCloseConnection = true,
                    });
                }

                return deviceLogDB;
            }
        }

        /// <summary>
        /// SFC 数据表
        /// </summary>
        public SqlSugarClient sfcData
        {
            get
            {
                if (sfcDataDB == null)
                {
                    SqlConnectionStringBuilder TsSFCdb =
                        new SqlConnectionStringBuilder(DeviceRepair.Utils.Config.Configurations.Properties.SfcConn);
                    TsSFCdb.InitialCatalog = "SFCData";

                    sfcDataDB = new SqlSugarClient(new ConnectionConfig()
                    {
                        ConnectionString = TsSFCdb.ConnectionString,
                        DbType = DbType.SqlServer,
                        InitKeyType = InitKeyType.Attribute,
                        IsAutoCloseConnection = true,
                    });
                }

                return sfcDataDB;
            }
        }

        /// <summary>
        /// SFC AddOn 表
        /// </summary>
        public SqlSugarClient sfcAddOn
        {
            get
            {
                if (sfcAddOnDB == null)
                {
                    SqlConnectionStringBuilder TsSFCdb =
                        new SqlConnectionStringBuilder(DeviceRepair.Utils.Config.Configurations.Properties.SfcConn);
                    TsSFCdb.InitialCatalog = "SFCAddOn";

                    sfcAddOnDB = new SqlSugarClient(new ConnectionConfig()
                    {
                        ConnectionString = TsSFCdb.ConnectionString,
                        DbType = DbType.SqlServer,
                        InitKeyType = InitKeyType.Attribute,
                        IsAutoCloseConnection = true,
                    });
                }

                return sfcAddOnDB;
            }
        }

        #endregion

        #region 函数

        public BaseDa()
        {
        }

        public BaseDa(IDictionary<string, string> apiParams)
        {
            m_ApiParameters = apiParams;
            OperationInfo = new OperationModel().InstanceModel(apiParams);
        }

        #endregion

        #region 方法


        /// <summary>
        /// 取字符串参数
        /// </summary>
        /// <param name="Key">键</param>
        /// <param name="Caption">字段标题</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public string GetParamString(string Key, string Caption)
        {
            try
            {
                if (!ApiParameters.ContainsKey(Key))
                {
                    throw new ArgumentException($"参数【{Caption}】不能为空！");
                }

                return (ApiParameters[Key] + "").Trim();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 取整数型参数
        /// </summary>
        /// <param name="Key">键</param>
        /// <param name="Caption">字段标题</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public int GetParamInt(string Key, string Caption)
        {
            try
            {
                if (!ApiParameters.ContainsKey(Key))
                {
                    throw new ArgumentException($"参数【{Caption}】不能为空！");
                }

                int value = 0;
                if (!int.TryParse(ApiParameters[Key], out value))
                {
                    throw new ArgumentException($"参数【{Caption}】传入值转整数型出错！");
                }

                return value;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 取时间类型参数
        /// </summary>
        /// <param name="Key">键</param>
        /// <param name="Caption">字段标题</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public DateTime GetParamDateTime(string Key, string Caption)
        {
            try
            {
                if (!ApiParameters.ContainsKey(Key))
                {
                    throw new ArgumentException($"参数【{Caption}】不能为空！");
                }

                DateTime value;
                if (!DateTime.TryParse(ApiParameters[Key] + "", out value))
                {
                    throw new ArgumentException($"参数【{Caption}】传入值转时间类型出错！");
                }

                return value;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 通用唯一识别码类型参数
        /// </summary>
        /// <param name="Key">键</param>
        /// <param name="Caption">字段标题</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public Guid GetParamGuid(string Key, string Caption)
        {
            try
            {
                if (!ApiParameters.ContainsKey(Key))
                {
                    throw new ArgumentException($"参数【{Caption}】不能为空！");
                }

                Guid value;
                if (!Guid.TryParse(ApiParameters[Key] + "", out value))
                {
                    throw new ArgumentException($"参数【{Caption}】传入值转通用唯一识别码类型出错！");
                }
                return value;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 集合 转 DataTable
        /// </summary>
        /// <param name="varlist"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public DataTable IListToDataTable<T>(IEnumerable<T> varlist)
        {
            DataTable dtReturn = new DataTable();
            PropertyInfo[] oProps = null;

            foreach (T rec in varlist)
            {
                if (oProps == null)
                {
                    oProps = ((Type)rec.GetType()).GetProperties();

                    foreach (PropertyInfo pi in oProps)
                    {
                        Type colType = pi.PropertyType;
                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }

                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                    }
                }

                DataRow dr = dtReturn.NewRow();
                foreach (PropertyInfo pi in oProps)
                {
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
                }

                dtReturn.Rows.Add(dr);
            }

            return (dtReturn);
        }

        /// <summary>
        /// 集合 转 DataTable
        /// </summary>
        /// <param name="varlist"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public DataTable ListToDataTable<T>(List<T> varlist)
        {
            DataTable dtReturn = new DataTable();
            PropertyInfo[] oProps = typeof(T).GetProperties();
            dtReturn.TableName = typeof(T).Name;

            foreach (PropertyInfo pi in oProps)
            {
                Type colType = pi.PropertyType;
                if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                {
                    colType = colType.GetGenericArguments()[0];
                }

                dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
            }

            foreach (T rec in varlist)
            {
                DataRow dr = dtReturn.NewRow();
                foreach (PropertyInfo pi in oProps)
                {
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
                }

                dtReturn.Rows.Add(dr);
            }

            return (dtReturn);
        }

        #endregion
    }
}