using AutoMapper;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Performance.Services
{
    public class UserService : IAutoInjection
    {
        private readonly IMapper _mapper;
        private readonly PerforUserRepository _userRepository;
        private readonly PerforSmsRepository _smsRepository;
        private readonly PerforHospitalRepository _hospitalRepository;
        private readonly PerforUserhospitalRepository _userhospitalRepository;
        private readonly PerforRoleRepository _roleRepository;
        private readonly PerforUserroleRepository _userroleRepository;
        private readonly PerforPerdeptdicRepository _perdeptdicRepository;
        private readonly PerforCofaccountingRepository _perforCofaccountingRepository;

        public UserService(
            IMapper mapper,
            PerforSmsRepository smsRepository,
            PerforUserRepository userRepository,
            PerforHospitalRepository hospitalRepository,
            PerforUserhospitalRepository userhospitalRepository,
            PerforRoleRepository roleRepository,
            PerforUserroleRepository userroleRepository,
            PerforPerdeptdicRepository perdeptdicRepository,
            PerforCofaccountingRepository perforCofaccountingRepository)
        {
            _userRepository = userRepository;
            _mapper = mapper;
            _smsRepository = smsRepository;
            _hospitalRepository = hospitalRepository;
            _userhospitalRepository = userhospitalRepository;
            _roleRepository = roleRepository;
            _userroleRepository = userroleRepository;
            _perdeptdicRepository = perdeptdicRepository;
            _perforCofaccountingRepository = perforCofaccountingRepository;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public UserIdentity Login(LoginRequest request)
        {
            //手机号登录
            if (request.LoginType == 1)
            {
                var sms = _smsRepository.GetEntity(t => t.Mobile == request.Account.Trim() && t.SmsCode == request.Password.Trim());
                if (sms == null)
                    throw new PerformanceException("验证码验证失败");
                var user = _userRepository.GetEntity(t => t.Mobile == request.Account && t.IsDelete == 1);
                if (user == null)
                    throw new PerformanceException("用户信息查询失败");

                var data = _mapper.Map<UserIdentity>(user);
                data.Token = Guid.NewGuid().ToString("N");
                return data;
            }
            //账号密码登录
            else if (request.LoginType == 2)
            {
                var user = _userRepository.GetEntity(t => t.Login == request.Account && t.IsDelete == 1);
                if (user == null)
                    throw new PerformanceException($"“{request.Account}”用户不存在");
                //MD5小写加密
                request.Password = PwdHelper.MD5AndSalt(request.Password);

                if (!user.Password.Equals(request.Password, StringComparison.OrdinalIgnoreCase))
                    throw new PerformanceException($"密码错误");

                var data = _mapper.Map<UserIdentity>(user);
                data.Token = Guid.NewGuid().ToString("N");
                return data;
            }
            throw new PerformanceException($"登录类型LoginType：{request.LoginType}暂不支持");
        }

        public UserIdentity GetUser(int userId)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId);
            if (user == null)
                throw new PerformanceException("用户信息查询失败");

            return _mapper.Map<UserIdentity>(user);
        }

        public UserIdentity QuickLogin(int targetUserId, int loginUserId, string password)
        {
            var loginUser = _userRepository.GetEntity(t => t.ID == loginUserId && t.IsDelete == 1);
            if (loginUser == null)
                throw new PerformanceException($"您的账号信息有误，请稍后重试!");

            if (loginUser.Password != PwdHelper.MD5AndSalt(password))
                throw new PerformanceException($"您的密码错误，请重新输入后重试");

            var targetUser = _userRepository.GetEntity(t => t.ID == targetUserId && t.IsDelete == 1);
            if (targetUser == null)
                throw new PerformanceException($"您要登录的用户信息有误，请检查后重试");

            var data = _mapper.Map<UserIdentity>(targetUser);
            data.Token = Guid.NewGuid().ToString("N");
            return data;
        }

        public UserIdentity GetUserIdentity(int userId)
        {
            var targetUser = _userRepository.GetEntity(t => t.ID == userId && t.IsDelete == 1);
            if (targetUser == null)
                throw new PerformanceException($"您要登录的用户信息有误，请检查后重试");

            var data = _mapper.Map<UserIdentity>(targetUser);
            data.Token = Guid.NewGuid().ToString("N");
            return data;
        }

        /// <summary>
        /// 获取用户第一个角色
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public sys_role GetUserFirstRole(int userId)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId);
            if (user == null)
                throw new PerformanceException("用户信息查询失败");

            var userrole = _userroleRepository.GetEntity(t => t.UserID == userId);
            if (userrole == null)
                throw new PerformanceException("角色信息查询失败");
            var role = _roleRepository.GetEntity(t => t.ID == userrole.RoleID);
            return role;
        }

        public List<int> GetUserHospital(int userId)
        {
            var userHospital = _userhospitalRepository.GetEntities(t => t.UserID == userId);
            if (userHospital != null && userHospital.Any(w => w.HospitalID.HasValue))
                return userHospital.Where(w => w.HospitalID.HasValue).Select(w => w.HospitalID.Value).ToList();
            return new List<int>();
        }

        /// <summary>
        /// 查询用户列表
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<UserResponse> GetUserList(int userID, int roleType = 1)
        {
            var userConter = _userRepository.GetUser(userID);
            if (userConter?.User == null) throw new PerformanceException("当前用户信息无效");
            if (userConter?.URole == null) throw new PerformanceException("当前用户角色无效");

            var users = _userRepository.GetUsersByRoleType();

            var userRoles = _userroleRepository.GetEntities();
            var userHospitals = _userhospitalRepository.GetEntities();
            var hospitals = _hospitalRepository.GetEntities();
            var roles = _roleRepository.GetEntities();

            var result = new List<UserResponse>();

            if (userConter?.URole.IsViewAllUsers == 2)
            {
                var userlist = users?.Where(t => t.CreateUser == userID && t.IsDelete == 1 && (t.ParentID == 0 || t.ParentID == null));
                var sonUser = users?.Where(t => t.ParentID != 0 && t.ParentID != null);
                if (sonUser != null)
                    foreach (var user in sonUser)
                    {
                        if (user.Department == "")
                            continue;
                        var parentUser = userlist.FirstOrDefault(t => t.ID == user.ParentID);
                        if (parentUser == null) continue;
                        parentUser.Department = user.Department;
                    }
                result = _mapper.Map<List<UserResponse>>(userlist);
            }
            else
            {
                var hospitalIds = userHospitals?.Where(t => t.UserID == userID)?.Select(t => t.HospitalID);
                if (hospitalIds == null || !hospitalIds.Any()) return result;

                var userIds = userHospitals?.Where(t => hospitalIds.Contains(t.HospitalID)).Select(t => t.UserID).Distinct();
                var userlist = users?.Where(t => t.ID != userID && userIds.Contains(t.ID) && t.IsDelete == 1 && (t.ParentID == 0 || t.ParentID == null));
                var sonUser = users?.Where(t => t.ParentID != 0 && t.ParentID != null);
                if (sonUser != null)
                    foreach (var user in sonUser)
                    {
                        if (user.Department == "")
                            continue;
                        var parentUser = userlist.FirstOrDefault(t => t.ID == user.ParentID);
                        if (parentUser == null) continue;
                        parentUser.Department = user?.Department;
                    }
                result = _mapper.Map<List<UserResponse>>(userlist);
            }
            if (result != null && result.Count > 0)
            {
                foreach (var item in result)
                {
                    var hoslist = userHospitals?.Where(p => p.UserID == item.UserID);
                    if (hoslist != null && hoslist.Count() > 0)
                    {
                        var hosids = hoslist.Select(p => p.HospitalID.Value).ToList();
                        item.Hospital = string.Join(",", hosids);
                        item.HospitalNameArr = hospitals?.Where(w => hosids.Contains(w.ID)).Select(w => w.HosName).ToArray();
                    }

                    List<int> roleId = new List<int>();
                    var userRole = userRoles?.FirstOrDefault(t => t.UserID == item.UserID);
                    if (userRole != null)
                    {
                        item.Role = userRole.RoleID;
                        roleId.Add(userRole.RoleID);
                    }

                    var diffUserRole = users?.Where(c => c.ParentID == item.UserID);
                    if (diffUserRole != null)
                    {
                        foreach (var user in diffUserRole)
                        {
                            var diffRole = userRoles?.FirstOrDefault(t => t.UserID == user.ID);

                            roleId.Add(diffRole.RoleID);
                        }
                    }

                    item.RoleArr = roleId?.ToArray();
                    item.RoleNameArr = roles?.Where(w => roleId.Contains(w.ID)).Select(w => w.RoleName).ToArray();
                }
            }
            return (roleType == (int)Role.绩效查询)
                ? result.Where(w => w.RoleArr.Contains((int)Role.绩效查询)).ToList()
                : result.Where(w => !(w.RoleArr.Length == 1 && w.RoleArr[0] == (int)Role.绩效查询)).ToList();
        }

        /// <summary>
        /// 设置用户医院
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool SetHospital(int userId, int[] hosIDArray)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId && t.IsDelete == 1);
            if (null == user)
                throw new PerformanceException($"用户不存在 UserId：{userId}");
            var userHospital = _userhospitalRepository.GetUserHospital(userId);

            bool rmResult = true, addResult = true;
            //获取需要删除的医院
            var rmHospital = userHospital.Where(t => !hosIDArray.Contains(t.HospitalID.Value));
            if (rmHospital != null && rmHospital.Count() > 0)
                rmResult = _userhospitalRepository.RemoveRange(rmHospital.ToArray());

            //获取需要新增的医院
            var addHospital = hosIDArray.Where(t => !userHospital.Select(u => u.HospitalID).Contains(t));
            if (addHospital != null && addHospital.Count() > 0)
            {
                var allHospital = _hospitalRepository.GetEntities();
                //获取有效医院ID
                var array = addHospital.Where(t => allHospital.Select(h => h.ID).Contains(t))
                    .Select(t => new sys_user_hospital { UserID = userId, HospitalID = t }).ToArray();
                addResult = _userhospitalRepository.AddRange(array);
            }

            return rmResult && addResult;
        }


        /// <summary>
        /// 修改个人信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public UserResponse UpdateSelf(UserRequest request)
        {
            var user = _userRepository.GetEntity(t => t.ID == request.ID && t.IsDelete == 1);
            if (null == user)
                throw new PerformanceException($"用户不存在 UserId：{request.ID}");

            var vlist = _userRepository.GetEntities(t => t.ID != user.ID && t.Login == request.Login && (t.ParentID == null || t.ParentID == 0) && t.IsDelete == 1);
            if (null != vlist && vlist.Count() > 0)
                throw new PerformanceException("登录名重复");

            vlist = _userRepository.GetEntities(t => t.ID != user.ID && t.Mobile == request.Mobile && t.IsDelete == 1);
            if (null != vlist && vlist.Count() > 0)
                throw new PerformanceException("手机号重复");

            user.Mobile = string.IsNullOrEmpty(request.RealName) ? user.Mobile : request.Mobile;
            user.RealName = string.IsNullOrEmpty(request.RealName) ? user.RealName : request.RealName;
            user.Mail = string.IsNullOrEmpty(request.Mail) ? user.Mail : request.Mail;

            if (!_userRepository.Update(user))
                throw new PerformanceException("保存失败");
            return _mapper.Map<UserResponse>(user);
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="request"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public UserResponse UpdatePwd(PasswordRequest request, int userId)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId && t.IsDelete == 1);
            if (null == user)
                throw new PerformanceException($"用户不存在 UserId：{userId}");
            if (string.IsNullOrEmpty(request.NewPwd))
                throw new PerformanceException($"新密码错误");

            //MD5小写加密
            request.OldPwd = PwdHelper.MD5AndSalt(request.OldPwd);
            if (request.OldPwd != user.Password)
                throw new PerformanceException("原密码错误");

            //Md5小写加密
            user.Password = PwdHelper.MD5AndSalt(request.NewPwd);
            user.IsInitialPassword = (int)InitialPassword.修改;

            if (!_userRepository.Update(user))
                throw new PerformanceException("保存失败");
            return _mapper.Map<UserResponse>(user);
        }

        /// <summary>
        /// 角色列表
        /// </summary>
        /// <returns></returns>
        public List<sys_role> RoleList(int userId)
        {
            var user = _userroleRepository.GetEntity(t => t.UserID == userId);
            if (user == null)
                throw new PerformanceException("登录用户不存在！");

            var roles = _roleRepository.GetEntities(t => t.States == 1);
            var role = roles.FirstOrDefault(s => s.ID == user.RoleID);
            if (user == null)
                throw new PerformanceException("当前用户角色无效！");
            List<sys_role> result = new List<sys_role>() { role };
            GetChildrenRole(roles, role.ID, result);

            return result?.OrderBy(w => w.Sort)?.Distinct().ToList();
        }

        /// <summary>
        /// 科室列表
        /// </summary>
        /// <returns></returns>
        public List<TitleValue> Department(int allotId)
        {
            var list = _perdeptdicRepository.GetEntities(t => t.AllotId == allotId);
            if (list == null || !list.Any()) return new List<TitleValue>();

            var result = list.Select(t => t.AccountingUnit).Distinct().OrderBy(t => t).ToList();
            return result?.Select(t => new TitleValue { Title = t, Value = t }).ToList();
        }

        /// <summary>
        /// 递归获取所有下属角色
        /// </summary>
        /// <param name="roles"></param>
        /// <param name="roleId"></param>
        /// <param name="result"></param>
        private void GetChildrenRole(List<sys_role> roles, int roleId, List<sys_role> result)
        {
            foreach (var role in roles.Where(s => !string.IsNullOrEmpty(s.ParentRoles)))
            {
                if (role.ParentRoles.SplitRemoveEmpty(",").Contains(roleId.ToString()))
                {
                    result.Add(role);
                    GetChildrenRole(roles, role.ID, result);
                }
            }
        }

        public List<TitleValue<int>> GetDemoUsers()
        {
            var roles = _roleRepository.GetEntities();
            if (roles == null || !roles.Any()) return new List<TitleValue<int>>();

            roles = roles.OrderBy(t => t.Sort).ToList();
            roles.RemoveAll(t => t.Type == 1);
            var users = _userhospitalRepository.GetEntities(t => t.HospitalID == 13);
            if (users == null || !users.Any()) return roles.Select(t => new TitleValue<int> { Title = t.RoleName, Value = 0 }).ToList();

            var userrole = _userroleRepository.GetEntities(t => users.Select(u => u.UserID).Contains(t.UserID));
            if (userrole == null || !userrole.Any()) return roles.Select(t => new TitleValue<int> { Title = t.RoleName, Value = 0 }).ToList();

            return roles.Select(t => new TitleValue<int>
            {
                Title = t.RoleName,
                Value = userrole.FirstOrDefault(ur => ur.RoleID == t.ID)?.UserID ?? 0
            }).ToList();
        }

        public UserIdentity GetDemoUserIdentity(int userId)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId);
            if (user == null)
                throw new PerformanceException($"用户不存在,请先创建!");

            var data = _mapper.Map<UserIdentity>(user);
            data.Token = Guid.NewGuid().ToString("N");
            return data;
        }

        /// <summary>
        /// 重置用户密码
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="loginUserId"></param>
        /// <returns></returns>
        public UserResponse ResetPwd(int userId, int loginUserId, string password)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId && t.IsDelete == 1);
            if (user == null)
                throw new PerformanceException($"用户不存在 UserId：{userId}");

            var loginUser = _userRepository.GetEntity(t => t.ID == loginUserId);
            if (loginUser == null)
                throw new PerformanceException($"用户不存在!");

            if (loginUser.Password != PwdHelper.MD5AndSalt(password))
                throw new PerformanceException($"您的密码错误，请重新输入后重试");

            //MD5小写加密
            user.Password = PwdHelper.MD5AndSalt2(AppConst.InitPwd);
            user.IsInitialPassword = (int)InitialPassword.初始; // 初始密码强制修改
            if (!_userRepository.Update(user))
                throw new PerformanceException("重置失败");
            return _mapper.Map<UserResponse>(user);
        }

        #region 多角色

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="request"></param>
        public UserResponse InsertUser(UserRequest request, int userid)
        {
            if (null != _userRepository.GetEntity(t => t.Login == request.Login && (t.ParentID == null || t.ParentID == 0) && t.IsDelete == 1))
                throw new PerformanceException("登录名重复");

            int[] roleArray = UnitTypeUtil.Maps.Keys.ToArray();
            if (roleArray.Intersect(request.RoleArr).Any() && string.IsNullOrEmpty(request.Department))
                throw new PerformanceException("二次绩效管理员科室不能为空");

            var user = _mapper.Map<sys_user>(request);
            user.CreateDate = DateTime.Now;
            user.CreateUser = userid;
            user.Password = PwdHelper.MD5AndSalt(request.Password);
            user.States = (int)States.Enabled;
            user.IsInitialPassword = (int)InitialPassword.初始;
            user.Department = UnitTypeUtil.Maps.ContainsKey(request.RoleArr[0]) ? request.Department : "";
            user.Remark = request.Remark;

            if (UnitTypeUtil.Maps.ContainsKey(request.RoleArr[0]))
            {
                var uninTypes = UnitTypeUtil.GetMaps(request.RoleArr[0]);
                var account = _perforCofaccountingRepository.GetEntity(w => w.AccountingUnit == request.Department && uninTypes.Contains(w.UnitType));
                user.UnitType = account?.UnitType ?? "";
                user.UnitCode = account?.Code ?? "";
            }
            user.IsDelete = 1;

            if (!_userRepository.Add(user))
                throw new PerformanceException("保存失败");

            //添加用户角色关联关系
            _userroleRepository.Add(new sys_user_role { UserID = user.ID, RoleID = request.RoleArr[0] });
            //添加用户医院
            SetHospital(user.ID, request.HosIDArray);

            var userID = user.ID;
            for (int i = 1; i < request.RoleArr.Length; i++)
            {
                user.Login = request.Login;
                user.ParentID = userID;
                user.Department = UnitTypeUtil.Maps.ContainsKey(request.RoleArr[i]) ? request.Department : "";
                if (roleArray.Contains(request.RoleArr[i]))
                {
                    var uninTypes = UnitTypeUtil.GetMaps(request.RoleArr[i]);
                    var account = _perforCofaccountingRepository.GetEntity(w => w.AccountingUnit == request.Department && uninTypes.Contains(w.UnitType));
                    user.UnitType = account?.UnitType ?? "";
                    user.UnitCode = account?.Code ?? "";
                }
                user.ID++;
                _userRepository.Add(user);

                //添加用户角色关联关系
                _userroleRepository.Add(new sys_user_role { UserID = user.ID, RoleID = request.RoleArr[i] });
                //添加用户医院
                SetHospital(user.ID, request.HosIDArray);
            }
            return _mapper.Map<UserResponse>(user);
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public UserResponse UpdateUser(UserRequest request, int userId)
        {
            var roleIds = request.RoleArr != null && request.RoleArr.Length > 0 ? request.RoleArr.Distinct().ToArray() : new int[0];
            if (roleIds.Length == 0)
                throw new PerformanceException("请选择用户角色");

            var isAgainAdmin = request.RoleArr.Any(w => UnitTypeUtil.Maps.ContainsKey(w));

            if (isAgainAdmin && string.IsNullOrEmpty(request?.Department))
                throw new PerformanceException("二次绩效管理员科室不能为空");

            var user = _userRepository.GetEntity(t => t.ID == request.ID && t.IsDelete == 1);

            if (null == user) throw new PerformanceException($"当前用户不存在");

            var vlist = _userRepository.GetEntities(t => t.ID != user.ID && t.Login == request.Login && (t.ParentID == null || t.ParentID == 0) && t.IsDelete == 1);
            if (null != vlist && vlist.Count() > 0) throw new PerformanceException("登录名重复");

            user.Login = request.Login;
            user.Mobile = request.Mobile;
            user.RealName = request.RealName;
            user.Mail = request.Mail;
            user.States = request.States;
            user.Remark = request.Remark;
            //Md5小写加密
            user.Password = string.IsNullOrEmpty(request.Password) ? user.Password : PwdHelper.MD5AndSalt(request.Password);
            user.Department = UnitTypeUtil.Maps.ContainsKey(request.RoleArr[0]) ? request.Department : "";
            if (UnitTypeUtil.Maps.ContainsKey(request.RoleArr[0]))
            {
                var uninTypes = UnitTypeUtil.GetMaps(request.RoleArr[0]);
                var account = _perforCofaccountingRepository.GetEntity(w => w.AccountingUnit == request.Department && uninTypes.Contains(w.UnitType));
                user.UnitType = account?.UnitType ?? "";
                user.UnitCode = account?.Code ?? "";
            }

            if (!_userRepository.Update(user))
                throw new PerformanceException("保存失败");

            //删除用户角色关联关系
            var userRole = _userroleRepository.GetEntity(t => t.UserID == user.ID);
            if (null != userRole)
                _userroleRepository.Remove(userRole);

            //添加用户角色关联关系
            _userroleRepository.Add(new sys_user_role { UserID = user.ID, RoleID = request.RoleArr[0] });
            //添加用户医院
            SetHospital(user.ID, request.HosIDArray);

            //删除子用户角色关联关系
            var userSubset = _userRepository.GetEntities(c => c.ParentID == user.ID);
            if (userSubset != null)
            {
                foreach (var item in userSubset)
                {
                    var diffUserRole = _userroleRepository.GetEntity(t => t.UserID == item.ID);
                    if (null != diffUserRole)
                        _userroleRepository.Remove(diffUserRole);
                }
                _userRepository.RemoveRange(userSubset.ToArray());
            }


            var userID = user.ID;
            var userLogin = user.Login;
            for (int i = 1; i < request.RoleArr.Length; i++)
            {
                sys_user diffUser = new sys_user();
                diffUser.CreateDate = DateTime.Now;
                diffUser.CreateUser = user.CreateUser;
                diffUser.IsDelete = 1;
                diffUser.Login = userLogin;
                diffUser.ParentID = userID;
                diffUser.Mobile = request.Mobile;
                diffUser.RealName = request.RealName;
                diffUser.Mail = request.Mail;
                diffUser.States = request.States;
                diffUser.Remark = request.Remark;
                //Md5小写加密
                diffUser.Password = string.IsNullOrEmpty(request.Password) ? user.Password : PwdHelper.MD5AndSalt(request.Password);
                diffUser.Department = UnitTypeUtil.Maps.ContainsKey(request.RoleArr[i]) ? request.Department : "";
                if (UnitTypeUtil.Maps.ContainsKey(request.RoleArr[i]))
                {
                    var uninTypes = UnitTypeUtil.GetMaps(request.RoleArr[i]);
                    var account = _perforCofaccountingRepository.GetEntity(w => w.AccountingUnit == request.Department && uninTypes.Contains(w.UnitType));
                    diffUser.UnitType = account?.UnitType ?? "";
                    diffUser.UnitCode = account?.Code ?? "";
                }

                if (!_userRepository.Add(diffUser))
                    throw new PerformanceException("保存失败");
                //添加子用户角色关联关系
                _userroleRepository.Add(new sys_user_role { UserID = diffUser.ID, RoleID = request.RoleArr[i] });
                //添加子用户医院
                SetHospital(diffUser.ID, request.HosIDArray);
            }
            return _mapper.Map<UserResponse>(user);
        }

        public ApiResponse DeleteUser(int iD)
        {
            var user = _userRepository.GetEntity(t => t.ID == iD && t.IsDelete == 1);
            if (null == user)
                throw new PerformanceException($"用户不存在 UserId：{iD}");
            user.IsDelete = 2;
            var result = _userRepository.Remove(user);

            var users = _userRepository.GetEntities(t => t.ParentID == user.ID && t.IsDelete == 1)?.ToArray();
            if (users != null)
            {
                _userRepository.RemoveRange(users);
                foreach (var item in users)
                {
                    var userRole = _userroleRepository.GetEntity(t => t.UserID == item.ID);
                    if (null != userRole)
                        _userroleRepository.Remove(userRole);
                }
            }

            return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail);
        }

        #endregion

        public HandsonTableBase GetUserHandsFlat()
        {
            HandsonTableBase table = new HandsonTableBase()
            {
                Columns = Users.Select(t => new HandsonColumn(t.Value)).ToList(),
                ColHeaders = Users.Select(t => t.Value).ToList(),
            };
            if (table.Columns != null && table.Columns.Any())
            {
                foreach (var column in table.Columns)
                {
                    if (Users.Any(w => w.Key == nameof(sys_role.RoleName)) && Users.First(w => w.Key == nameof(sys_role.RoleName)).Value == column.Data)
                    {
                        column.Type = "autocomplete";
                        column.Source = _roleRepository.GetEntities().Select(t => t.RoleName).ToArray();
                        column.Strict = true;
                    }
                    if (Users.Any(w => w.Key == nameof(sys_hospital.HosName)) && Users.First(w => w.Key == nameof(sys_hospital.HosName)).Value == column.Data)
                    {
                        column.Type = "autocomplete";
                        column.Source = _hospitalRepository.GetEntities().Select(t => t.HosName).ToArray();
                        column.Strict = true;
                    }
                }
            }
            return table;
        }

        /// <summary>
        /// 批量保存用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ApiResponse SaveUserHandsFlat(UserCollectData request)
        {
            try
            {
                var dicData = CreateDataRow(request, Users);
                var allDataList = dicData.Select(item => JsonHelper.Deserialize<UserHandsResponse>(JsonHelper.Serialize(item))).ToList();

                var getUsers = _userRepository.GetEntities();
                var roles = _roleRepository.GetEntities();

                var hosnames = allDataList.Select(w => w.HosName).Distinct().Where(w => !string.IsNullOrEmpty(w)).ToList();
                var hospitals = _hospitalRepository.GetEntities(w => hosnames.Contains(w.HosName));
                var hospitalIds = hospitals.Select(w => w.ID).ToArray();
                var accounts = _perforCofaccountingRepository.GetAccounting(hospitalIds) ?? new List<CofAccountingEntity>();

                List<sys_user> users = new List<sys_user>();
                List<sys_user_role> userRoles = new List<sys_user_role>();
                List<sys_user_hospital> userHoss = new List<sys_user_hospital>();

                List<Dictionary<string, string>> error = new List<Dictionary<string, string>>();
                for (int i = 0; i < allDataList.Count(); i++)
                {
                    // 姓名、登录名、角色、分配医院
                    if (string.IsNullOrEmpty(allDataList[i].Login?.Trim())
                        || string.IsNullOrEmpty(allDataList[i].RealName?.Trim())
                        || string.IsNullOrEmpty(allDataList[i].RoleName?.Trim())
                        || string.IsNullOrEmpty(allDataList[i].HosName?.Trim())
                        || string.IsNullOrEmpty(allDataList[i].Department?.Trim()))
                    {

                        error.Add(new Dictionary<string, string>
                        {
                            { "行号", $"第{i+1}行" },
                            { "姓名", allDataList[i].Login ?? "" },
                            { "登录名", allDataList[i].RealName ?? "" },
                            { "角色", allDataList[i].RoleName ?? "" },
                            { "分配医院", allDataList[i].HosName ?? "" },
                            { "核算单元", allDataList[i].Department ?? "" },
                            { "错误原因", "“关键信息缺失”请补全或删除" },
                        });
                        continue;
                    }
                    if (!Enum.IsDefined(typeof(Role), allDataList[i].RoleName))
                    {
                        error.Add(new Dictionary<string, string>
                        {
                            { "行号", $"第{i+1}行" },
                            { "姓名", allDataList[i].Login ?? "" },
                            { "登录名", allDataList[i].RealName ?? "" },
                            { "角色", allDataList[i].RoleName ?? "" },
                            { "分配医院", allDataList[i].HosName ?? "" },
                            { "核算单元", allDataList[i].Department ?? "" },
                            { "错误原因", "“角色”错误，请修改或删除" },
                        });
                    }
                    if (!hospitals.Any(w => w.HosName == (allDataList[i].HosName?.Trim())))
                    {
                        error.Add(new Dictionary<string, string>
                        {
                            { "行号", $"第{i+1}行" },
                            { "姓名", allDataList[i].Login ?? "" },
                            { "登录名", allDataList[i].RealName ?? "" },
                            { "角色", allDataList[i].RoleName ?? "" },
                            { "分配医院", allDataList[i].HosName ?? "" },
                            { "核算单元", allDataList[i].Department ?? "" },
                            { "错误原因", "“分配医院”错误，请修改或删除" },
                        });
                    }

                    if (getUsers.Any(c => c.Login == allDataList[i].Login?.Trim()))
                    {
                        error.Add(new Dictionary<string, string>
                        {
                            { "行号", $"第{i+1}行" },
                            { "姓名", allDataList[i].Login ?? "" },
                            { "登录名", allDataList[i].RealName ?? "" },
                            { "角色", allDataList[i].RoleName ?? "" },
                            { "分配医院", allDataList[i].HosName ?? "" },
                            { "核算单元", allDataList[i].Department ?? "" },
                            { "错误原因", "“登录名”已存在，请修改或删除" },
                        });
                    }
                    if (UnitTypeUtil.SecondAdmin.Any(r => r.ToString() == allDataList[i].RoleName?.Trim()))
                    {
                        var hospitalId = hospitals.FirstOrDefault(w => w.HosName == (allDataList[i].HosName?.Trim()))?.ID ?? -1;
                        var role = (Role)Enum.Parse(typeof(Role), allDataList[i].RoleName);
                        var uninTypes = UnitTypeUtil.GetMaps((int)role);
                        var cts = accounts.FirstOrDefault(w => w.HospitalId == hospitalId && w.AccountingUnit == allDataList[i].Department?.Trim() && uninTypes.Contains(w.UnitType));
                        if (cts == null)
                        {
                            error.Add(new Dictionary<string, string>
                            {
                                { "行号", $"第{i+1}行" },
                                { "姓名", allDataList[i].Login ?? "" },
                                { "登录名", allDataList[i].RealName ?? "" },
                                { "角色", allDataList[i].RoleName ?? "" },
                                { "分配医院", allDataList[i].HosName ?? "" },
                                { "核算单元", allDataList[i].Department ?? "" },
                                { "错误原因", "“核算单元”错误，当前角色暂无该核算单元，请修改或删除" },
                            });
                        }
                    }
                }
                if (error.Count > 0)
                    return new ApiResponse(ResponseType.WarningTable, "验证不通过,当前操作已拒绝", error);

                foreach (var data in allDataList)
                {
                    if (users.Any(c => c.Login == data?.Login)) continue;

                    var hospitalId = hospitals.FirstOrDefault(w => w.HosName == (data.HosName?.Trim()))?.ID ?? -1;
                    var role = (Role)Enum.Parse(typeof(Role), data.RoleName);
                    var uninTypes = UnitTypeUtil.GetMaps((int)role);
                    var cts = accounts.FirstOrDefault(w => w.HospitalId == hospitalId && w.AccountingUnit == data.Department?.Trim() && uninTypes.Contains(w.UnitType));
                    var user = new sys_user
                    {
                        RealName = data.RealName,
                        CreateDate = DateTime.Now,
                        CreateUser = request.CreateUser,
                        Department = data?.Department.Trim() ?? "",
                        UnitType = cts?.UnitType ?? "",
                        UnitCode = cts?.Code ?? "",
                        IsDelete = 1,
                        Login = data.Login,
                        Password = PwdHelper.MD5AndSalt2(AppConst.InitPwd),
                        States = 1,
                        Mobile = data?.Mobile ?? "",
                        Mail = data?.Mail ?? "",
                        IsInitialPassword = (int)InitialPassword.初始,
                    };
                    users.Add(user);
                }
                _userRepository.AddRange(users.ToArray());

                var joinData = users.Join(allDataList,
                    outer => new { outer.Login, outer.RealName, Department = outer.Department ?? "" },
                    inner => new { inner.Login, inner.RealName, Department = inner.Department ?? "" },
                    (outer, inner) => new { outer, inner });


                var roleJoin = joinData.Select(t => new sys_user_role
                {
                    UserID = t.outer.ID,
                    RoleID = (int)roles.FirstOrDefault(r => r.RoleName == t.inner.RoleName)?.Type
                });
                _userroleRepository.AddRange(roleJoin.ToArray());

                var hosJoin = joinData.Select(t => new sys_user_hospital
                {
                    UserID = t.outer.ID,
                    HospitalID = hospitals.FirstOrDefault(h => h.HosName == t.inner.HosName)?.ID
                });
                _userhospitalRepository.AddRange(hosJoin.ToArray());

                return new ApiResponse(ResponseType.OK, "保存成功");
            }
            catch (Exception)
            {
                throw;
            }
        }

        public static Dictionary<string, string> Users { get; } = new Dictionary<string, string>
        {
            {nameof(sys_user.RealName), "姓名"},
            {nameof(sys_user.Login), "登录名"},
            {nameof(sys_user.Password), "密码"},
            {nameof(sys_user.Mobile), "手机号码"},
            {nameof(sys_user.Mail), "邮箱"},
            {nameof(sys_role.RoleName), "角色"},
            {nameof(sys_hospital.HosName), "分配医院"},
            {nameof(sys_user.Department), "核算单元"},
        };

        private List<Dictionary<string, string>> CreateDataRow(UserCollectData request, Dictionary<string, string> config)
        {
            List<Dictionary<string, string>> allData = new List<Dictionary<string, string>>();

            for (int r = 0; r < request.Data.Length; r++)
            {
                // 创建固定数据列
                Dictionary<string, string> baseData = CreateBaseData(request, config, r);
                allData.Add(baseData);

            }
            return allData;
        }

        private Dictionary<string, string> CreateBaseData(UserCollectData request, Dictionary<string, string> config, int rownumber)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            for (int c = 0; c < request.ColHeaders.Length; c++)
            {
                var header = request.ColHeaders[c];
                var first = config.FirstOrDefault(w => w.Value == header);
                if (!default(KeyValuePair<string, string>).Equals(first)
                    && !result.ContainsKey(header)
                    && request.Data[rownumber].Length > c)
                {
                    result.Add(first.Key, request.Data[rownumber][c]);
                }
            }

            return result;
        }
    }
}