using AutoMapper;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Performance.Services
{
    public class UserService : IAutoInjection
    {
        private Application application;
        private PerforUserRepository _userRepository;
        private readonly IMapper _mapper;
        private PerforSmsRepository _smsRepository;
        private PerforHospitalRepository _hospitalRepository;
        private PerforUserhospitalRepository _userhospitalRepository;
        private PerforRoleRepository _roleRepository;
        private PerforUserroleRepository _userroleRepository;
        private PerforImemployeeRepository _employeeRepository;
        private PerforPerallotRepository _perforPerallotRepository;
        private PerforImaccountbasicRepository _imaccountbasicRepository;
        private PerforImspecialunitRepository _imspecialunitRepository;
        private PerforResaccountRepository _resaccountRepository;
        private PerforPerallotRepository _perallotRepository;
        private PerforPerdeptdicRepository _perdeptdicRepository;
        private readonly PerforCofaccountingRepository perforCofaccountingRepository;

        public UserService(
            IMapper mapper,
            IOptions<Application> application,
            PerforSmsRepository smsRepository,
            PerforUserRepository userRepository,
            PerforHospitalRepository hospitalRepository,
            PerforUserhospitalRepository userhospitalRepository,
            PerforRoleRepository roleRepository,
            PerforUserroleRepository userroleRepository,
            PerforImemployeeRepository employeeRepository,
            PerforPerallotRepository perforPerallotRepository,
            PerforImaccountbasicRepository imaccountbasicRepository,
            PerforImspecialunitRepository imspecialunitRepository,
            PerforResaccountRepository resaccountRepository,
            PerforPerallotRepository perallotRepository,
            PerforPerdeptdicRepository perdeptdicRepository,
            PerforCofaccountingRepository perforCofaccountingRepository)
        {
            this.application = application.Value;
            this._userRepository = userRepository;
            _mapper = mapper;
            this._smsRepository = smsRepository;
            this._hospitalRepository = hospitalRepository;
            this._userhospitalRepository = userhospitalRepository;
            this._roleRepository = roleRepository;
            this._userroleRepository = userroleRepository;
            this._employeeRepository = employeeRepository;
            this._perforPerallotRepository = perforPerallotRepository;
            this._imaccountbasicRepository = imaccountbasicRepository;
            this._imspecialunitRepository = imspecialunitRepository;
            this._resaccountRepository = resaccountRepository;
            this._perallotRepository = perallotRepository;
            this._perdeptdicRepository = perdeptdicRepository;
            this.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($"用户不存在 UserId:{request.Account}");
                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);
        }

        /// <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 userRoles = _userroleRepository.GetEntities();
            var userHospitals = _userhospitalRepository.GetEntities();
            var users = _userRepository.GetEntities();
            var hospitals = _hospitalRepository.GetEntities();
            var roles = _roleRepository.GetEntities();

            var userrole = userRoles?.FirstOrDefault(t => t.UserID == userID);

            if (roleType == 12)
            {
                var jxQuery = userRoles.Where(t => t.RoleID == roles?.FirstOrDefault(c => c.RoleName == "绩效查询")?.ID).Select(t => t.UserID);
                users = users.Where(t => jxQuery.Contains(t.ID)).ToList();
            }
            else
            {
                var jxQuery = userRoles.Where(t => roles.Where(c => c.RoleName != "绩效查询").Select(c => c.ID).Contains(t.RoleID)).Select(t => t.UserID);
                users = users.Where(t => jxQuery.Contains(t.ID)).ToList();
            }

            if (userrole == null)
                throw new PerformanceException("用户未配置角色");
            var role = roles?.FirstOrDefault(t => t.ID == userrole.RoleID);
            if (role == null)
                throw new PerformanceException("用户角色不存在");

            var result = new List<UserResponse>();

            if (role.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 result;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="iD"></param>
        /// <returns></returns>
        public ApiResponse Delete(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);
            return result ? new ApiResponse(ResponseType.OK) : new ApiResponse(ResponseType.Fail);
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="request"></param>
        public UserResponse Insert(UserRequest request, int userid)
        {
            if (null != _userRepository.GetEntity(t => t.Login == request.Login && t.IsDelete == 1))
                throw new PerformanceException("登录名重复");
            //if (null != _userRepository.GetEntity(t => t.Mobile == request.Mobile && t.IsDelete == 1))
            //    throw new PerformanceException("手机号重复");
            //if (request.Role == 3 && string.IsNullOrEmpty(request.Department))
            //    throw new PerformanceException("请选择科室");
            if (request.HosIDArray.Length > 1)
                throw new PerformanceException("二次绩效管理员只支持单家医院");

            int[] roleArray = new int[] { application.NurseRole, application.DirectorRole, application.SpecialRole, application.OfficeRole };
            if (roleArray.Contains(request.Role) && string.IsNullOrEmpty(request.Department))
                throw new PerformanceException("二次绩效管理员科室不能为空");

            var user = _mapper.Map<sys_user>(request);
            user.CreateDate = DateTime.Now;
            user.CreateUser = userid;
            user.States = (int)States.Enabled;
            user.Department = request.Department;
            user.IsDelete = 1;

            if (!_userRepository.Add(user))
                throw new PerformanceException("保存失败");
            //添加用户角色关联关系
            _userroleRepository.Add(new sys_user_role { UserID = user.ID, RoleID = request.Role });
            //添加用户医院
            SetHospital(user.ID, request.HosIDArray);

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

        /// <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 Update(UserRequest request, bool isAgainAdmin)
        {
            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.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("手机号重复");

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

            if (isAgainAdmin && request.HosIDArray.Length > 1)
                throw new PerformanceException("二次绩效管理员只支持单家医院");

            user.Login = request.Login;
            user.Mobile = request.Mobile;
            user.RealName = request.RealName;
            user.Mail = request.Mail;
            user.States = request.States;
            user.Password = string.IsNullOrEmpty(request.Password) ? user.Password : request.Password;
            user.Department = request.Department;

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

            //删除用户角色关联关系
            var userRole = _userroleRepository.GetEntity(t => t.UserID == request.ID);
            if (null != userRole)
                _userroleRepository.Remove(userRole);
            //添加用户角色关联关系
            _userroleRepository.Add(new sys_user_role { UserID = request.ID, RoleID = request.Role });
            //添加用户医院
            SetHospital(user.ID, request.HosIDArray);

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

        /// <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.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;
            user.Password = string.IsNullOrEmpty(request.Password) ? user.Password : request.Password;

            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 (request.OldPwd != user.Password)
                throw new PerformanceException("原密码错误");

            user.Password = string.IsNullOrEmpty(request.NewPwd) ? user.Password : request.NewPwd;

            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 hospitalId)
        {
            //var allotList = _perforPerallotRepository.GetEntities(t => t.HospitalId == hospitalId);
            //var result = new List<string>();
            //if (allotList != null)
            //{
            //    var idList = allotList.Select(s => s.ID).ToList();
            //    //var department = _employeeRepository.GetEntities(t => t.Department != "" && idList.Contains(t.AllotID.Value)).Select(t => t.Department);
            //    //if (department != null && department.Count() > 0)
            //    //    result.AddRange(department);

            //    var department = _imaccountbasicRepository.GetEntities(t => !string.IsNullOrEmpty(t.DoctorAccountingUnit) && idList.Contains(t.AllotID.Value))?.Select(t => t.DoctorAccountingUnit);
            //    if (department != null && department.Count() > 0)
            //        result.AddRange(department);

            //    // 特殊科室
            //    department = _imspecialunitRepository.GetEntities(t => !string.IsNullOrEmpty(t.AccountingUnit) && idList.Contains(t.AllotID.Value))?.Select(t => t.AccountingUnit);
            //    if (department != null && department.Count() > 0)
            //        result.AddRange(department);

            //    if (result != null && result.Any())
            //    {
            //        result = result.Distinct().OrderBy(t => t).ToList();
            //    }
            //}

            var list = _perdeptdicRepository.GetEntities(t => t.HospitalId == hospitalId);
            if (list == null || !list.Any()) return new List<TitleValue>();

            var result = list.Select(t => t.AccountingUnit).Distinct().OrderBy(t => t).ToList();
            //// 补充行政科室
            //var states = new int[] { (int)AllotStates.Archive, (int)AllotStates.GenerateAccomplish };
            //var allots = _perallotRepository.GetEntities(w => w.HospitalId == hospitalId && states.Contains(w.States));
            //if (allots != null && allots.Any())
            //{
            //    var allot = allots.OrderByDescending(w => w.Year).ThenByDescending(w => w.Month).FirstOrDefault();
            //    if (allot != null)
            //    {
            //        var types = new int[] { (int)UnitType.行政中层, (int)UnitType.行政后勤 };
            //        var accounts = _resaccountRepository.GetEntities(w => w.AllotID == allot.ID && w.UnitType.HasValue && types.Contains(w.UnitType.Value));
            //        if (accounts != null && accounts.Any())
            //        {
            //            result.AddRange(accounts.Select(w => w.AccountingUnit));
            //        }
            //    }
            //}

            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)
        {
            var user = _userRepository.GetEntity(t => t.ID == userId && t.IsDelete == 1);
            if (user == null)
                throw new PerformanceException($"用户不存在 UserId：{userId}");

            //if (user.CreateUser != loginUserId)
            //    throw new PerformanceException($"当前用户无权限重置用户密码");

            user.Password = "123456";
            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.IsDelete == 1))
                throw new PerformanceException("登录名重复");

            int[] roleArray = new int[] { application.NurseRole, application.DirectorRole, application.SpecialRole, application.OfficeRole };
            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.States = (int)States.Enabled;
            user.Department = roleArray.Contains(request.RoleArr[0]) ? request.Department : "";
            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 + i;
                user.ParentID = userID;
                user.Department = roleArray.Contains(request.RoleArr[i]) ? request.Department : "";
                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, bool isAgainAdmin)
        {
            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.IsDelete == 1);
            if (null != vlist && vlist.Count() > 0)
                throw new PerformanceException("登录名重复");

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

            int[] roleArray = new int[] { application.NurseRole, application.DirectorRole, application.SpecialRole, application.OfficeRole };
            user.Login = request.Login;
            user.Mobile = request.Mobile;
            user.RealName = request.RealName;
            user.Mail = request.Mail;
            user.States = request.States;
            user.Password = string.IsNullOrEmpty(request.Password) ? user.Password : request.Password;
            user.Department = roleArray.Contains(request.RoleArr[0]) ? request.Department : "";
            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 + i;
                diffUser.ParentID = userID;
                diffUser.Mobile = request.Mobile;
                diffUser.RealName = request.RealName;
                diffUser.Mail = request.Mail;
                diffUser.States = request.States;
                diffUser.Password = string.IsNullOrEmpty(request.Password) ? user.Password : request.Password;
                diffUser.Department = roleArray.Contains(request.RoleArr[i]) ? request.Department : "";
                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 HandsonTable GetUserHandsFlat()
        {
            var result = new HandsonTable((int)SheetType.Unidentifiable, Users.Select(t => t.Value).ToArray(), Users.Select(t => new collect_permission
            {
                HeadName = t.Value,
                Visible = 1
            }).ToList());
            if (result.Columns != null && result.Columns.Any())
            {
                foreach (var column in result.Columns)
                {
                    if (column.Data == "角色")
                    {
                        column.Type = "autocomplete";
                        column.Source = _roleRepository.GetEntities().Select(t => t.RoleName).ToArray();
                        column.Strict = true;
                    }
                    else if (column.Data == "分配医院")
                    {
                        column.Type = "autocomplete";
                        column.Source = _hospitalRepository.GetEntities().Select(t => t.HosName).ToArray();
                        column.Strict = true;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 批量保存用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SaveUserHandsFlat(UserCollectData request)
        {
            try
            {
                var dicData = CreateDataRow(request, Users);
                var getUsers = _userRepository.GetEntities();
                var roles = _roleRepository.GetEntities();
                var hospitals = _hospitalRepository.GetEntities();
                var accounts = perforCofaccountingRepository.GetEntities();

                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>();
                var roleArr = new[] { "护士长", "科主任", "特殊科室", "行政科室" };

                var allDataList = dicData.Select(item => JsonHelper.Deserialize<UserHandsResponse>(JsonHelper.Serialize(item)));
                var names = allDataList?.Select(w => w?.HosName).Distinct();

                Dictionary<string, List<string>> res = new Dictionary<string, List<string>>();
                foreach (var item in names)
                {
                    if (string.IsNullOrEmpty(item)) return "必填项为空";
                    var HospitalId = hospitals.FirstOrDefault(w => w.HosName == item)?.ID;

                    if (HospitalId == null) return "未找到分配医院";

                    var allot = _perallotRepository.GetEntities(t => t.HospitalId == HospitalId);
                    var accountingUnits = accounts?.Join(allot, t => t.AllotId, w => w.ID, (t, w) => t.AccountingUnit).Distinct().ToList();
                    res.Add(item, accountingUnits);
                }

                foreach (var data in allDataList)
                {
                    if (string.IsNullOrEmpty(data.Login) || string.IsNullOrEmpty(data.RealName)
                        || string.IsNullOrEmpty(data.RoleName) || string.IsNullOrEmpty(data.HosName))
                        return "必填项为空";

                    if (roleArr.Contains(data.RoleName) && res != null && res[data.HosName] != null && !res[data.HosName].Any(t => t == data.Department))
                        return "核算单元填写错误";

                    if (users.Any(c => c.Login == data?.Login) && !string.IsNullOrEmpty(data.Login)
                        || getUsers.Any(c => c.Login == data?.Login)) continue;

                    var user = new sys_user
                    {
                        RealName = data.RealName,
                        CreateDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd hh:mm:dd")),
                        CreateUser = request.CreateUser,
                        Department = data?.Department ?? "",
                        IsDelete = 1,
                        Login = data.Login,
                        Password = data?.Password ?? "123456",
                        States = 1,
                        Mobile = data?.Mobile ?? "",
                        Mail = data?.Mail ?? ""
                    };
                    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 "";
            }
            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;
        }
    }
}