using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace CNAS_DBSync
{
    public class CnasDataCheck
    {
        public DataTable DtReadyInsert { get; set; }

        public SyncInstrumentItemInfo SyncInstrumentItem { get; set; }

        public string StrTableName { get; set; }

        public List<IllegalCnasData> LstIllegalMsg { get; set; }

        public void CheckData()
        {
            //1.获取数据库的字段类型和长度
            DataTable dtTableType = CnasDataOperationFact.CnasDataOperation().GetCNASTableTypeLenth(StrTableName,SyncInstrumentItem);
            LstIllegalMsg = new List<IllegalCnasData>();
            //2.根据字段类型和长度获取检查条件
            if (dtTableType != null && dtTableType.Rows.Count > 0)
            {
                foreach (DataColumn dc in DtReadyInsert.Columns)
                {
                    string strColumnName = dc.ColumnName;
                    bool bIfNullable = true;
                    DataRow[] rowsType = dtTableType.Select("ColumnName='"+strColumnName+"'");
                    if (rowsType.Length == 1)
                    {
                        string strColumnType = rowsType[0]["DataType"].ToString();
                        switch (strColumnType.ToLower())
                        {
                            case "varchar":
                                int Maxlenth = Convert.ToInt32(rowsType[0]["CharMaxLenth"]);
                                int MaxByteLenth= Convert.ToInt32(rowsType[0]["CharOcterLenth"]);
                                bIfNullable = rowsType[0]["IsNullable"].ToString().ToLower()=="yes"?true:false;
                                foreach (DataRow dr in DtReadyInsert.Rows)
                                {
                                    if (!CheckVarcharData(dr[strColumnName].ToString(), bIfNullable, Maxlenth, MaxByteLenth))
                                        LstIllegalMsg.Add(new IllegalCnasData() { ColumnName = strColumnName, ColumnValue = dr[strColumnName].ToString() });
                                }
                                break;
                            case "bigint":
                                //bIfNullable = Convert.ToBoolean(rowsType[0]["IsNullable"]);
                                //int NumericPrecision = Convert.ToInt32(rowsType[0]["NumericPrecision"]);
                                //int NumericScale = Convert.ToInt32(rowsType[0]["NumericScale"]);
                                
                                break;
                            case "decimal":
                                bIfNullable = rowsType[0]["IsNullable"].ToString().ToLower() == "yes" ? true : false;
                                int NumericPrecision = Convert.ToInt32(rowsType[0]["NumericPrecision"]);
                                int NumericScale = Convert.ToInt32(rowsType[0]["NumericScale"]);

                                foreach (DataRow dr in DtReadyInsert.Rows)
                                {
                                    if (!CheckDecimalData(dr[strColumnName].ToString(), bIfNullable, NumericPrecision, NumericScale))
                                        LstIllegalMsg.Add(new IllegalCnasData() { ColumnName = strColumnName, ColumnValue = dr[strColumnName].ToString() });
                                }
                                break;
                        }
                    }
                }
            }
        }

        private bool CheckVarcharData(string strValue, bool IfNullable, int MaxLenth,int MaxByteLenth)
        {
            if (strValue == null || strValue == "")
                if (!IfNullable)  //如果数据库不允许为空，此处需要检查是否准备插入的数据是空值
                    return false;
                else
                    return true;
            if (Encoding.Default.GetByteCount(strValue) > MaxByteLenth)
                return false;
            return true;
        }

        private bool CheckDecimalData(string strValue, bool IfNullable, int NumericPrecision, int NumericScale)
        {
            if (strValue == null || strValue == "")
                if (!IfNullable)  //如果数据库不允许为空，此处需要检查是否准备插入的数据是空值
                    return false;
                else
                    return true;
            double result=0;
            if (!double.TryParse(strValue, out result))
                return false;
            long ValueInt = (long)(result);
            int ValueDigit = (int)(result % 1);
            if (ValueInt.ToString().Length > NumericPrecision- NumericScale || ValueDigit.ToString().Length > NumericScale)
                return false;
            return true;
        }
    }

    public class IllegalCnasData
    {
        public string ColumnName { get; set; }

        public object ColumnValue { get; set; }
    }

    public class DataFieldAndLenth
    {
        public string FieldName { get; set; }

        public Type FieldType { get; set; }

        public int FieldLenth { get; set; }

        public int FieldDigits{ get; set; }
    }

}
