using BPA.KitChen.GroupMeal.Core.Common;
using BPA.KitChen.GroupMeal.Core.Common.Const;
using BPA.KitChen.GroupMeal.Core.Entity.Base;
using Furion;
using Furion.DatabaseAccessor;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BPA.KitChen.GroupMeal.SqlSugar
{
    public class SqlSugarDb
    {
        public static SqlSugarScope Db { get; set; }

        public static SqlSugarScope SqlSugarScope(ConnectionConfig configConnection)
        {
            //全局过滤

            Db = new SqlSugarScope(configConnection, db =>
            {
                //全局过滤
                TableFilterItem(db);
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql);

                    //sql 执行前
                };
                db.Aop.OnLogExecuted = (sql, pars) =>
                {
                    //sql 执行后
                };
                db.Aop.OnError = ex =>
                {
                    //sql 异常
                };
            });

            return Db;
        }

        #region 全局过滤器及配置
        /// <summary>
        /// 全局过滤
        /// </summary>
        private static void TableFilterItem(SqlSugarClient db)
        {

            //添加默认值
            DataExecuting(db);

            //// 配置租户过滤器
            //var tenantId = App.User?.FindFirst(ClaimConst.GroupId)?.Value;
            //db.QueryFilter.AddTableFilter<IBaseGroupIdEntity>(u => u.GroupId == tenantId);

            //db.QueryFilter.AddTableFilter<IBaseOPEntity>(u => u.IsDeleted ==0);
            var types = Assembly.Load("BPA.KitChen.GroupMeal.Core").GetTypes()
                .Where(x => x.GetCustomAttribute<SugarTable>() != null);

            foreach (var entityType in types)
            {

                if (entityType.GetProperty("GroupId") != null)//判断实体类中包含属性
                {
                    var groupId = string.IsNullOrWhiteSpace(CurrentUser.TenantId)
                        ? App.User?.FindFirst(ClaimConst.GroupId)?.Value
                        : CurrentUser.TenantId;
                    //构建动态Lambda
                    var lambda = DynamicExpressionParser.ParseLambda
                    (new[] { Expression.Parameter(entityType, "it") },
                        typeof(bool), $"{nameof(IBaseGroupIdEntity.GroupId)} ==  @0",
                        groupId);
                    db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                }

                if (entityType.GetProperty("IsDeleted") != null) //判断实体类中包含属性
                {
                    //构建动态Lambda
                    var lambda = DynamicExpressionParser.ParseLambda
                    (new[] { Expression.Parameter(entityType, "it") },
                        typeof(bool), $"{nameof(IBaseOPEntity.IsDeleted)} ==  @0",
                        0);
                    db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
                }

            }


            //var types = Assembly.Load("BPA.KitChen.GroupMeal.Core").GetTypes()
            //    .Where(x => x.Namespace != null
            //                && x.GetCustomAttribute<SugarTable>() != null
            //                && x.Namespace.Contains("BPA.KitChen.GroupMeal.Core.Entity"));

            //foreach (var entityType in types)
            //{
            //    if (entityType.GetProperty("GroupId") != null)//判断实体类中包含属性
            //    {
            //        //构建动态Lambda
            //        var lambda = DynamicExpressionParser.ParseLambda
            //        (new[] { Expression.Parameter(entityType, "it") },
            //            typeof(bool), $"{nameof(ITenantIdFilter.GroupId)} ==  @0",
            //            CurrentUser.GroupId);
            //        db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
            //    }

            //    if (entityType.GetProperty("IsDelete") != null) //判断实体类中包含属性
            //    {
            //        //构建动态Lambda
            //        var lambda = DynamicExpressionParser.ParseLambda
            //        (new[] { Expression.Parameter(entityType, "it") },
            //            typeof(bool), $"{nameof(IDeletedFilter.IsDelete)} ==  @0",
            //            false);
            //        db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda, true)); //将Lambda传入过滤器
            //    }

            //}

        }

        /// <summary>
        /// 附默认值
        /// </summary>
        /// <param name="db"></param>
        private static void DataExecuting(SqlSugarClient db)
        {
            //全局字段赋值
            db.Aop.DataExecuting = (oldValue, entityInfo) =>
            {
                InsertByObject(entityInfo);
                UpdateByObject(oldValue, entityInfo);
            };

        }
        /// <summary>
        ///插入数据时附默认值
        /// </summary>
        /// <param name="entityInfo"></param>
        private static void InsertByObject(DataFilterModel entityInfo)
        {
            if (entityInfo.OperationType != DataFilterType.InsertByObject) return;
            switch (entityInfo.PropertyName)
            {
                case "CreateAt":
                    entityInfo.SetValue(DateTime.Now);
                    break;
                case "CreateBy":
                    entityInfo.SetValue(CurrentUser.Account);
                    break;
                case "GroupId":
                    entityInfo.SetValue(CurrentUser.TenantId);
                    break;
            }
        }

        /// <summary>
        /// 修改数据时附默认值
        /// </summary>
        /// <param name="oldValue"></param>
        /// <param name="entityInfo"></param>
        private static void UpdateByObject(object oldValue, DataFilterModel entityInfo)
        {
            if (entityInfo.OperationType != DataFilterType.UpdateByObject) return;

            switch (entityInfo.PropertyName)
            {
                case "UpdateAt":
                    entityInfo.SetValue(DateTime.Now);
                    break;
                case "UpdateBy":
                    entityInfo.SetValue(CurrentUser.Account);
                    break;
            }

            //if (entityInfo.PropertyName == "IsDelete" && (bool)oldValue)
            //{
            //    switch (entityInfo.PropertyName)
            //    {
            //        case "DeleteAt":
            //            entityInfo.SetValue(DateTime.Now);
            //            break;
            //        case "DeleteBy":
            //            entityInfo.SetValue(CurrentUser.Account);
            //            break;
            //    }
            //}
            //else
            //{

            //}

        }
        #endregion
    }
}
