using APT.BaseData.Domain.ApiModel.FM;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Entities.BD;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.Entities.NW;
using APT.BaseData.Domain.Entities.PF;
using APT.BaseData.Domain.Enums;
using APT.Infrastructure.Core;
using APT.Utility;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace APT.NW.WebApi.Controllers.Api
{
    [Route("api/NW/EnterpriseRole")]
    public class EnterpriseRoleController : AuthorizeApiController<T_FM_ORGANIZATION>
    {
        [HttpPost, Route("Update")]
        public JsonActionResult<bool> Update([FromBody] T_FM_ORGANIZATION tenant)
        {
            return SafeExecute<bool>(() =>
            {
                #region 授权数据
                var orgFilter = new BaseFilter();
                orgFilter.IgnoreOrgRule = true;
                var permOPMenu = this.GetEntities<T_NW_ROLE_MENU>(x => x.ENTERPRISE_ID == tenant.ID, orgFilter).ToList();//企业权限
                var permPFMenu = this.GetEntities<T_PF_MENU>(x => x.ORG_ID == tenant.ID, orgFilter).ToList();//企业菜单
                var permPFForm = this.GetEntities<T_PF_FORM>(x => x.ORG_ID == tenant.ID, orgFilter).ToList();//企业表单

                var deletePermOPMenu = new List<Guid>();
                var deletePermPFMenu = new List<T_PF_MENU>();
                List<Guid> dicCheckKeys = new List<Guid>();

                var saveDataPerm = new List<T_NW_ROLE_DATA_PERM>();
                var deleteDataPerm = new List<Guid>();
                #endregion            
                #region 增加权限
                var savePermOPMenu = new List<T_NW_ROLE_MENU>();
                var savePermPFMenu = new List<T_PF_MENU>();
                //var savePermPFForm = new List<T_PF_FORM>();

                var saveParamItems = new List<T_PF_PARAM_ITEM>();
                var addParamItems = new List<T_PF_PARAM_ITEM>();
                var saveParamSchemes = new List<T_PF_PARAM_SCHEME>();
                var addParamSchemes = new List<T_PF_PARAM_SCHEME>();
                var saveParamSchemeDetails = new List<T_PF_PARAM_SCHEME_DETAIL>();
                var addParamSchemeDetails = new List<T_PF_PARAM_SCHEME_DETAIL>();

                var addCodeRules = new List<T_PF_CODE_RULE>();
                var addSyncTasks = new List<T_FM_SYNC_TASK>();
                var saveVersions = new List<T_PF_VERSION_MANAGE>();

             
                List<T_FM_ENUM_TYPE> addEnumType = new List<T_FM_ENUM_TYPE>();
                List<T_FM_ENUM> addEnum = new List<T_FM_ENUM>();
                List<T_BD_PICTURE> addPicture = new List<T_BD_PICTURE>();
                List<T_PF_DATA_FREQUENCY> addDataFrequency = new List<T_PF_DATA_FREQUENCY>();
                List<T_FM_ENUM_ITEM> addEnumItem = new List<T_FM_ENUM_ITEM>();


                var saveUser = new List<T_FM_USER>();
                var saveRole = new List<T_FM_ROLE>();
                var saveUserBelongRole = new List<T_FM_USER_BELONG_ROLE>();
                #endregion
                Dictionary<string, object> relationMenu = new Dictionary<string, object>();//id.pid
                Dictionary<string, string> newRelationMenu = new Dictionary<string, string>();//id.newid
                Dictionary<Guid, Guid> MenuFormRelation = new Dictionary<Guid, Guid>();//id.newid
                Dictionary<Guid, Guid> newItems = new Dictionary<Guid, Guid>();//id.newid
                Dictionary<Guid, Guid> newSchemes = new Dictionary<Guid, Guid>();//id.newid
                Dictionary<Guid, Guid> newSchemeDetails = new Dictionary<Guid, Guid>();//id.newid
                Dictionary<Guid, Guid> newTablePanels = new Dictionary<Guid, Guid>();//id.newid
                Dictionary<Guid, Guid> newCodeRules = new Dictionary<Guid, Guid>();//id.newid
                Dictionary<Guid, Guid> newEditPanels = new Dictionary<Guid, Guid>();
                var dicMenu = new Dictionary<Guid, object>();
                #region OPT信息                    
                var orgs = this.GetEntities<T_FM_ORGANIZATION>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, orgFilter);
                var root = new T_FM_ORGANIZATION();
                if (tenant.PARENT_ID == null)
                {
                    root = orgs.Where(x => x.ID == tenant.ID).FirstOrDefault();
                }
                else
                {
                    var org = orgs.Where(x => x.ID == tenant.PARENT_ID).FirstOrDefault();
                    root = selectRoot(orgs, org);
                }
                var filter = new BaseFilter(root.ID);//当前企业根企业菜单,表单等
                filter.Level = -1;
                filter.IsParentData = true;
                #region  表单配置信息
                //var optForms = this.GetEntities<T_PF_FORM>(x => x.ORG_ID == filter.OrgId, filter);
                var optMenusTree = this.GetTreeOrderEntities<T_PF_MENU>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用 && x.ORG_ID == filter.OrgId, filter);
                var optMenus = this.GetEntities<T_PF_MENU>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用 && x.ORG_ID == filter.OrgId, filter);

                List<T_PF_PARAM_ITEM> srcParamItems = null;
                List<T_PF_PARAM_SCHEME> srcParamSchemes = null;
                List<T_PF_PARAM_SCHEME_DETAIL> srcParamSchemeDetails = null;
                List<T_PF_VERSION_MANAGE> srcVersionManages = null;
                List<T_PF_CODE_RULE> srcCodeRules = null;
                List<T_FM_SYNC_TASK> srcSyncTasks = null;
             
                List<T_FM_ENUM_TYPE> srcEnumType = null;
                List<T_FM_ENUM> srcEnum = null;
                List<T_BD_PICTURE> srcPicture = null;
              
                List<T_PF_DATA_FREQUENCY> srcDataFrequency = null;
                
                List<T_FM_ENUM_ITEM> srcEnumItem = null;
                
                srcParamItems = this.GetEntities<T_PF_PARAM_ITEM>(null, filter).ToList();
                srcParamSchemes = this.GetEntities<T_PF_PARAM_SCHEME>(null, filter).ToList();
                srcParamSchemeDetails = this.GetEntities<T_PF_PARAM_SCHEME_DETAIL>(null, filter).ToList();
                srcVersionManages = this.GetEntities<T_PF_VERSION_MANAGE>(null, filter).ToList();
                srcCodeRules = this.GetEntities<T_PF_CODE_RULE>(null, filter).ToList();
                srcSyncTasks = this.GetEntities<T_FM_SYNC_TASK>(null, filter).ToList();

              
                srcEnumType = this.GetEntities<T_FM_ENUM_TYPE>(null, filter).ToList();
                srcEnum = this.GetEntities<T_FM_ENUM>(null, filter).ToList();
                srcPicture = this.GetEntities<T_BD_PICTURE>(null, filter).ToList();
               
                srcDataFrequency = this.GetEntities<T_PF_DATA_FREQUENCY>(null, filter).ToList();
               
                srcEnumItem = this.GetEntities<T_FM_ENUM_ITEM>(null, filter).ToList();
                

                #endregion
                #endregion
                List<Guid> existForm = new List<Guid>();
                List<Guid> existTable = new List<Guid>();
                List<Guid> existPermForm = new List<Guid>();
                if (tenant.CheckKeys.Count > 0)
                {
                    var tenantFilter = new BaseFilter(tenant.ID);//当前企业
                    var perOPMenu = this.GetEntities<T_NW_ROLE_MENU>(x => x.ENTERPRISE_ID == tenant.ID, orgFilter);
                    var tenantMenus = this.GetEntities<T_PF_MENU>(x => x.ORG_ID == tenantFilter.OrgId, tenantFilter);
                    List<T_PF_PARAM_ITEM> tenantParamItems = null;
                    List<T_PF_PARAM_SCHEME> tenantParamSchemes = null;
                    List<T_PF_PARAM_SCHEME_DETAIL> tenantParamSchemeDetails = null;
                    List<T_PF_VERSION_MANAGE> tenantVersionManages = null;
                    List<T_PF_CODE_RULE> tenantCodeRules = null;
                    List<T_FM_SYNC_TASK> tenantSyncTasks = null;
                    List<T_FM_ENUM_TYPE> tenantEnumType = null;//枚举类别
                    List<T_FM_ENUM> tenantEnum = null;//枚举管理
                    List<T_FM_ENUM_ITEM> tenantEnumItem = null;
                    List<T_BD_PICTURE> tenantPicture = null;//图片管理
                    List<T_PF_DATA_FREQUENCY> tenantDataFrequency = null;//数据采集频率
                    tenantParamItems = this.GetEntities<T_PF_PARAM_ITEM>(null, tenantFilter).ToList();
                    tenantParamSchemes = this.GetEntities<T_PF_PARAM_SCHEME>(null, tenantFilter).ToList();
                    tenantParamSchemeDetails = this.GetEntities<T_PF_PARAM_SCHEME_DETAIL>(null, tenantFilter).ToList();
                    tenantVersionManages = this.GetEntities<T_PF_VERSION_MANAGE>(null, tenantFilter).ToList();
                    tenantCodeRules = this.GetEntities<T_PF_CODE_RULE>(null, tenantFilter).ToList();
                    tenantSyncTasks = this.GetEntities<T_FM_SYNC_TASK>(null, tenantFilter).ToList();

                    tenantEnumType = this.GetEntities<T_FM_ENUM_TYPE>(null, tenantFilter).ToList();
                    tenantEnum = this.GetEntities<T_FM_ENUM>(null, tenantFilter).ToList();
                    tenantEnumItem = this.GetEntities<T_FM_ENUM_ITEM>(null, tenantFilter).ToList();
                    tenantPicture = this.GetEntities<T_BD_PICTURE>(null, tenantFilter).ToList();
                    tenantDataFrequency = this.GetEntities<T_PF_DATA_FREQUENCY>(null, tenantFilter).ToList();

                    #region 系统参数模板           
                    if (!tenantParamItems.Any(x => x.ORG_ID == tenant.ID) && !tenantParamSchemes.Any(x => x.ORG_ID == tenant.ID) && !tenantParamSchemeDetails.Any(x => x.SRC_ID == tenant.ID))
                    {
                        foreach (var item in srcParamItems)
                        {
                            T_PF_PARAM_ITEM parmItem = item;
                            var newItemID = Guid.NewGuid();
                            var oldItenID = parmItem.ID;
                            parmItem.SRC_ID = parmItem.ID;
                            parmItem.ID = newItemID;
                            parmItem.ORG_ID = tenant.ID;
                            newItems.Add(oldItenID, newItemID);
                            addParamItems.Add(parmItem);
                        }
                        foreach (var item in srcParamSchemes)
                        {
                            T_PF_PARAM_SCHEME paramScheme = item;
                            var newSchemesID = Guid.NewGuid();
                            var oldSchemeID = paramScheme.ID;
                            paramScheme.SRC_ID = paramScheme.ID;
                            paramScheme.ID = newSchemesID;
                            paramScheme.ORG_ID = tenant.ID;
                            newSchemes.Add(oldSchemeID, newSchemesID);
                            addParamSchemes.Add(paramScheme);

                        }
                        foreach (var item in srcParamSchemeDetails)
                        {
                            T_PF_PARAM_SCHEME_DETAIL paramSchemeDetail = item;
                            var newSchemeDetailID = Guid.NewGuid();
                            var oldSchemeDetailID = paramSchemeDetail.ID;
                            var scheneId = newSchemes[item.PARAM_SCHEME_ID];
                            var ItemId = newItems[item.PARAM_ITEM_ID];
                            paramSchemeDetail.SRC_ID = paramSchemeDetail.ID;
                            paramSchemeDetail.ID = newSchemeDetailID;
                            paramSchemeDetail.ORG_ID = tenant.ID;
                            paramSchemeDetail.PARAM_SCHEME_ID = scheneId;
                            paramSchemeDetail.PARAM_ITEM_ID = ItemId;
                            newSchemeDetails.Add(oldSchemeDetailID, newSchemeDetailID);
                            addParamSchemeDetails.Add(paramSchemeDetail);
                        }
                    }
                    #endregion
                    #region 编码规则表          
                    if (!tenantCodeRules.Any(x => x.ORG_ID == tenant.ID))
                    {
                        foreach (var item in srcCodeRules)
                        {
                            T_PF_CODE_RULE codeRule = item;
                            var newCodeRuleID = Guid.NewGuid();
                            var oldCodeRuleID = item.ID;
                            codeRule.SRC_ID = codeRule.ID;
                            codeRule.ID = newCodeRuleID;
                            codeRule.ORG_ID = tenant.ID;
                            newCodeRules.Add(oldCodeRuleID, newCodeRuleID);
                            addCodeRules.Add(codeRule);
                        }
                    }
                    #endregion
                    #region T_FM_SYNC_TASK         
                    if (!tenantSyncTasks.Any(x => x.ORG_ID == tenant.ID))
                    {
                        foreach (var item in srcSyncTasks)
                        {
                            T_FM_SYNC_TASK syncTask = item;
                            var newSyncTaskID = Guid.NewGuid();
                            var oldCodeRuleID = item.ID;
                            syncTask.SRC_ID = syncTask.ID;
                            syncTask.ID = newSyncTaskID;
                            syncTask.ORG_ID = tenant.ID;
                            addSyncTasks.Add(syncTask);//添加到对应租户     


                        }
                    }
                    #endregion
                    #region T_PF_VERSION_MANAGE 版本                
                    if (!tenantVersionManages.Any(x => x.ORG_ID == tenant.ID))
                    {
                        foreach (var item in srcVersionManages)
                        {
                            T_PF_VERSION_MANAGE version = item;
                            var newCodeRuleID = Guid.NewGuid();
                            //var oldCodeRuleID = item.ID;                         
                            version.ID = newCodeRuleID;
                            version.ORG_ID = tenant.ID;
                            //newCodeRules.Add(oldCodeRuleID, newCodeRuleID);
                            saveVersions.Add(version);//添加到对应租户  
                        }
                    }
                    #endregion
                    #region 基础参数下发                            
                   
                    Dictionary<Guid, Guid> dicEnumType = new Dictionary<Guid, Guid>();
                    Dictionary<Guid, Guid> dicEnum = new Dictionary<Guid, Guid>();
                    Dictionary<Guid, Guid> dicEnumItem = new Dictionary<Guid, Guid>();
                    Dictionary<Guid, Guid> dicEnergyType = new Dictionary<Guid, Guid>();
                    Dictionary<Guid, Guid> dicReductionFactor = new Dictionary<Guid, Guid>();
                    Dictionary<Guid, Guid> dicPicture = new Dictionary<Guid, Guid>();
                    if (!tenantEnumType.Any(x => x.ORG_ID == tenant.ID))//枚举类别(枚举管理)
                    {
                        foreach (var item in srcEnumType)
                        {
                            T_FM_ENUM_TYPE enumType = item;
                            var newID = Guid.NewGuid();
                            dicEnumType.Add(enumType.ID, newID);
                            enumType.ID = newID;
                            enumType.ORG_ID = tenant.ID;
                            addEnumType.Add(enumType);//添加到对应租户  
                        }
                    }
                    if (!tenantEnum.Any(x => x.ORG_ID == tenant.ID))//枚举管理
                    {
                        foreach (var item in srcEnum)
                        {
                            T_FM_ENUM enumInfo = item;
                            var newID = Guid.NewGuid();
                            dicEnum.Add(enumInfo.ID, newID);
                            enumInfo.ID = newID;
                            enumInfo.ORG_ID = tenant.ID;
                            enumInfo.ENUM_TYPE_ID = dicEnumType[enumInfo.ENUM_TYPE_ID];
                            addEnum.Add(enumInfo);//添加到对应租户  
                        }
                    }
                    if (!tenantEnumItem.Any(x => x.ORG_ID == tenant.ID))//枚举管理
                    {
                        foreach (var item in srcEnumItem)
                        {
                            T_FM_ENUM_ITEM enumItem = item;
                            var newID = Guid.NewGuid();
                            dicEnumItem.Add(enumItem.ID, newID);
                            enumItem.ID = newID;
                            enumItem.ORG_ID = tenant.ID;
                            enumItem.ENUM_ID = dicEnum[enumItem.ENUM_ID];
                            addEnumItem.Add(enumItem);//添加到对应租户  
                        }
                    }
                   
                    if (!tenantPicture.Any(x => x.ORG_ID == tenant.ID))//图片资源
                    {
                        foreach (var item in srcPicture)
                        {
                            T_BD_PICTURE picture = item;
                            var newID = Guid.NewGuid();
                            dicPicture.Add(picture.ID, newID);
                            picture.ID = newID;
                            picture.ORG_ID = tenant.ID;
                            if (picture.ENUM_ID != null)
                            {
                                picture.ENUM_ID = dicEnum[(Guid)picture.ENUM_ID];
                            }
                            if (picture.ENUM_ITEM_ID != null)
                            {
                                picture.ENUM_ITEM_ID = dicEnumItem[(Guid)picture.ENUM_ITEM_ID];
                            }
                            addPicture.Add(picture);//添加到对应租户  
                        }
                    }

                    if (!tenantDataFrequency.Any(x => x.ORG_ID == tenant.ID))//数据采集频率
                    {
                        foreach (var item in srcDataFrequency)
                        {
                            T_PF_DATA_FREQUENCY dataFrequency = item;
                            var newCodeRuleID = Guid.NewGuid();
                            dataFrequency.ID = newCodeRuleID;
                            dataFrequency.ORG_ID = tenant.ID;
                            addDataFrequency.Add(dataFrequency);//添加到对应租户  
                        }
                    }
                   
                    #endregion
                    #region 添加租户管理员
                    var tenantUser = this.GetEntities<T_FM_USER>(x => x.ORG_ID == tenantFilter.OrgId, tenantFilter);
                    var tenantRole = this.GetEntities<T_FM_ROLE>(x => x.ORG_ID == tenantFilter.OrgId, tenantFilter);
                    var tenantUserBelongRole = this.GetEntities<T_FM_USER_BELONG_ROLE>(x => x.ORG_ID == tenantFilter.OrgId, tenantFilter);
                    if (!tenantUser.Any(x => x.ORG_ID == tenant.ID) && !tenantRole.Any(x => x.ORG_ID == tenant.ID) && !tenantUserBelongRole.Any(x => x.ORG_ID == tenant.ID))
                    {
                        T_FM_USER user = new T_FM_USER();
                        user.ID = Guid.NewGuid();
                        user.IS_DELETED = false;
                        user.ORG_ID = tenant.ID;
                        user.NAME = "管理员";
                        user.CODE = "admin";
                        user.PASSWORD = "E10ADC3949BA59ABBE56E057F20F883E";
                        user.ENTITY_ORG_TPYE = 0;
                        user.FLOW_STATUS = 0;
                        user.FLOW_SEND_STATUS = 0;
                        user.ENABLE_STATUS = 0;
                        T_FM_ROLE role = new T_FM_ROLE();
                        role.ID = Guid.NewGuid();
                        role.IS_DELETED = false;
                        role.ORG_ID = tenant.ID;
                        role.NAME = "管理员";
                        role.CODE = "admin";
                        role.ENTITY_ORG_TPYE = 0;
                        role.FLOW_STATUS = 0;
                        role.FLOW_SEND_STATUS = 0;
                        role.ENABLE_STATUS = 0;
                        role.ROLE_TYPE = 99;
                        role.PLATFORM_TYPE = 0;
                        T_FM_USER_BELONG_ROLE userBelongRole = new T_FM_USER_BELONG_ROLE();
                        userBelongRole.ID = Guid.NewGuid();
                        userBelongRole.IS_DELETED = false;
                        userBelongRole.ORG_ID = tenant.ID;
                        userBelongRole.ENTITY_ORG_TPYE = 0;
                        userBelongRole.FLOW_STATUS = 0;
                        userBelongRole.FLOW_SEND_STATUS = 0;
                        userBelongRole.USER_ID = user.ID;
                        userBelongRole.BELONG_ROLE_ID = role.ID;
                        saveUser.Add(user);
                        saveRole.Add(role);
                        saveUserBelongRole.Add(userBelongRole);
                    }
                    #endregion
                    foreach (var CheckKey in tenant.CheckKeys)
                    {
                        var checkMenu = optMenusTree.FirstOrDefault(x => x.Node.ID == new Guid(CheckKey));
                        if (checkMenu == null)
                        {
                            foreach (var item in optMenusTree)
                            {
                                checkMenu = selectNode(item, CheckKey);
                                if (checkMenu != null)
                                    break;
                            }
                        }
                        if (checkMenu != null && checkMenu.Node.IS_PERMISSION_SUB == (int)FMSubPermEnum.子企业可见)
                        {
                            if (checkMenu.IsLeaf && checkMenu.Node.MENU_FORM_ID != null)//叶子节点
                            {
                                dicMenu.Add(new Guid(CheckKey), checkMenu.Node.MENU_FORM_ID);
                                // T_PF_FORM t_PF_FORM = this.GetEntities<T_PF_FORM>(x=>x.ORG_ID==filter.OrgId, filter).FirstOrDefault(x => x.ID == checkMenu.Node.MENU_FORM_ID);//OPT
                                T_PF_MENU t_PF_MENU = this.GetEntities<T_PF_MENU>(x => x.ORG_ID == filter.OrgId, filter).Where(x => x.ID == new Guid(CheckKey)).FirstOrDefault();
                                if (tenantMenus.Any(x => x.SRC_ID == new Guid(CheckKey)))//菜单存在
                                {
                                    #region 生成菜单      
                                    var tenantMenu = tenantMenus.FirstOrDefault(x => x.SRC_ID == new Guid(CheckKey));
                                    if (!perOPMenu.Any(x => x.MENU_ID == new Guid(CheckKey)))//未授权
                                    {
                                        savePermOPMenu.Add(new T_NW_ROLE_MENU() { ENTERPRISE_ID = tenant.ID, MENU_ID = new Guid(CheckKey), ENTERPRISE_MENU_ID = tenantMenu.ID, ORG_ID = tenant.ID });//菜单授权
                                    }
                                    t_PF_MENU.SRC_ID = new Guid(CheckKey);
                                    t_PF_MENU.ID = tenantMenu.ID;
                                    t_PF_MENU.ORG_ID = tenant.ID;
                                    t_PF_MENU.IS_PERMISSION_MENU = true;
                                    relationMenu.Add(checkMenu.Node.ID.ToString(), checkMenu.Node.PARENT_ID);
                                    newRelationMenu.Add(checkMenu.Node.ID.ToString(), tenantMenu.ID.ToString());
                                    #endregion
                                }
                                else
                                {
                                    #region 菜单授权
                                    var newMenuID = Guid.NewGuid();
                                    savePermOPMenu.Add(new T_NW_ROLE_MENU() { ENTERPRISE_ID = tenant.ID, MENU_ID = new Guid(CheckKey), ENTERPRISE_MENU_ID = newMenuID, ORG_ID = tenant.ID });//菜单授权
                                    #endregion                                  
                                    #region 生成菜单        
                                    t_PF_MENU.SRC_ID = checkMenu.Node.ID;
                                    t_PF_MENU.ID = newMenuID;
                                    t_PF_MENU.ORG_ID = tenant.ID;
                                    t_PF_MENU.IS_PERMISSION_MENU = true;
                                    relationMenu.Add(checkMenu.Node.ID.ToString(), checkMenu.Node.PARENT_ID);
                                    newRelationMenu.Add(checkMenu.Node.ID.ToString(), newMenuID.ToString());
                                    #endregion
                                }
                                //savePermPFForm.Add(t_PF_FORM);//添加表单到对应租户
                                savePermPFMenu.Add(t_PF_MENU);//添加菜单到对应租户                            
                            }
                            else
                            {
                                dicMenu.Add(new Guid(CheckKey), null);
                                T_PF_MENU t_PF_MENU = this.GetEntities<T_PF_MENU>(x => x.ORG_ID == filter.OrgId, filter).Where(x => x.ID == new Guid(CheckKey)).FirstOrDefault();
                                if (tenantMenus.Any(x => x.SRC_ID == new Guid(CheckKey)))//菜单存在
                                {
                                    var tenantMenu = tenantMenus.FirstOrDefault(x => x.SRC_ID == new Guid(CheckKey));
                                    if (!perOPMenu.Any(x => x.MENU_ID == new Guid(CheckKey)))//未授权
                                    {
                                        savePermOPMenu.Add(new T_NW_ROLE_MENU() { ENTERPRISE_ID = tenant.ID, MENU_ID = new Guid(CheckKey), ENTERPRISE_MENU_ID = tenantMenu.ID, ORG_ID = tenant.ID });//菜单授权
                                    }
                                    t_PF_MENU.SRC_ID = checkMenu.Node.ID;
                                    t_PF_MENU.ID = tenantMenu.ID;
                                    t_PF_MENU.ORG_ID = tenantMenu.ORG_ID;
                                    t_PF_MENU.IS_PERMISSION_MENU = true;
                                    relationMenu.Add(checkMenu.Node.ID.ToString(), checkMenu.Node.PARENT_ID);
                                    newRelationMenu.Add(checkMenu.Node.ID.ToString(), tenantMenu.ID.ToString());
                                }
                                else
                                {
                                    var newMenuID = Guid.NewGuid();
                                    savePermOPMenu.Add(new T_NW_ROLE_MENU() { ENTERPRISE_ID = tenant.ID, MENU_ID = new Guid(CheckKey), ENTERPRISE_MENU_ID = newMenuID, ORG_ID = tenant.ID });//菜单授权
                                    t_PF_MENU.SRC_ID = checkMenu.Node.ID;
                                    t_PF_MENU.ID = newMenuID;
                                    t_PF_MENU.ORG_ID = tenant.ID;
                                    t_PF_MENU.IS_PERMISSION_MENU = true;
                                    relationMenu.Add(checkMenu.Node.ID.ToString(), checkMenu.Node.PARENT_ID);
                                    newRelationMenu.Add(checkMenu.Node.ID.ToString(), newMenuID.ToString());
                                }
                                savePermPFMenu.Add(t_PF_MENU);//添加菜单到对应租户                            
                            }
                        }
                    }
                    var deleteFilter = new BaseFilter(tenant.ID);//OPT创建的菜单,表单等
                    deleteFilter.Level = -1;
                    deleteFilter.IsParentData = true;
                    var tenantMenusTree = this.GetTreeOrderEntities<T_PF_MENU>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用, deleteFilter);
                    foreach (var item in permOPMenu)
                    {
                        if (!dicMenu.Keys.Contains(item.MENU_ID))
                        {
                            var deleteMenu = tenantMenusTree.FirstOrDefault(x => x.Node.ID == item.ENTERPRISE_MENU_ID);
                            if (deleteMenu == null)
                            {
                                foreach (var tenantMenu in tenantMenusTree)
                                {
                                    deleteMenu = selectNode(tenantMenu, item.ENTERPRISE_MENU_ID.ToString());
                                    if (deleteMenu != null)
                                        break;
                                }
                            }
                            if (deleteMenu != null)
                            {
                                var cancelMenu = this.GetEntities<T_PF_MENU>(x => x.ID == deleteMenu.Node.ID, orgFilter).FirstOrDefault();
                                cancelMenu.IS_PERMISSION_MENU = false;
                                deletePermPFMenu.Add(cancelMenu);
                                deletePermOPMenu.Add(item.ID);
                            }
                        }
                    }
                    #region 菜单节点关系
                    foreach (var item in relationMenu)
                    {
                        if (item.Value != null)
                        {
                            var newMenuID = newRelationMenu[item.Key];//需要更新父ID
                            savePermPFMenu.Where(x => x.ID == new Guid(newMenuID)).FirstOrDefault().PARENT_ID = new Guid(newRelationMenu[item.Value.ToString()]);
                        }
                    }
                    #endregion
                    #region 数据权限
                    var permissionOrg = this.GetEntities<T_NW_ROLE_DATA_PERM>(x => x.ENTERPRISE_ID == tenant.ID, orgFilter).ToList();
                    if (tenant.OrgCheckKeys.Count > 0)
                    {
                        foreach (var item in tenant.OrgCheckKeys)
                        {
                            dicCheckKeys.Add(new Guid(item));
                            if (!permissionOrg.Any(x => x.PREM_ENTERPRISE_ID == new Guid(item)))
                            {
                                saveDataPerm.Add(new T_NW_ROLE_DATA_PERM() { ORG_ID = tenant.ORG_ID, PREM_ENTERPRISE_ID = new Guid(item), ENTERPRISE_ID = tenant.ID });
                            }
                        }
                        foreach (var item in permissionOrg)
                        {
                            if (!dicCheckKeys.Contains(item.PREM_ENTERPRISE_ID))
                            {
                                deleteDataPerm.Add(item.ID);
                            }
                        }
                    }
                    else
                    {
                        foreach (var item in permissionOrg)
                        {
                            deleteDataPerm.Add(item.ID);
                        }
                    }
                    #endregion
                    UnifiedCommit(() =>
                    {
                        tenant.CheckKeys = null;
                        tenant.OrgCheckKeys = null;
                        this.UpdateEntity(tenant);

                        if (deletePermOPMenu.Count > 0)
                            this.BantchDeleteEntityNoCommit<T_NW_ROLE_MENU>(deletePermOPMenu);
                        if (deletePermPFMenu != null && deletePermPFMenu.Any())
                            this.BantchSaveEntityNoCommit(deletePermPFMenu);
                        if (savePermOPMenu != null && savePermOPMenu.Any())
                            this.BantchSaveEntityNoCommit(savePermOPMenu);
                        if (savePermPFMenu != null && savePermPFMenu.Any())
                            this.BantchSaveEntityNoCommit(savePermPFMenu);
                        if (saveUser != null && saveUser.Any())
                            this.BantchSaveEntityNoCommit(saveUser);
                        if (saveRole != null && saveRole.Any())
                            this.BantchSaveEntityNoCommit(saveRole);
                        if (saveUserBelongRole != null && saveUserBelongRole.Any())
                            this.BantchSaveEntityNoCommit(saveUserBelongRole);

                       
                        if (addCodeRules != null && addCodeRules.Any())
                           this.BantchSaveEntityNoCommit(addCodeRules);                   
                        if (addSyncTasks != null && addSyncTasks.Any())
                           this.BantchSaveEntityNoCommit(addSyncTasks);
                        if (saveVersions != null && saveVersions.Any())
                           this.BantchSaveEntityNoCommit(saveVersions);
                     
                        if (addEnumType != null && addEnumType.Any())
                           this.BantchSaveEntityNoCommit(addEnumType);
                        if (addEnum != null && addEnum.Any())
                           this.BantchSaveEntityNoCommit(addEnum);
                        if (addEnumItem != null && addEnumItem.Any())
                           this.BantchSaveEntityNoCommit(addEnumItem);
                        if (addPicture != null && addPicture.Any())
                           this.BantchSaveEntityNoCommit(addPicture);
                        if (addDataFrequency != null && addDataFrequency.Any())
                           this.BantchSaveEntityNoCommit(addDataFrequency);
                        if (saveDataPerm != null && saveDataPerm.Any())
                            this.BantchSaveEntityNoCommit(saveDataPerm);
                        if (deleteDataPerm != null && deleteDataPerm.Any())
                            this.BantchDeleteEntityNoCommit<T_NW_ROLE_DATA_PERM>(deleteDataPerm);
                    });
                }
                else
                {
                    if (permOPMenu.Count > 0)
                    {
                        deletePermOPMenu.AddRange(permOPMenu.Select(x => x.ID).ToList());
                    }
                    if (tenant.PARENT_ID != null)
                    {
                        if (permPFMenu.Count > 0)
                        {
                            foreach (var item in permPFMenu)
                            {
                                item.IS_PERMISSION_MENU = false;
                                deletePermPFMenu.Add(item);
                            }
                        }
                    }
                    #region 数据权限
                    var permissionOrg = this.GetEntities<T_NW_ROLE_DATA_PERM>(x => x.ENTERPRISE_ID == tenant.ID, orgFilter).ToList();
                    if (tenant.OrgCheckKeys.Count > 0)
                    {
                        foreach (var item in tenant.OrgCheckKeys)
                        {
                            dicCheckKeys.Add(new Guid(item));
                            if (!permissionOrg.Any(x => x.PREM_ENTERPRISE_ID == new Guid(item)))
                            {
                                saveDataPerm.Add(new T_NW_ROLE_DATA_PERM() { ORG_ID = tenant.ORG_ID, PREM_ENTERPRISE_ID = new Guid(item), ENTERPRISE_ID = tenant.ID });
                            }
                        }
                        foreach (var item in permissionOrg)
                        {
                            if (!dicCheckKeys.Contains(item.PREM_ENTERPRISE_ID))
                            {
                                deleteDataPerm.Add(item.ID);
                            }
                        }
                    }
                    else
                    {
                        foreach (var item in permissionOrg)
                        {
                            deleteDataPerm.Add(item.ID);
                        }
                    }
                    #endregion
                    UnifiedCommit(() =>
                    {
                        tenant.CheckKeys = null;
                        tenant.OrgCheckKeys = null;
                        this.UpdateEntityNoCommit(tenant);
                        if (deletePermOPMenu.Count > 0)
                            this.BantchDeleteEntityNoCommit<T_NW_ROLE_MENU>(deletePermOPMenu);
                        if (deletePermPFMenu != null && deletePermPFMenu.Any())
                            this.BantchSaveEntityNoCommit(deletePermPFMenu);
                        if (saveDataPerm != null && saveDataPerm.Any())
                            this.BantchSaveEntityNoCommit(saveDataPerm);
                        if (deleteDataPerm != null && deleteDataPerm.Any())
                            this.BantchDeleteEntityNoCommit<T_NW_ROLE_DATA_PERM>(deleteDataPerm);
                    });
                }
                return true;
            });
        }
        public T_FM_ORGANIZATION selectRoot(IEnumerable<T_FM_ORGANIZATION> orgs, T_FM_ORGANIZATION org)
        {
            if (org.PARENT_ID == null)
            {
                return org;
            }
            else
            {
                T_FM_ORGANIZATION checkRoot = null;
                T_FM_ORGANIZATION pOrg = orgs.Where(x => x.ID == org.PARENT_ID).FirstOrDefault();
                checkRoot = selectRoot(orgs, pOrg);
                if (checkRoot != null)
                {
                    return checkRoot;
                }
                return checkRoot;
            }
        }
        public TreeNode<T_PF_MENU> selectNode(TreeNode<T_PF_MENU> treeNode, string checkKey)
        {
            if (treeNode.Node.ID == new Guid(checkKey))
            {
                return treeNode;
            }
            else
            {
                TreeNode<T_PF_MENU> checkNode = null;
                foreach (var item in treeNode.Children)
                {
                    checkNode = selectNode(item, checkKey);
                    if (checkNode != null)
                    {
                        return checkNode;
                    }
                }
                return checkNode;
            }
        }

        /// <summary>
        /// 树形授权
        /// </summary>
        /// <param name="role"></param>
        /// <returns></returns>
        [HttpPost, Route("GetTreePermissionForms")]
        public JsonActionResult<RolePermissionResul> GetTreePermissionForms([FromBody] KeywordPageFilter pageFilter)
        {
            return SafeExecute<RolePermissionResul>(() =>
            {
                List<RolePermissionTreeModel> result = new List<RolePermissionTreeModel>();//最终返回树结果
                var orgfilter = new BaseFilter();
                orgfilter.IgnoreOrgRule = true;
                var org = this.GetEntities<T_FM_ORGANIZATION>(x => x.ID == new Guid(pageFilter.Keyword), orgfilter).FirstOrDefault();
                bool isRoot = org.PARENT_ID == null ? true : false;
                var filter = new BaseFilter(pageFilter.OrgId);//OPT OrgId
                filter.Level = -1;
                filter.IsParentData = true;
                string tenantId = pageFilter.Keyword;//租户ID
                List<T_NW_ROLE_MENU> permissionMenu = null;
                var menuTree = this.GetTreeOrderEntities<T_PF_MENU>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用 && x.PLATFORM_CATEGORY == 0, filter);
                if (!string.IsNullOrEmpty(tenantId))
                {
                    permissionMenu = this.GetEntities<T_NW_ROLE_MENU>(x => x.ENTERPRISE_ID == new Guid(tenantId), orgfilter).ToList();
                }
                List<FormInfo> formInfos = new List<FormInfo>();
                List<FormInfo> orgInfos = new List<FormInfo>();
                List<string> checks = new List<string>();
                List<string> checkLastKey = new List<string>();
                List<string> orgChecks = new List<string>();
                List<string> orgCheckLastKey = new List<string>();
                foreach (var menu in menuTree)
                {
                    AddChildren(menu, permissionMenu, formInfos);
                }
                result = RolePermissionTreeModel.GetRolePermissionTree(formInfos);
                result = result[0].children;
                foreach (var item in result)
                {
                    SelectCheck(item, checks, checkLastKey);
                }
                #region 数据授权
                var orgFilter = new BaseFilter();
                orgFilter.IgnoreOrgRule = true;
                var orgs = this.GetTreeOrderEntities<T_FM_ORGANIZATION>(x => x.ENABLE_STATUS == (int)FMEnableStatusEnum.启用 && x.ORG_ID == pageFilter.OrgId, orgFilter);
            
                var permissionOrg = this.GetEntities<T_NW_ROLE_DATA_PERM>(x => x.ENTERPRISE_ID == new Guid(tenantId), filter).ToList();
                foreach (var item in orgs)
                {
                    AddOrgChildren(item, permissionOrg, orgInfos);
                }
                List<RolePermissionTreeModel> orgResult = new List<RolePermissionTreeModel>();//最终返回树结果
                orgResult = RolePermissionTreeModel.GetRolePermissionTree(orgInfos);
                orgResult = orgResult[0].children;
                foreach (var item in orgResult)
                {
                    SelectCheck(item, orgChecks, orgCheckLastKey);
                }
                #endregion
                var rlt = new RolePermissionResul()
                {
                    checks = checks,
                    checkLastKey = checkLastKey,
                    rolePermissionTreeModels = result,
                    isRoot = isRoot,
                    orgChecks = orgChecks,
                    orgCheckLastKey = orgCheckLastKey,
                    orgRolePermissionTreeModels = orgResult
                };
                return rlt;
            });
        }
        public void AddChildren(TreeNode<T_PF_MENU> treeNode, IEnumerable<T_NW_ROLE_MENU> permissionMenu, List<FormInfo> formInfos)
        {
            var permission = false;
            if (!treeNode.Node.IS_LEAF)
            {
                permission = permissionMenu == null ? false : permissionMenu.Any(x => x.MENU_ID == treeNode.Node.ID);
                formInfos.Add(new FormInfo()
                {
                    Code = treeNode.Node.ID.ToString(),
                    Title = treeNode.Node.NAME,
                    ParentCode = treeNode.Node.PARENT_ID.ToString(),
                    IsCheck = permission
                });
                foreach (var item in treeNode.Children)
                {
                    AddChildren(item, permissionMenu, formInfos);
                }
            }
            else
            {
                permission = permissionMenu == null ? false : permissionMenu.Any(x => x.MENU_ID == treeNode.Node.ID);
                formInfos.Add(new FormInfo()
                {
                    Code = treeNode.Node.ID.ToString(),
                    Title = treeNode.Node.NAME,
                    ParentCode = treeNode.Node.PARENT_ID.ToString(),
                    IsCheck = permission
                });
            }
        }
        public void AddOrgChildren(TreeNode<T_FM_ORGANIZATION> treeNode, IEnumerable<T_NW_ROLE_DATA_PERM> permissionOrg, List<FormInfo> orgInfos)
        {
            var permission = false;
            if (!treeNode.Node.IS_LEAF)
            {
                permission = permissionOrg == null ? false : permissionOrg.Any(x => x.PREM_ENTERPRISE_ID == treeNode.Node.ID);
                orgInfos.Add(new FormInfo()
                {
                    Code = treeNode.Node.ID.ToString(),
                    Title = treeNode.Node.NAME,
                    ParentCode = treeNode.Node.PARENT_ID.ToString(),
                    IsCheck = permission
                });
                foreach (var item in treeNode.Children)
                {
                    AddOrgChildren(item, permissionOrg, orgInfos);
                }
            }
            else
            {
                permission = permissionOrg == null ? false : permissionOrg.Any(x => x.PREM_ENTERPRISE_ID == treeNode.Node.ID);
                orgInfos.Add(new FormInfo()
                {
                    Code = treeNode.Node.ID.ToString(),
                    Title = treeNode.Node.NAME,
                    ParentCode = treeNode.Node.PARENT_ID.ToString(),
                    IsCheck = permission
                });
            }
        }
        public void SelectCheck(RolePermissionTreeModel RolePermissions, List<string> checks, List<string> checkLastKey)
        {
            if (RolePermissions.IsCheck)
            {
                checks.Add(RolePermissions.key);
            }
            if (RolePermissions.children.Count == 0 && RolePermissions.IsCheck)
            {
                checkLastKey.Add(RolePermissions.key);
            }
            if (RolePermissions.children.Count > 0)
            {
                foreach (var item in RolePermissions.children)
                {
                    SelectCheck(item, checks, checkLastKey);
                }
            }

        }

    }
}
