using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Enums;
using APT.Infrastructure.Core;
using APT.MS.Domain.ApiModel;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.IServices.EX;
using APT.Utility;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

using APT.Utility;
using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.ApiModel.Platform;
using APT.Infrastructure.Api.Redis;
using System.Configuration;

namespace APT.FM.WebApi.Controllers.Api.FM
{
    [Route("api/FM/UserCCQuery")]
    [APT.Infrastructure.Api.RootOrg]
    public class UserCCQueryController : AuthorizeApiController<T_FM_USER_C_C_QUERY>
    {

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("Entities")]
        public JsonActionResult<IEnumerable<T_FM_USER_C_C_QUERY>> Entities([FromBody] KeywordFilter filter)
        {
            return WitEntities(null, filter);
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        /// 

        [HttpPost, Route("OrderEntities")]
        public JsonActionResult<IEnumerable<T_FM_USER_C_C_QUERY>> OrderEntities([FromBody] KeywordFilter filter)
        {
            return WitOrderEntities(null, filter);
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="pageFilter"></param>
        /// <returns></returns>
        [HttpPost, Route("Paged")]
        public PagedActionResult<T_FM_USER_C_C_QUERY> Paged([FromBody] KeywordPageFilter pageFilter)
        {
            return WitPaged(null, pageFilter);
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="pageFilter"></param>
        /// <returns></returns>
        [HttpPost, Route("OrderPaged")]
        public PagedActionResult<T_FM_USER_C_C_QUERY> OrderPaged([FromBody] KeywordPageFilter pageFilter)
        {
            return WitOrderPaged(null, pageFilter);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet, Route("Delete")]
        public JsonActionResult<bool> Delete(string id)
        {
            return WitDelete(id);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost, Route("Update")]
        public JsonActionResult<bool> Update([FromBody] T_FM_USER_C_C_QUERY entity)
        {
            return WitUpdate(entity);
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [HttpGet, Route("BatchDelete")]
        public JsonActionResult<bool> BatchDelete(string ids)
        {
            return WitBatchDelete(ids);
        }


        /// <summary>
        /// 获得单条实体数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("Get")]
        public JsonActionResult<T_FM_USER_C_C_QUERY> Get([FromBody] KeywordFilter filter)
        {
            return WitEntity(null, filter);
        }

        /// <summary>
        /// 查询实体并获取枚举
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("OrderEntitiesOnEnum")]
        public JsonActionResult<IEnumerable<T_FM_USER_C_C_QUERY>> OrderEntitiesOnEnum([FromBody] KeywordFilter filter)
        {
            return SafeExecute<IEnumerable<T_FM_USER_C_C_QUERY>>(() =>
            {
                var tmps = this.GetOrderEntities<T_FM_USER_C_C_QUERY>(null, filter);
                var list = tmps.ToList();
                if (list != null && list.Any())
                {
                    list.ForEach(t =>
                    {
                        if (t.Nav_Fields != null && t.Nav_Fields.Any())
                        {
                            t.Nav_Fields.Where(t1 => t1.DATA_TYPE == (int)PFDataTypeEnum.枚举 && !string.IsNullOrEmpty(t1.ENUM_NAME)).ForEach(t1 =>
                            {
                                t1.ENUM_NAME = DataHelper.EnumToString(t1.ENUM_NAME);
                            });
                        }
                    });
                }
                return list;
            });
        }


        private void GetDeleteChildGroupId(List<T_FM_USER_C_C_QUERY_GROUP> list, List<Guid> deleteGroupIds)
        {
            var temps = list.Where(t => deleteGroupIds.Contains(t.PARENT_ID ?? Guid.Empty)).ToList();
            temps.ForEach(t =>
            {
                if (!deleteGroupIds.Contains(t.ID))
                    deleteGroupIds.Add(t.ID);
                this.GetDeleteChildGroupId(list, deleteGroupIds);
            });
        }

        private void DoFullUpdate(T_FM_USER_C_C_QUERY entity)
        {
            var fields = entity.Nav_Fields;
            var groups = entity.Nav_Groups;
            entity.Nav_Groups = null;
            entity.Nav_Fields = null;
            if (fields != null && fields.Any())
                fields.ForEach(t => t.USER_C_C_QUERY_ID = entity.ID);
            if (groups != null && groups.Any())
                groups.ForEach(t => t.USER_C_C_QUERY_ID = entity.ID);

            List<Guid> deleteFieldIds = new List<Guid>();
            List<Guid> deleteGroupIds = new List<Guid>();
            var dbEntity = this.GetEntity<T_FM_USER_C_C_QUERY>(entity.ID.ToString(), new string[] { "Nav_Fields", "Nav_Groups" });
            if (dbEntity != null)
            {
                if (dbEntity.Nav_Groups != null)
                {
                    dbEntity.Nav_Groups.ForEach(item =>
                    {
                        var group = groups == null ? null : groups.FirstOrDefault(t => t.ID == item.ID);
                        if (group == null)
                            deleteGroupIds.Add(item.ID);
                        if (group != null)
                        {
                            group.CREATER_ID = item.CREATER_ID;
                            group.CREATE_TIME = item.CREATE_TIME;
                        }
                    });
                    this.GetDeleteChildGroupId(dbEntity.Nav_Groups.ToList(), deleteGroupIds);
                }
                if (dbEntity.Nav_Fields != null)
                {
                    dbEntity.Nav_Fields.ForEach(item =>
                    {
                        var field = fields == null ? null : fields.FirstOrDefault(t => t.ID == item.ID);
                        if (field == null || deleteGroupIds.Any(t => t == item.USER_C_C_QUERY_GROUP_ID))
                            deleteFieldIds.Add(item.ID);
                        if (field != null)
                        {
                            field.CREATER_ID = item.CREATER_ID;
                            field.CREATE_TIME = item.CREATE_TIME;
                        }
                    });
                }
            }

            if (deleteGroupIds != null && deleteGroupIds.Any())
                fields = fields.Where(t => !deleteGroupIds.Contains(t.USER_C_C_QUERY_GROUP_ID ?? Guid.Empty)).ToList();


            List<T_FM_USER_C_C_QUERY> updateList = null;
            if (entity.IS_DEFAULT && (dbEntity == null || !dbEntity.IS_DEFAULT))
            {
                updateList = this.GetEntities<T_FM_USER_C_C_QUERY>(t => t.PAGE_FORM_ID == entity.PAGE_FORM_ID && t.ID != entity.ID, new BaseFilter()).ToList();
                if (updateList != null && updateList.Any())
                {
                    updateList.ForEach(t =>
                    {
                        t.IS_DEFAULT = false;
                    });
                }
            }

            UnifiedCommit(() =>
            {
                this.UpdateEntityNoCommit(entity);
                if (groups != null && groups.Any())
                    this.BantchSaveEntityNoCommit(groups);
                if (fields != null && fields.Any())
                    this.BantchSaveEntityNoCommit(fields);
                if (updateList != null && updateList.Any())
                    this.BantchUpdateEntityNoCommit(updateList);
                if (deleteFieldIds.Any())
                    this.DeleteEntityNoCommit<T_FM_USER_C_C_QUERY_FIELD>(t => deleteFieldIds.Contains(t.ID));
                if (deleteGroupIds.Any())
                    this.DeleteEntityNoCommit<T_FM_USER_C_C_QUERY_GROUP>(t => deleteGroupIds.Contains(t.ID));
            });
        }



        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost, Route("FullUpdate")]
        public JsonActionResult<bool> FullUpdate([FromBody] T_FM_USER_C_C_QUERY entity)
        {
            return SafeExecute<bool>(() =>
            {
                this.DoFullUpdate(entity);
                return true;
            });
        }


        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet, Route("FullDelete")]
        public JsonActionResult<bool> FullDelete(string id)
        {
            return SafeExecute<bool>(() =>
            {
                if (string.IsNullOrEmpty(id)) return false;
                var tmpsIds = this.GetEntities<T_FM_USER_C_C_QUERY_FIELD>(t => t.USER_C_C_QUERY_ID == new Guid(id), new BaseFilter()).
                        Select(t => t.ID).ToList();
                if (tmpsIds != null && tmpsIds.Any())
                    foreach (var item in tmpsIds)
                        this.DeleteEntity<T_FM_USER_C_C_QUERY_FIELD>(item.ToString());
                this.DeleteEntity<T_FM_USER_C_C_QUERY>(id);
                return true;
            });
        }

        /// <summary>
        ///更新是否默认值
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("UpdateIsDefault")]
        public JsonActionResult<bool> UpdateIsDefault([FromBody] KeywordFilter filter)
        {
            return SafeExecute<bool>(() =>
            {
                string id = filter.Keyword;//查询方案ID
                bool isDefault = string.IsNullOrEmpty(filter.Parameter1) ? false : LibUtils.ToBoolean(filter.Parameter1);//是否默认
                if (string.IsNullOrEmpty(id)) return false;
                var query = this.GetEntity<T_FM_USER_C_C_QUERY>(id);
                if (query == null) return false;
                query.IS_DEFAULT = isDefault;

                List<T_FM_USER_C_C_QUERY> updateList = null;
                if (isDefault)
                {
                    updateList = this.GetEntities<T_FM_USER_C_C_QUERY>(t => t.PAGE_FORM_ID == query.PAGE_FORM_ID && t.ID != query.ID, new BaseFilter()).ToList();
                    if (updateList != null && updateList.Any())
                    {
                        updateList.ForEach(t =>
                        {
                            t.IS_DEFAULT = false;
                        });
                    }
                }

                this.UpdateEntity(query);
                if (updateList != null && updateList.Any())
                    this.BantchUpdateEntity(updateList);
                return true;
            });
        }





        /// <summary>
        /// 获取用户查询配置并且查询字段
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("GetQueryFieldByUserQuery")]
        public JsonActionResult<UserCCQueryModel> GetQueryFieldByUserQuery([FromBody] KeywordFilter filter)
        {
            return base.SafeExecute(() =>
            {
                string formIdStr = filter.Keyword;//表单ID;
                string queryId = filter.Parameter1;//用户自定义查询方案ID
                string userId = filter.Parameter2;//用户ID
                string code = filter.Parameter3;//编号
                bool isCopyFromSys = string.IsNullOrEmpty(filter.Parameter4) ? false : LibUtils.ToBoolean(filter.Parameter4);//从系统查询中拷贝
                string copyCCQueryId = filter.Parameter5;//拷贝Id
                UserCCQueryModel model = new UserCCQueryModel();
                if (string.IsNullOrEmpty(formIdStr))
                    throw new Exception("请选择表单ID");
                var redisCode = string.Format(RedisCacheKey.TableUserConfigRedisKey, queryId,filter.GetOrgId());
                bool isRedisConfig = true;
                var redisConfig =APT.Infrastructure.Api.ConfigurationManager.AppSettings["RedisFormConfig"];
                if (!string.IsNullOrEmpty(redisConfig))
                    isRedisConfig = bool.Parse(redisConfig);
                if (isRedisConfig)
                {
                    if (CsRedisManager.KeyExists(redisCode))
                        return CsRedisManager.GetClient().Get<UserCCQueryModel>(redisCode);
                }
                //var baseFilter = new BaseFilter();
                //baseFilter.SelectField = new string[] { "ID", "CODE" };
                //baseFilter.IsNoTranking = true;
                T_PF_FORM form = this.GetEntity<T_PF_FORM>(formIdStr);
                if (form == null)
                    throw new Exception("无效表单");
                var entityOperateService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IEntityOperateService>();
                Dictionary<string, byte> existFields = new Dictionary<string, byte>();

                //Expression<Func<T_PF_FORM_QUERY, bool>> queryExpression = t => t.PAGE_FORM_ID == form.ID;
                var formQuerys = this.GetEntitiesByRedis<T_PF_FORM_QUERY>(null, new BaseFilter(filter.GetOrgId()), form.ID.ToString());
                var formQuery = formQuerys.FirstOrDefault();

                List<T_PF_QUERY> querys = null;
                filter.Sort = "NUM";
                if (formQuery != null)
                {

                    //Expression<Func<T_PF_QUERY, bool>> expression = t => t.PAGE_FORM_QUERY_ID == formQuery.ID;
                    //if (!string.IsNullOrEmpty(code))
                    //    expression = expression.And(t => t.CODE == code);
                    //querys = this.GetEntities<T_PF_QUERY>(expression, new BaseFilter()).ToList();

                    querys = this.GetEntitiesByRedis<T_PF_QUERY>(null, new BaseFilter(filter.GetOrgId()), formQuery.ID.ToString())
                    .ToList();

                    if (!string.IsNullOrEmpty(code))
                        querys = querys.Where(t => t.CODE == code).ToList();

                }
                List<string> expandFields = null;
                if (!string.IsNullOrEmpty(queryId))
                {
                    //var userCCQuery = this.GetEntity<T_FM_USER_C_C_QUERY>(queryId, new string[] { "Nav_Fields", "Nav_Groups" });
                    T_FM_USER_C_C_QUERY userCCQuery = null;
                    userCCQuery = GetCCQueryByRedis(filter, queryId);
                    if (userCCQuery == null)
                    {
                        T_FM_USER_C_C_QUERY copyUserCCQuery = string.IsNullOrEmpty(copyCCQueryId) ? null :
                                GetCCQueryByRedis(filter, copyCCQueryId);

                        userCCQuery = new T_FM_USER_C_C_QUERY();
                        userCCQuery.ID = new Guid(queryId);
                        userCCQuery.ORG_ID = filter.OrgId;
                        if (copyUserCCQuery != null)
                        {
                            CopyUtils.CopyObject(userCCQuery, copyUserCCQuery);
                            userCCQuery.TITLE = userCCQuery.TITLE + "-副本";
                        }
                        userCCQuery.PAGE_FORM_ID = form.ID;

                        //拷贝系统查询方案
                        if (isCopyFromSys && querys != null && querys.Any())
                        {
                            userCCQuery.Nav_Fields = new List<T_FM_USER_C_C_QUERY_FIELD>();
                            querys.ForEach(t =>
                            {
                                T_FM_USER_C_C_QUERY_FIELD field = new T_FM_USER_C_C_QUERY_FIELD();
                                field.ORG_ID = userCCQuery.ORG_ID;
                                field.USER_C_C_QUERY_ID = userCCQuery.ID;
                                CopyUtils.CopyObject(field, t);
                                if (!string.IsNullOrEmpty(code))
                                    field.CODE = code;
                                field.IS_SYS_QUERY_FIELD = true;
                                userCCQuery.Nav_Fields.Add(field);
                            });
                        }
                        Dictionary<Guid, Guid?> groupIdRelations = new Dictionary<Guid, Guid?>();//拷贝分组ID和新增分组ID对应关系列表

                        //拷贝已有的自定义查询方案 分组
                        if (copyUserCCQuery != null && copyUserCCQuery.Nav_Groups != null && copyUserCCQuery.Nav_Groups.Any())
                        {
                            var tmps = copyUserCCQuery.Nav_Groups.OrderBy(t => t.NUM).ToList();
                            userCCQuery.Nav_Groups = new List<T_FM_USER_C_C_QUERY_GROUP>();
                            this.GetGroupByList(tmps, null, null, userCCQuery, code, groupIdRelations);
                        }

                        //拷贝已有的自定义查询方案 字段
                        if (copyUserCCQuery != null && copyUserCCQuery.Nav_Fields != null && copyUserCCQuery.Nav_Fields.Any())
                        {
                            var tmps = copyUserCCQuery.Nav_Fields.OrderBy(t => t.NUM).ToList();
                            userCCQuery.Nav_Fields = new List<T_FM_USER_C_C_QUERY_FIELD>();
                            tmps.ForEach(t =>
                            {
                                Guid? currGroupId = null;
                                if (t.USER_C_C_QUERY_GROUP_ID != null)
                                {
                                    if (!groupIdRelations.TryGetValue(t.USER_C_C_QUERY_GROUP_ID.Value, out currGroupId))
                                        return;
                                }
                                T_FM_USER_C_C_QUERY_FIELD field = new T_FM_USER_C_C_QUERY_FIELD();
                                field.ORG_ID = userCCQuery.ORG_ID;
                                CopyUtils.CopyObject(field, t);
                                field.USER_C_C_QUERY_ID = userCCQuery.ID;
                                field.USER_C_C_QUERY_GROUP_ID = currGroupId;
                                if (!string.IsNullOrEmpty(code))
                                    field.CODE = code;
                                userCCQuery.Nav_Fields.Add(field);

                            });
                        }

                        var customConfigs = this.GetEntitiesByRedis<T_FM_USER_CUSTOM_CONFIG>(null, new BaseFilter(filter.GetOrgId()), userId);
                        var customConfig = customConfigs.FirstOrDefault();

                        if (customConfig == null)
                        {
                            customConfig = new T_FM_USER_CUSTOM_CONFIG();
                            customConfig.ORG_ID = filter.OrgId;
                            customConfig.USER_ID = new Guid(userId);
                            this.AddEntity(customConfig);
                        }
                        userCCQuery.USER_CUSTOM_CONFIG_ID = customConfig.ID;
                    }

                    model.Nav_UserCCQuery = userCCQuery;
                    if (userCCQuery != null && userCCQuery.Nav_Fields != null && userCCQuery.Nav_Fields.Any())
                    {
                        Dictionary<string, byte> expandFieldDic = new Dictionary<string, byte>();
                        model.Nav_UserCCQuery.Nav_Fields.ForEach(t =>
                        {
                            if (t.IS_SYS_QUERY_FIELD || !string.IsNullOrEmpty(t.QUERY_NAME)) return;
                            var tmps = t.QUERY_NAME.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                            if (tmps.Count >= 1)
                            {
                                tmps.RemoveAt(tmps.Count - 1);
                                var expand = string.Join(".", tmps);
                                if (!expandFieldDic.ContainsKey(expand))
                                    expandFieldDic.Add(expand, 0);
                            }
                        });
                        expandFields = expandFieldDic.Keys.ToList();
                    }
                }

                var fields = entityOperateService.GetEntityFieldsByQueryFormId(form.ID, code, string.Empty, string.Empty, expandFields, filter);
                if (fields != null && fields.Any())
                    fields.ForEach(t => model.Nav_Fields.Add(t));
                CsRedisManager.GetClient().Set(redisCode, model);
                return model;
            });
        }

        private T_FM_USER_C_C_QUERY GetCCQueryByRedis(KeywordFilter filter, string queryId)
        {
            T_FM_USER_C_C_QUERY userCCQuery = this.GetEntityByRedis<T_FM_USER_C_C_QUERY>(queryId, filter.GetOrgId());
            if (userCCQuery != null)
            {
                var fileds = this.GetEntitiesByRedis<T_FM_USER_C_C_QUERY_FIELD>(filter)
                    .Where(t => t.USER_C_C_QUERY_ID == userCCQuery.ID).ToList();
                userCCQuery.Nav_Fields = fileds;

                var groups = this.GetEntitiesByRedis<T_FM_USER_C_C_QUERY_GROUP>(filter)
                    .Where(t => t.USER_C_C_QUERY_ID == userCCQuery.ID).ToList();
                userCCQuery.Nav_Groups = groups;
            }

            return userCCQuery;
        }

        private void GetGroupByList(List<T_FM_USER_C_C_QUERY_GROUP> list, Guid? parentId, Guid? currParentId, T_FM_USER_C_C_QUERY userCCQuery, string code, Dictionary<Guid, Guid?> groupIdRelations)
        {
            var tmps = list == null ? null : list.Where(t => t.PARENT_ID == parentId).ToList();
            if (tmps == null || !tmps.Any()) return;
            tmps.ForEach(t =>
            {
                T_FM_USER_C_C_QUERY_GROUP group = new T_FM_USER_C_C_QUERY_GROUP();
                group.ORG_ID = userCCQuery.ORG_ID;
                CopyUtils.CopyObject(group, t);
                group.USER_C_C_QUERY_ID = userCCQuery.ID;
                if (!string.IsNullOrEmpty(code))
                    group.CODE = code;
                group.PARENT_ID = currParentId;
                userCCQuery.Nav_Groups.Add(group);
                groupIdRelations[t.ID] = group.ID;
                GetGroupByList(list, t.ID, group.ID, userCCQuery, code, groupIdRelations);
            });
        }





        /// <summary>
        /// 获取查询字段
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [HttpPost, Route("GetQueryFields")]
        public JsonActionResult<IEnumerable<EntityFieldByQueryFieldModel>> GetQueryFields([FromBody] KeywordFilter filter)
        {
            return SafeExecute<IEnumerable<EntityFieldByQueryFieldModel>>(() =>
            {
                string formIdStr = filter.Keyword;//表单ID;
                string curFieldName = filter.Parameter1;//当前字段名称
                string tableName = filter.Parameter2;//表名
                string lablePrefix = filter.Parameter3;//显示名称前缀
                var entityOperateService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IEntityOperateService>();
                return entityOperateService.GetEntityFieldsByTableName(tableName, curFieldName, lablePrefix, null);
            });
        }



        /// <summary>
        /// 保存查询字段默认值
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [HttpPost, Route("SaveQueryFieldDefaultValue")]
        public JsonActionResult<bool> SaveQueryFieldDefaultValue([FromBody] T_FM_USER_C_C_QUERY entity)
        {
            return SafeExecute<bool>(() =>
            {
                var dbEntity = this.GetEntity<T_FM_USER_C_C_QUERY>(entity.ID.ToString());
                dbEntity.Nav_Groups = entity.Nav_Groups;
                dbEntity.Nav_Fields = entity.Nav_Fields;
                this.DoFullUpdate(dbEntity);
                return true;
            });
        }



    }
}
