using System;
using System.Data.Entity;
using System.Data.Entity.Core;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CK.SCP.Models.AppBoxEntity;
using CK.SCP.Models.Enums;
using CK.SCP.Models.UniApiEntity;
using CK.SCP.Utils;
using ChangKeTec.Wms.Models.Wms;
using System.ComponentModel;

namespace CK.SCP.Models
{
    public class LogModel : INotifyPropertyChanged
    {
        public string LogTime { get; set; }
        public string LogMessage { get; set; }
        public string TaskState { get; set; }
        public string TableName { get; set; }
        public string TaskId { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotityPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public static class EntitiesFactory
    {
        static EntitiesFactory()
        {
            Database.SetInitializer<ScpEntities>(null);
            Database.SetInitializer<WmsEntities>(null);
            Database.SetInitializer<UniApiEntities>(null);
            Database.SetInitializer<DataCenterContext>(null);
            Database.SetInitializer<ExchangeCenterContext>(null);
        }

        public static ScpEntities CreateScpInstance()
        {
            try
            {
                //            var strConn = setting == null ? GetEfConnectionString("Wms") : GetEfConnectionString(setting);

                var strConn = GetEfConnectionString(GlobalConfig.ScpDatabase);
                var db = new ScpEntities(strConn);
              
                return db;
            }
            catch (SqlException ex)
            {
                throw new Exception($"ϵͳ�޷����ӵ����ݿ�:{GlobalConfig.ScpDatabase}���������õķ�����,���ݿ�,�û������������Ϣ�Ƿ���ȷ��" + Environment.NewLine + ex);
            }

        }

        public static UniApiEntities CreateUniApiInstance()
        {
            try
            {
                //            var strConn = setting == null ? GetEfConnectionString("UniApi") : GetEfConnectionString(setting);
                var strConn = GetEfConnectionString(GlobalConfig.UniApiDatabase);
                var db = new UniApiEntities(strConn);
                return db;
            }
            catch (SqlException ex)
            {
                throw new Exception($"ϵͳ�޷����ӵ����ݿ�:{GlobalConfig.UniApiDatabase}���������õķ�����,���ݿ�,�û������������Ϣ�Ƿ���ȷ��" + Environment.NewLine + ex);
            }
        }

        public static AppBoxContext CreateAppBoxInstance()
        {
            try
            {
                //            var strConn = setting == null ? GetEfConnectionString("UniApi") : GetEfConnectionString(setting);
                var strConn = GetEfConnectionString(GlobalConfig.AppBoxDatabase);
                var db = new AppBoxContext(strConn);
                return db;
            }
            catch (SqlException ex)
            {
                throw new Exception($"ϵͳ�޷����ӵ����ݿ�:{GlobalConfig.AppBoxDatabase}���������õķ�����,���ݿ�,�û������������Ϣ�Ƿ���ȷ��" + Environment.NewLine + ex);
            }
        }

        public static WmsEntities CreateWmsInstance()
        {
            try
            {
                //            var strConn = setting == null ? GetEfConnectionString("Wms") : GetEfConnectionString(setting);

                var strConn = GetEfConnectionString(GlobalConfig.WmsDatabase);
                var db = new WmsEntities(strConn);
                return db;
            }
            catch (SqlException ex)
            {
                throw new Exception($"ϵͳ�޷����ӵ����ݿ�:{GlobalConfig.WmsDatabase}���������õķ�����,���ݿ�,�û������������Ϣ�Ƿ���ȷ��" + Environment.NewLine + ex);
            }

        }
        public static DataCenterContext CreateDataCenterInstance()
        {
            var dbSetting = GlobalConfig.DataCenterDB;
            try
            {
                DataCenterContext db;
                var strConn = GetEfConnectionString(dbSetting);
                db = new DataCenterContext(strConn);

                return db;
            }
            catch (SqlException ex)
            {
                throw new Exception($"ϵͳ�޷����ӵ����ݿ�:{dbSetting}���������õķ�����,���ݿ�,�û������������Ϣ�Ƿ���ȷ��{Environment.NewLine}{ex}");
            }
        }

        public static ExchangeCenterContext CreateExchangeCenterInstance()
        {
            var dbSetting = GlobalConfig.ExchangeCenterDB;
            try
            {
                ExchangeCenterContext db;
                var strConn = GetEfConnectionString(dbSetting);
                db = new ExchangeCenterContext(strConn);
                return db;
            }
            catch (SqlException ex)
            {
                throw new Exception($"ϵͳ�޷����ӵ����ݿ�:{dbSetting}���������õķ�����,���ݿ�,�û������������Ϣ�Ƿ���ȷ��{Environment.NewLine}{ex}");
            }
        }

        public static string GetEfConnectionString(DbSetting dbSetting)
        {
            var sbConn = new StringBuilder();

            if (string.IsNullOrEmpty(dbSetting.����))
            {
                throw new Exception("�����ļ���������");
            }
            switch (dbSetting.���ݿ�����)
            {
                case "SQLServer":
                    sbConn.Append($"Data source ={dbSetting.��������ַ}");
                    sbConn.Append(dbSetting.�˿� == "0" ? ";" : $",{dbSetting.�˿�};");
                    sbConn.Append($"Initial catalog = {dbSetting.���ݿ�����};");
                    sbConn.Append($"User id = {dbSetting.�û���};");
                    sbConn.Append($"Password = {EncryptHelper.Decrypt(dbSetting.����)};");
                    sbConn.Append("MultipleActiveResultSets = True;");
                    sbConn.Append("persist security info = True;");
                    sbConn.Append("App = EntityFramework;");
                    break;
                case "MySql":
                    sbConn.Append($"server ={dbSetting.��������ַ};");
                    sbConn.Append($"port ={dbSetting.�˿�};");
                    sbConn.Append($"database = {dbSetting.���ݿ�����};");
                    sbConn.Append($"user id = {dbSetting.�û���};");
                    sbConn.Append($"password = {EncryptHelper.Decrypt(dbSetting.����)};");
                    sbConn.Append("persistsecurityinfo =True;");
                    break;
            }
            //            LogHelper.Write(sbConn.ToString());
            return sbConn.ToString();
        }

        public static void SaveDb(DbContext db)
        {
            try
            {
                db.SaveChanges();
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)//����ʵ����֤�쳣
            {
                var sb = new StringBuilder();

                foreach (var error in dbEx.EntityValidationErrors.ToList())
                {

                    error.ValidationErrors.ToList().ForEach(i =>
                    {
                        sb.AppendFormat("����{0}���ֶΣ�{1}����Ϣ��{2}\r\n", error.Entry.Entity.GetType().Name, i.PropertyName, i.ErrorMessage);
                    });
                }
                throw new ScpException(ResultCode.DbEntityValidationException, sb.ToString(), "�ֶ���֤ʧ��" + sb.ToString());
            }
            catch (OptimisticConcurrencyException ex)//������ͻ�쳣
            {
                
                throw new ScpException(ResultCode.Exception, "9999", ex.ToString());
            }
            catch (ScpException ex)
            {
                

                if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UpdateException))
                {
                    var inner = (UpdateException)ex.InnerException;

                    
                    throw new ScpException(ResultCode.Exception, "0000", ex.ToString());
                }
                else
                {
                    if (ex.InnerException != null) throw ex.InnerException;
                }
            }
        }

    }
}