using Newtonsoft.Json.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using DbType = SqlSugar.DbType;
namespace OpenAuth.App.FormScheme.FormHelpers
{
    public class DBCommonHelper
    {
        /// <summary>
        /// 获取fsql的数据库类型
        /// </summary>
        /// <param name="dbtype">SqlServer,Oracle,MySql,PostgreSQL,Dameng,Kdbndp</param>
        /// <returns></returns>
        public static DbType GetDbType(string dbtype)
        {
            switch (dbtype)
            {
                case "SqlServer":
                    return DbType.SqlServer;
                case "Oracle":
                    return DbType.Oracle;
                case "MySql":
                    return DbType.MySql;
                case "PostgreSQL":
                    return DbType.PostgreSQL;
                case "Dameng":
                    return DbType.Dm;//达梦
                case "Kdbndp":
                    return DbType.Kdbndp;//人大金仓
                case "Sqlite":
                    return DbType.Sqlite;//Sqlite 
                default:
                    return DbType.MySql;
            }
        }

        /// <summary>
        /// 将IDataReader转换为DataTable  
        /// </summary>
        /// <returns>datatable</returns>
        /// <param name="reader">IDataReader</param>
        public static DataTable IDataReaderToDataTable(IDataReader reader)
        {
            using (reader)
            {
                DataTable objDataTable = new DataTable("Table");
                int intFieldCount = reader.FieldCount;
                for (int intCounter = 0; intCounter < intFieldCount; ++intCounter)
                {
                    objDataTable.Columns.Add(reader.GetName(intCounter).ToLower(), reader.GetFieldType(intCounter));
                }
                objDataTable.BeginLoadData();
                object[] objValues = new object[intFieldCount];
                while (reader.Read())
                {
                    reader.GetValues(objValues);
                    objDataTable.LoadDataRow(objValues, true);
                }
                reader.Close();
                reader.Dispose();
                objDataTable.EndLoadData();
                return objDataTable;
            }
        }

        /// <summary>
        /// 将datatable的字段格式化为小写
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DataTable DtColToLow(DataTable dt)
        {
            foreach (DataColumn item in dt.Columns)
            {
                //item.ColumnName = item.ColumnName.ToLower();
                item.ColumnName = item.ColumnName;//不转小写
            }
            return dt;
        }

        /// <summary>
        /// 判断是否为匿名对象
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool CheckIfAnonymousType(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
                && type.IsGenericType && type.Name.Contains("AnonymousType")
                && (type.Name.StartsWith("<>"))
                && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
        }

        ///// <summary>
        ///// 将不是匿名对象转化为字典数据
        ///// </summary>
        ///// <param name="param"></param>
        ///// <returns></returns>
        //public static object ConvertToDic(object param)
        //{
        //    //判断是否匿名，不是匿名就转一下，是就直接加进去
        //    if (param != null && !CheckIfAnonymousType(param.GetType()))
        //    {
        //        return param.ToObject<Dictionary<string, object>>();
        //    }
        //    return param;
        //}
        /// <summary>
        /// 获取c#字段类型
        /// </summary>
        /// <param name="dbtype">数据库类型</param>
        /// <param name="dbType">数据库字段类型</param>
        /// <returns></returns>
        public static string GetCsType(DbType dbtype, string dbType)
        {
            string csType = "string";
            switch (dbType.ToLower())
            {
                case "varchar":
                    csType = "string";
                    break;
                case "varchar2":
                    csType = "string";
                    break;
                case "char":
                case "nchar":
                case "nvarchar":
                case "nvarchar2":
                    csType = "string";
                    break;
                case "text":
                    csType = "string";
                    break;
                case "ntext":
                case "longtext":
                case "clob":
                case "nclog":
                    csType = "text";
                    break;
                case "int2":
                    csType = "int";
                    break;
                case "integer":
                    csType = "int";
                    break;
                case "int4":
                    csType = "int";
                    break;
                case "mediumint":// mysql
                case "year":
                    csType = "int";
                    break;
                case "bigint":
                    csType = "long";
                    break;
                case "smallint":
                    csType = "short";
                    break;
                case "bit":
                    csType = "bool";
                    break;
                case "tinyint":
                    csType = "byte";
                    break;
                case "decimal":
                    csType = "decimal";
                    break;
                case "numeric":
                    csType = "decimal";
                    break;
                case "number":
                    csType = "int";
                    break;
                case "number(8,2)":
                    csType = "double";
                    break;
                case "money":
                case "bool":
                    csType = "bool";
                    break;
                case "smallmoney":
                    csType = "decimal";
                    break;
                case "real":
                case "double":
                    if (dbtype == DbType.MySql)
                    {
                        csType = "double";
                    }
                    else
                    {
                        csType = "float";
                    }
                    break;
                case "float":
                    if (dbtype == DbType.MySql)
                    {
                        csType = "float";
                    }
                    else
                    {
                        csType = "double";
                    }
                    break;
                case "float4":
                    csType = "double";
                    break;
                case "float8":
                    csType = "double";
                    break;
                case "date":
                    csType = "DateTime";
                    break;
                case "datetime":
                    csType = "DateTime";
                    break;
                case "datetime2":
                    csType = "DateTime";
                    break;
                case "smalldatetime":
                    csType = "DateTime";
                    break;
                case "datetimeoffset":
                    csType = "DateTimeOffset";
                    break;
                case "time":
                    csType = "DateTime";
                    break;
                case "timestamp":
                    if (dbtype == DbType.MySql)
                    {
                        csType = "DateTime";

                    }
                    else
                    {
                        csType = "DateTime";
                    }
                    break;
                case "binary":
                case "varbinary":
                case "image":

                case "tinyblob":
                case "blob":
                case "mediumblob":
                case "longblob":
                    csType = "byte[]";
                    break;
                case "uniqueidentifier":
                    csType = "Guid";
                    break;
                case "variant":
                    csType = "Object";
                    break;
                case "timestamp without time zone":
                    csType = "TimeSpan";
                    break;
                // mysql
                case "set":
                case "enum":
                    csType = "Enum";
                    break;
                case "point":
                case "linestring":
                case "polygon":
                case "geometry":
                case "multipoint":
                case "multilinestring":
                case "multipolygon":
                //case "geometrycollection":
                //    csType = "MygisGeometry";
                case "geometrycollection":
                    csType = "string";
                    break;
            }

            return csType;
        }

        public static string GetDbType(DbType dbtype, string dbType, string csType)
        {
            if (!string.IsNullOrEmpty(dbType))
            {
                return dbType;
            }
            if (csType == "text")
            {
                if (DbType.Oracle == dbtype)
                {
                    return "clob";
                }
                else
                {
                    return "text";
                }
            }

            return string.Empty;
        }
    }
}
