using APT.BaseData.Domain.ApiModel;
using APT.BaseData.Domain.Entities;
using APT.BaseData.Domain.Entities.FM;
using APT.BaseData.Domain.Entities.OP;
using APT.BaseData.Domain.Enums;
using APT.BaseData.Domain.IServices.FM;
using APT.BaseData.Domain.Msg;
using APT.Infrastructure.Api.Redis;
using APT.Infrastructure.Core;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using APT.Utility;
using APT.NW.WebApi.Models;
using APT.BaseData.Domain.Enums.PF;
using APT.Infrastructure.Api;
namespace APT.NW.WebApi.Controllers.Api.NW
{
    /// <summary>登入</summary>
    [Route("api/NW/Login")]
    public class LoginController : CommonApiController
    {



        /// <summary>
        /// 登入
        /// </summary>
        /// <param name="filter">
        /// Keyword：用户ID
        /// Parameter1：用户Code
        /// Parameter2：密码
        /// Parameter3：平台类型
        /// Parameter4：Orgid
        /// Parameter5：//表单配置版本，取消
        /// Parameter6：验证码
        /// Parameter7：随机数
        /// </param>
        /// <returns></returns>
        [HttpPost, Route("Login")]
        public JsonActionResult<UserLoginBaseModel> Login([FromBody] KeywordFilter filter)
        {
            return base.SafeExecute(() =>
            {
                //var tenantInfo = this.GetEntities<T_FM_ORGANIZATION>(x=>x.PARENT_ID==null, new BaseFilter()).Select(x=>x.ID).ToList();
                //if (!tenantInfo.Contains(new Guid(filter.Parameter4)))
                //    throw new Exception(ErrMsg.PM_NO_USER_ID);//用户不存在
                UserLoginBaseModel result = new UserLoginModel();

                //验证码验证
                if (!string.IsNullOrEmpty(filter.Parameter6) && !string.IsNullOrEmpty(filter.Parameter7))
                {
                    var verCode = CsRedisManager.StringGet(SessionKey.VERIFY_CODE + filter.Parameter7);
                    if (verCode == null)
                    {
                        this.ThrowError("020010");
                    }
                    if (filter.Parameter6.ToUpper() != verCode.ToUpper())
                    {
                        this.ThrowError("020004");
                    }
                }

                string userId = filter == null ? string.Empty : filter.Keyword;
                int platformType = filter == null ? (int)PFPlatTypeEnum.后台 : string.IsNullOrEmpty(filter.Parameter3)
                ? (int)PFPlatTypeEnum.后台 : Convert.ToInt32(filter.Parameter3);
                //bool ingoreLoginLog = LibUtils.ToBoolean(filter.Parameter7);//是否忽略登入日志
                //bool isPlatformLogin = LibUtils.ToBoolean(filter.Parameter8);//是否平台登录

                //int formConfigVersion = LibUtils.ToInt(filter.Parameter5);//当前表单配置版本
                string orgId = filter.Parameter4;

                if (string.IsNullOrEmpty(orgId))
                {
                    throw new Exception(ErrMsg.FM_NO_ORG);
                }
                BaseFilter baseFilter = new BaseFilter();
                baseFilter.Sort = "CREATE_TIME";
                baseFilter.Order = DbOrder.ASC;
                baseFilter.OrgType = FilterOrgTypeEnum.仅本组织;
                baseFilter.IsParentData = true;
                baseFilter.Level = -1;
                baseFilter.OrgId = new Guid(orgId);
                baseFilter.IgnoreDataRule = true;
                filter.OrgId= baseFilter.OrgId;
                if (string.IsNullOrEmpty(userId))
                {
                    string userCode = filter.Parameter1;
                    string userPassword = filter.Parameter2.ToUpper();
                    string userPasswordLower = filter.Parameter2.ToLower();


                    if (string.IsNullOrEmpty(userCode))
                    {
                        throw new Exception(ErrMsg.FM_NO_USER);
                    }
                    if (string.IsNullOrEmpty(userPassword))
                    {
                        throw new Exception(ErrMsg.FM_NO_PWD);
                    }
                    baseFilter.SelectField = new string[] { "CODE" };
                    var user = this.GetEntity<T_FM_USER>(t => ((t.CODE == userCode && (
                    t.PASSWORD == userPassword || t.PASSWORD == userPasswordLower))), baseFilter);
                    if (user == null)
                        throw new Exception(ErrMsg.PM_PSD_ERROR);
                    userId = user.ID.ToString();

                }
                var userService = APT.Infrastructure.Api.ServiceLocator.Instance.GetService<IFMUserService>();
                var useRoleModel = userService.GetRolesByUser(new Guid(userId), filter);
                if (useRoleModel == null)
                    return null;
                if (useRoleModel.User.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                    throw new Exception(ErrMsg.FM_USER_UNABLE);
                /*平台登录  注释  20200816
                if (isPlatformLogin && string.Compare(useRoleModel.User.CODE, "Admin", true) != 0)
                    throw new Exception("只允许集团管理员登录平台");
                */
                if (useRoleModel.User.CODE.Contains("System"))
                    throw new Exception("不允许系统账号手动登入");
                if (useRoleModel.User.Nav_Org != null && useRoleModel.User.Nav_Org.ENABLE_STATUS == 1)
                    throw new Exception("当前组织已停用不允许登入");

                if (platformType == (int)PFPlatTypeEnum.客户端)
                    result = new UserClientLoginModel();
                else if (platformType == (int)PFPlatTypeEnum.APP)
                    result = new UserAppLoginModel();
                result.User = useRoleModel.User;

                result.BaseConfig = this.GetEntitiesByRedis<T_FM_BASE_CONFIG>(baseFilter).FirstOrDefault();



                //Dictionary<string, Guid> permissionFormIds = new Dictionary<string, Guid>();
                //List<T_FM_WORKSTAGE> stages = new List<T_FM_WORKSTAGE>();
                List<T_FM_ROLE> roleList = new List<T_FM_ROLE>();
                List<Guid> menuIds = new List<Guid>();
                //获取角色信息
                if (useRoleModel.Roles != null && useRoleModel.Roles.Any())
                {
                    foreach (var item in useRoleModel.Roles)
                    {
                        if (item.PLATFORM_TYPE != platformType) continue;
                        if (item.ROLE_TYPE == (int)FMRoleTypeEnum.管理角色)
                        {
                            result.UserType = (int)PFUserTypeEnum.管理员;
                            menuIds.Clear();
                            break;
                        }
                        else if (item.Nav_MenuPermissions != null && item.Nav_MenuPermissions.Count != 0)
                        {
                            var menus = item.Nav_MenuPermissions.Select(i => i.MENU_ID ?? Guid.Empty).Distinct().ToList();
                            menuIds.AddRange(menus);
                            menuIds = menuIds.Distinct().ToList();
                            //foreach (var menuPer in item.Nav_MenuPermissions)
                            //{
                            //    if (menuPer.Nav_PermissionForm == null || menuPer.Nav_PermissionForm.ENABLE_STATUS == 1) continue;
                            //    if (menuPer.IS_PERMISSION && (!permissionFormIds.ContainsKey(key)))
                            //        permissionFormIds.Add(key, menuPer.MENU_ID ?? Guid.Empty);
                            //}
                        }
                        //if (item.Nav_Workstages != null && item.Nav_Workstages.Any())
                        //{
                        //    foreach (var stage in item.Nav_Workstages)
                        //    {
                        //        if (stage.IS_PERMISSION && stage.Nav_Workstage != null && !stages.Any(i => i.ID == stage.WORKSTAGE_ID))
                        //            stages.Add(stage.Nav_Workstage);
                        //    }
                        //}
                        roleList.Add(item);
                    }
                }
                result.Roles = roleList;
                //result.CanMenuRework = roleList.Any(t => t.CAN_CHANGE_REWORK);

                //获取授权信息
                if (useRoleModel.Nav_RolePerm != null)
                {
                    var srcRolePerm = useRoleModel.Nav_RolePerm;
                    RolePerm rolePerm = new RolePerm();
                    //if (srcRolePerm.Nav_RolePermForms != null && srcRolePerm.Nav_RolePermForms.Any())
                    //{
                    //    var tmpList = srcRolePerm.Nav_RolePermForms.Where(t => t.Nav_PermForm != null && t.Nav_PermForm.PLATFORM_TYPE == platformType).ToList();
                    //    if (tmpList.Any())
                    //        tmpList.ForEach(t => rolePerm.Nav_RolePermForms.Add(t));
                    //}

                    if (srcRolePerm.Nav_RolePermPanels != null && srcRolePerm.Nav_RolePermPanels.Any())
                        srcRolePerm.Nav_RolePermPanels.ForEach(t => rolePerm.Nav_RolePermPanels.Add(t));
                    if (srcRolePerm.Nav_RolePermWorkStages != null && srcRolePerm.Nav_RolePermWorkStages.Any())
                        srcRolePerm.Nav_RolePermWorkStages.ForEach(t => rolePerm.Nav_RolePermWorkStages.Add(t));
                    result.Nav_RolePerm = rolePerm;
                }

                if (platformType == (int)PFPlatTypeEnum.后台)
                {

                    //baseFilter.Level = -1;

                    UserLoginModel tmp = result as UserLoginModel;
                    //tmp.WorkStages = stages;
                    Expression<Func<T_PF_MENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID && t.IS_PERMISSION_MENU &&
                    t.PLATFORM_CATEGORY == (int)PFPlatformTypeEnum.企业平台 && t.NAME == "企业维护"
                    && t.ENABLE_STATUS != (int)FMEnableStatusEnum.禁用;
                    if (result.UserType != (int)PFUserTypeEnum.管理员)
                    {
                        expression = expression.And(t => menuIds.Contains(t.ID));
                        var filter = new BaseFilter();
                        var ruleIds = result.Roles.Select(i => i.ID).ToArray();
                        filter.SelectField = new string[] { "DEPARTMENT_ID" };
                        tmp.DataRule = this.GetEntities<T_FM_ROLE_DEPARTMENT>(i => i.ORG_ID == result.User.ORG_ID && ruleIds.Contains(i.ROLE_ID), filter)
                        .Select(i => i.DEPARTMENT_ID.ToString()).Distinct().ToList();
                    }
                    else
                    {
                        filter.SelectField = new string[] { "ID" };
                        tmp.DataRule = this.GetEntities<T_FM_DEPARTMENT>(i => i.ORG_ID == result.User.ORG_ID, filter).Select(i => i.ID.ToString()).ToList();

                    }
                    baseFilter.SelectField = new string[] { "ID", "NAME", "MENU_FORM_PARAMS", "MENU_FORM_ID","ICON", "IS_INIT_SHOW",
                        "IS_PERMISSION_MENU", "IS_LEAF", "NUM", "NAME_ACRONYM", "PARENT_ID", "ORG_ID", "ENABLE_STATUS","PLATFORM_CATEGORY",
                        "Nav_MenuForm.CODE", "Nav_MenuForm.NAME", "Nav_MenuForm.NAME_ACRONYM", "Nav_MenuForm.PLATFORM_TYPE",
                        "Nav_MenuForm.FORM_TYPE", "Nav_MenuForm.MODULE_TYPE", "Nav_MenuForm.URI", "Nav_MenuForm.CUSTOM_PARAMS",
                        "Nav_MenuForm.JS_FILES", "Nav_MenuForm.ENABLE_STATUS", "Nav_MenuForm.TABLE_NAME", "Nav_MenuForm.IS_IGNORE_PERMISSION",
                        "Nav_MenuForm.AUTH_ORG_CODES", "Nav_MenuForm.SRC_ID"};
                    var menuList = this.GetTreeOrderEntities<T_PF_MENU>(expression, baseFilter).ToList();
                    // var menuList = this.GetTreeOrderEntities<T_PF_MENU>(expression, baseFilter, new string[] { "Nav_MenuForm" }).ToList();
                    RemoveDisable(menuList);

                    tmp.Menus = menuList;
                    var keyPer = "Style_";
                    if (CsRedisManager.KeyExists(keyPer + userId.ToString()))
                    {
                        result.ShowStyle = CsRedisManager.StringGet<int>(keyPer + userId.ToString());
                    }
                    else
                    {
                        result.ShowStyle = 0;
                    }
                }
                #region 客户端，APP
                //else if (platformType == (int)PFPlatTypeEnum.客户端)
                //{
                //    UserClientLoginModel tmp = result as UserClientLoginModel;
                //    if (useRoleModel.User.PERSON_ID != null)
                //    {
                //        var team = this.GetEntity<T_FM_TEAM>(i => i.Nav_TeamPersons.Any(x => x.PERSON_ID == useRoleModel.User.PERSON_ID),
                //            "Nav_TeamNodes.Nav_MeterNode");
                //        tmp.Team = team;
                //    }
                //    //tmp.WorkStages = stages;
                //    Expression<Func<T_PF_CLIENT_MENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID
                //    && t.IS_LEAF
                //    && t.ENABLE_STATUS == (int)FMEnableStatusEnum.启用;
                //    if (result.UserType != (int)PFUserTypeEnum.管理员)
                //        expression = expression.And(t => menuIds.Contains(t.ID));
                //    var menuList = this.GetTreeOrderEntities<T_PF_CLIENT_MENU>(expression, baseFilter, new string[] { "Nav_MenuForm" }).ToList();
                //    tmp.Menus = menuList;
                //    RemoveDisable(menuList);
                //    if (menuList != null && menuList.Any())
                //    {
                //        /*
                //        var formIds = menuList.Where(t => t.MENU_FORM_ID != null).Select(t => t.MENU_FORM_ID).Distinct().ToList();
                //        List<T_PF_PAGE_CUSTOM> pageCustoms = null;
                //        if (formIds.Any())
                //            pageCustoms = this.GetEntities<T_PF_PAGE_CUSTOM>(t => formIds.Contains(t.PAGE_FORM_ID), new BaseFilter()).ToList();


                //        var fristLevel = menuList.Where(i => i.PARENT_ID == null || i.PARENT_ID == Guid.Empty).ToList();
                //        fristLevel = menuList.Where(i => i.PARENT_ID == null
                //        || i.PARENT_ID == Guid.Empty).OrderBy(t => t.NUM).ToList();

                //        foreach (var f in fristLevel)
                //        {
                //            if (f.MENU_FORM_ID != null)
                //            {
                //                var pageCustom = pageCustoms == null ? null : pageCustoms.Where(t => t.PAGE_FORM_ID == f.MENU_FORM_ID).FirstOrDefault();
                //                if (pageCustom != null)
                //                    f.VIRTUAL_URL = pageCustom.COMPONENT_NAME;//URL
                //            }
                //            UserClientLoginMenuModel m = new UserClientLoginMenuModel();
                //            m.Menu = f;
                //            GetClientChildrenMenu(menuList, m, pageCustoms);
                //            tmp.Menus.Add(m);
                //        }*/
                //        //foreach (var menu in menuList)
                //        //{
                //        //    UserClientLoginMenuModel m = new UserClientLoginMenuModel();
                //        //    m.Menu = menu;
                //        //    tmp.Menus.Add(m);
                //        //}

                //    }

                //}
                //else if (platformType == (int)PFPlatTypeEnum.APP)
                //{
                //    UserAppLoginModel tmp = result as UserAppLoginModel;
                //    //tmp.WorkStages = stages;
                //    Expression<Func<T_PF_APPMENU, bool>> expression = t => t.ORG_ID == result.User.ORG_ID
                //    && t.ENABLE_STATUS != (int)FMEnableStatusEnum.禁用;
                //    if (result.UserType != (int)PFUserTypeEnum.管理员)
                //        expression = expression.And(t => menuIds.Contains(t.ID));
                //    var menuList = this.GetTreeOrderEntities<T_PF_APPMENU>(expression, baseFilter, new string[] { "Nav_MenuForm" }).ToList();
                //    tmp.Menus = menuList;
                //    RemoveDisable(menuList);                  
                //}
                #endregion
                return result;
            });
        }

        private static void RemoveDisable(IList<TreeNode<T_PF_MENU>> menuList)
        {
            for (var x = menuList.Count - 1; x >= 0; x--)
            {
                if (menuList[x].Node.ENABLE_STATUS == (int)FMEnableStatusEnum.禁用)
                {
                    menuList.RemoveAt(x);
                }
                else
                {
                    if (menuList[x].Children != null && menuList[x].Children.Any())
                    {
                        RemoveDisable(menuList[x].Children);
                    }
                }
            }
        }


    }
}
