using System.Data;
using System.Data.Common;
namespace ThingsGateway.SqlSugar
{
    public class SugarParameter : DbParameter
    {
        public bool IsRefCursor { get; set; }
        public bool IsClob { get; set; }
        public bool IsNClob { get; set; }
        public bool IsNvarchar2 { get; set; }
        public SugarParameter(string name, object value)
        {
            this.Value = value;
            this.ParameterName = name;
            if (value != null)
            {
                SettingDataType(value.GetType());
            }
        }
        public SugarParameter(string name, object value, Type type)
        {
            this.Value = value;
            this.ParameterName = name;
            SettingDataType(type);
        }
        public SugarParameter(string name, object value, Type type, ParameterDirection direction)
        {
            this.Value = value;
            this.ParameterName = name;
            this.Direction = direction;
            SettingDataType(type);
        }
        public SugarParameter(string name, object value, Type type, ParameterDirection direction, int size)
        {
            this.Value = value;
            this.ParameterName = name;
            this.Direction = direction;
            this.Size = size;
            SettingDataType(type);
        }


        public SugarParameter(string name, object value, System.Data.DbType type)
        {
            this.Value = value;
            this.ParameterName = name;
            this.DbType = type;
        }
        public SugarParameter(string name, DataTable value, string SqlServerTypeName)
        {
            this.Value = value;
            this.ParameterName = name;
            this.TypeName = SqlServerTypeName;
        }
        public SugarParameter(string name, object value, System.Data.DbType type, ParameterDirection direction)
        {
            this.Value = value;
            this.ParameterName = name;
            this.Direction = direction;
            this.DbType = type;
        }
        public SugarParameter(string name, object value, System.Data.DbType type, ParameterDirection direction, int size)
        {
            this.Value = value;
            this.ParameterName = name;
            this.Direction = direction;
            this.Size = size;
            this.DbType = type;
        }

        private void SettingDataType(Type type)
        {
            if (type == UtilConstants.ByteArrayType)
            {
                this.DbType = System.Data.DbType.Binary;
            }
            else if (type == UtilConstants.GuidType)
            {
                this.DbType = System.Data.DbType.Guid;
            }
            else if (type == UtilConstants.IntType)
            {
                this.DbType = System.Data.DbType.Int32;
            }
            else if (type == UtilConstants.ShortType)
            {
                this.DbType = System.Data.DbType.Int16;
            }
            else if (type == UtilConstants.LongType)
            {
                this.DbType = System.Data.DbType.Int64;
            }
            else if (type == UtilConstants.DateType)
            {
                this.DbType = System.Data.DbType.DateTime;
            }
            else if (type == UtilConstants.DobType)
            {
                this.DbType = System.Data.DbType.Double;
            }
            else if (type == UtilConstants.DecType)
            {
                this.DbType = System.Data.DbType.Decimal;
            }
            else if (type == UtilConstants.ByteType)
            {
                this.DbType = System.Data.DbType.Byte;
            }
            else if (type == UtilConstants.SByteType)
            {
                this.DbType = System.Data.DbType.SByte;
            }
            else if (type == UtilConstants.FloatType)
            {
                this.DbType = System.Data.DbType.Single;
            }
            else if (type == UtilConstants.BoolType)
            {
                this.DbType = System.Data.DbType.Boolean;
            }
            else if (type == UtilConstants.StringType)
            {
                this.DbType = System.Data.DbType.String;
            }
            else if (type == UtilConstants.DateTimeOffsetType)
            {
                this.DbType = System.Data.DbType.DateTimeOffset;
            }
            else if (type == UtilConstants.TimeSpanType)
            {
                this.DbType = System.Data.DbType.Time;
            }
            else if (type?.Name == "Geometry")
            {
                this.DbType = System.Data.DbType.Object;
            }
            else if (type?.Namespace == "Kdbndp.LegacyPostgis")
            {
                this.DbType = System.Data.DbType.Object;
            }
            else if (type?.Namespace == "NetTopologySuite.Geometries")
            {
                this.DbType = System.Data.DbType.Object;
            }
            else if (type?.IsEnum() == true)
            {
                this.DbType = System.Data.DbType.Int64;
                if (Value != null)
                {
                    this.Value = Convert.ToInt64(Value);
                }
            }
            else if (type == UtilConstants.UIntType)
            {
                this.DbType = System.Data.DbType.UInt32;
            }
            else if (type == UtilConstants.ULongType)
            {
                this.DbType = System.Data.DbType.UInt64;
            }
            else if (type == UtilConstants.UShortType)
            {
                this.DbType = System.Data.DbType.UInt16;
            }
            else if (type == UtilConstants.ShortType)
            {
                this.DbType = System.Data.DbType.UInt16;
            }
            else if (type?.Name == "TimeOnly")
            {
                this.DbType = System.Data.DbType.Time;
                this.Value = UtilMethods.TimeOnlyToTimeSpan(this.Value);
            }
            else if (type?.Name == "DateOnly")
            {
                this.DbType = System.Data.DbType.Date;
                this.Value = Convert.ToDateTime(UtilMethods.DateOnlyToDateTime(this.Value));
            }
            else if (type?.FullName == "Newtonsoft.Json.Linq.JObject" || type?.FullName == "Newtonsoft.Json.Linq.JArray" || type?.FullName == "Newtonsoft.Json.Linq.JValue")
            {
                this.Value = this.Value == null ? default(string) : this.Value.ObjToString();
            }

        }
        public SugarParameter(string name, object value, bool isOutput)
        {
            this.Value = value;
            this.ParameterName = name;
            if (isOutput)
            {
                this.Direction = ParameterDirection.Output;
            }
        }
        public override System.Data.DbType DbType
        {
            get; set;
        }

        public override ParameterDirection Direction
        {
            get; set;
        }

        public override bool IsNullable
        {
            get; set;
        }

        public override string ParameterName
        {
            get; set;
        }

        public override byte Scale
        {
            get; set;
        }

        public int _Size;

        public override int Size
        {
            get
            {
                if (_Size == 0 && Value != null)
                {
                    var isByteArray = Value.GetType() == UtilConstants.ByteArrayType;
                    if (isByteArray)
                        _Size = -1;
                    else
                    {
                        var length = Value.ToString().Length;
                        _Size = length < 4000 ? 4000 : -1;

                    }
                }
                if (_Size == 0)
                    _Size = 4000;
                return _Size;
            }
            set
            {
                _Size = value;
            }
        }

        public override string SourceColumn
        {
            get; set;
        }

        public override bool SourceColumnNullMapping
        {
            get; set;
        }
        public string UdtTypeName
        {
            get;
            set;
        }

        public override object Value
        {
            get; set;
        }

        public Dictionary<string, object> TempDate
        {
            get; set;
        }

        /// <summary>
        /// 如果类库是.NET 4.5请删除该属性
        /// If the SqlSugar library is.NET 4.5, delete the property
        /// </summary>
        public override DataRowVersion SourceVersion
        {
            get; set;
        }

        public override void ResetDbType()
        {
            this.DbType = System.Data.DbType.String;
        }


        public string TypeName { get; set; }
        public bool IsJson { get; set; }
        public bool IsArray { get; set; }
        public object CustomDbType { get; set; }
    }
}
