using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using MTWorkHR.Application.Identity;
using MTWorkHR.Application.Mapper;
using MTWorkHR.Application.Models;
using MTWorkHR.Core.Global;
using MTWorkHR.Core.IRepositories;
using MTWorkHR.Core.UnitOfWork;
using MTWorkHR.Application.Services.Interfaces;
using MTWorkHR.Core.Email;
using MTWorkHR.Core.Entities;
using MTWorkHR.Infrastructure.UnitOfWorks;
using MTWorkHR.Infrastructure.Entities;
using static Org.BouncyCastle.Crypto.Engines.SM2Engine;
using System.Web;
using System.Data;
using MTWorkHR.Core.IDto;
using System.Linq.Dynamic.Core;
using MTWorkHR.Core.Entities.Base;
using MTWorkHR.Infrastructure.EmailService;
using Countries.NET.Database;
using Microsoft.AspNetCore.Http;
using System.Collections;

namespace MTWorkHR.Application.Services
{
    public class UserService : IUserService
    {
        private readonly RoleManager<ApplicationRole> _roleManager;
        private readonly ApplicationUserManager _userManager;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IUserRoleRepository<IdentityUserRole<string>> _userRole;
        private readonly AppSettingsConfiguration _configuration;
        private readonly IMailSender _emailSender;
        private readonly GlobalInfo _globalInfo;
        private readonly IFileService _fileService;
        private readonly IOTPService _oTPService;

        public UserService(ApplicationUserManager userManager, IUnitOfWork unitOfWork
             , RoleManager<ApplicationRole> roleManager, GlobalInfo globalInfo, AppSettingsConfiguration configuration, IMailSender emailSender
            , IUserRoleRepository<IdentityUserRole<string>> userRole, IFileService fileService, IOTPService oTPService)
        {
            _userManager = userManager;
            _unitOfWork = unitOfWork;
            _roleManager = roleManager;
            _userRole = userRole;
            _configuration = configuration;
            _emailSender = emailSender;
            _globalInfo = globalInfo;
            _fileService = fileService;
            _oTPService = oTPService;
        }

        public async Task<UserDto> GetById()
        {
            return await GetById(_globalInfo.UserId);
        }
        public async Task<UserDto> GetById(string id)
        {
            var entity = await _userManager.Users
                .Include(x => x.UserRoles)
                .Include(x => x.UserAddress).ThenInclude(x=> x.City)
                .Include(x => x.UserAddress).ThenInclude(x=> x.Country)
                .Include(x => x.UserAttachments)
                .Include(x => x.JobTitle)
                .Include(x => x.Industry)
                .Include(x => x.University)
                .Include(x => x.Country)
                .Include(x => x.Qualification)
                .FirstOrDefaultAsync(x => x.Id == id);
            var response = MapperObject.Mapper.Map<UserDto>(entity);
            if (response.UserAttachments != null)
                foreach (var attach in response.UserAttachments.Where(a => a.Content != null))
                {
                    //var stream = new MemoryStream(attach.Content);
                    //IFormFile file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName);

                    using (var stream = new MemoryStream(attach.Content))
                    {
                        var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName)
                        {
                            Headers = new HeaderDictionary(),
                            ContentType = attach.ContentType,
                        };

                        System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
                        {
                            FileName = file.FileName
                        };
                        file.ContentDisposition = cd.ToString();
                        switch (attach.AttachmentTypeId)
                        {
                            case 1:
                                response.CVAttach = file;
                                break;
                            case 2:
                                response.PassportAttach = file;
                                break;
                            case 3:
                                response.EduCertificateAttach = file;
                                break;
                            case 4:
                                response.ExperienceCertificateAttach= file;
                                break;
                            case 5:
                                response.ProfCertificateAttach = file;
                                break;
                            case 6:
                                response.CommercialRegAttach = file;
                                break;
                            case 7:
                                response.TaxDeclarationAttach = file;
                                break;
                            case 8:
                                response.IdAttach = file;
                                break;
                            case 9:
                                response.ProfileImage = file;
                                break;
                        }
                        attach.Content = new byte[0];
                    }
                   
                }
            return response;
        }
        public async Task<UserDto> GetUserById(string id)
        {
            var entity = await _userManager.Users
                .FirstOrDefaultAsync(x => x.Id == id);
            var response = MapperObject.Mapper.Map<UserDto>(entity);

            return response;
        }
        public async Task<string> GetUserFullName(string userId)
        {
            var entity = await GetUserById(userId);
            var name = entity == null ? "" : entity.FirstName + " " + entity.LastName;
            return name;
        }
        public async Task<UserDto> GetUserWithAttachmentById(string id)
        {
            var entity = await _userManager.Users.Include(u=> u.UserAttachments)
                .FirstOrDefaultAsync(x => x.Id == id);
            var response = MapperObject.Mapper.Map<UserDto>(entity);

            return response;
        }
        //public async Task<List<UserDto>> GetAll(PagingInputDto pagingInput)
        //{
        //    var employees = await _userManager.GetUsersInRoleAsync("Employee");
        //    return employees.Select(e => new UserDto
        //    {
        //        Email = e.Email,
        //        FirstName = e.FirstName,
        //        LastName = e.LastName,
        //        Id = e.Id
        //    }).ToList();
        //}
        public virtual async Task<PagingResultDto<UserAllDto>> GetAll(UserPagingInputDto PagingInputDto)
        {
            var query = _userManager.Users
                .Include(u => u.Qualification).Include(u => u.JobTitle).Include(u => u.University).Include(u => u.Industry).Include(u => u.Country)
                .Where(e => _globalInfo.CompanyId == null || e.CompanyId != _globalInfo.CompanyId)
                .AsQueryable();

            if (PagingInputDto.Filter != null)
            {
                var filter = PagingInputDto.Filter;
                query = query.Where(u => 
                    u.UserName.Contains(filter) ||
                    u.Email.Contains(filter) ||
                    u.FirstName.Contains(filter) ||
                    u.LastName.Contains(filter) ||
                    u.FavoriteName.Contains(filter) ||
                    u.Position.Contains(filter) ||
                    u.PhoneNumber.Contains(filter));
            }
            if (PagingInputDto.IndustryId != null)
            {
                query = query.Where(u => u.IndustryId == PagingInputDto.IndustryId);
            }
            if (PagingInputDto.QualificationId != null)
            {
                query = query.Where(u => u.QualificationId == PagingInputDto.QualificationId);
            }
            if (PagingInputDto.JobTitleId != null)
            {
                query = query.Where(u => u.JobTitleId == PagingInputDto.JobTitleId);
            }
            if (PagingInputDto.UniversityId != null)
            {
                query = query.Where(u => u.UniversityId == PagingInputDto.UniversityId);
            }
            if (PagingInputDto.CountryId != null)
            {
                query = query.Where(u => u.CountryId == PagingInputDto.CountryId);
            }
            if (PagingInputDto.UserTypeId != null)
            {
                query = query.Where(u => u.UserType == PagingInputDto.UserTypeId);
            }
            if (PagingInputDto.Employed != null && PagingInputDto.Employed == true)
            {
                query = query.Where(u => u.CompanyId != null);
            }
            if (PagingInputDto.Employed != null && PagingInputDto.Employed == false)
            {
                query = query.Where(u => u.CompanyId == null);
            }

            var order = query.OrderBy(PagingInputDto.OrderByField + " " + PagingInputDto.OrderType);

            var page = order.Skip((PagingInputDto.PageNumber * PagingInputDto.PageSize) - PagingInputDto.PageSize).Take(PagingInputDto.PageSize);

            var total = await query.CountAsync();

            var list = MapperObject.Mapper
                .Map<IList<UserAllDto>>(await page.ToListAsync());

            var response = new PagingResultDto<UserAllDto>
            {
                Result = list,
                Total = total
            };

            return response;
        }
        public async Task<List<UserDto>> GetAllEmployees()
        {
            var employees = await _userManager.GetUsersInRoleAsync("Employee");
            return employees.Select(e => new UserDto
            {
                Email = e.Email,
                FirstName = e.FirstName,
                LastName = e.LastName,
                Id = e.Id
            }).ToList();
        }


        public async Task<List<UserAllDto>> GetAllCompanyEmployees()
        {
            var employees = await _userManager.GetUsersInRoleAsync("Employee");
            var res = employees.Where(e => e.CompanyId == _globalInfo.CompanyId).ToList();
            var response = MapperObject.Mapper.Map<List<UserAllDto>>(res);

            return response;
        }

        public async Task Delete(string id)
        {
            var user = await _userManager.FindByIdAsync(id);
            if (user != null)
            {
                user.IsDeleted = true;

                await _userManager.UpdateAsync(user);
            }
        }


        public async Task<UserDto> Create(UserDto input)
        {
            var emailExists = await _userManager.FindByEmailAsync(input.Email);
            if (emailExists != null)
                throw new AppException(ExceptionEnum.RecordEmailAlreadyExist);

            var phoneExists = await _userManager.FindByAnyAsync(input.PhoneNumber);
            if (phoneExists != null)
                throw new AppException(ExceptionEnum.RecordPhoneAlreadyExist);

            var userExists = await _userManager.FindByAnyAsync(input.UserName);
            if (userExists != null)
                throw new AppException(ExceptionEnum.RecordNameAlreadyExist);
            //loop for given list of attachment, and move each file from Temp path to Actual path
            //  _fileService.UploadFiles(files);
            if (input.UserAttachments == null )
                input.UserAttachments = new List<AttachmentDto>();
            if (input.ProfileImage != null)
            {
                input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfileImage, OriginalName = input.ProfileImage?.Name, FileName = input.ProfileImage?.FileName, AttachmentTypeId = 9 });
            }
            if (input.CVAttach != null)
            {
                input.UserAttachments.Add(new AttachmentDto { FileData = input.CVAttach, OriginalName = input.CVAttach?.Name,FileName = input.CVAttach?.FileName, AttachmentTypeId = 1 });
            }
            if (input.PassportAttach != null)
            {
                input.UserAttachments.Add(new AttachmentDto { FileData = input.PassportAttach, OriginalName = input.PassportAttach?.Name, FileName = input.PassportAttach?.FileName, AttachmentTypeId = 2 });
            }
            if (input.EduCertificateAttach != null)
            {
                input.UserAttachments.Add(new AttachmentDto { FileData = input.EduCertificateAttach, OriginalName = input.EduCertificateAttach?.Name, FileName = input.EduCertificateAttach?.FileName, AttachmentTypeId = 3 });
            }
            if (input.ExperienceCertificateAttach != null)
            {
                input.UserAttachments.Add(new AttachmentDto { FileData = input.ExperienceCertificateAttach, OriginalName = input.ExperienceCertificateAttach?.Name, FileName = input.ExperienceCertificateAttach?.FileName, AttachmentTypeId = 4 });
            }
            if (input.ProfCertificateAttach != null)
            {
                input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfCertificateAttach, OriginalName = input.ProfCertificateAttach?.Name, FileName = input.ProfCertificateAttach?.FileName, AttachmentTypeId = 5 });
            }
            var files = input.UserAttachments.Select(a=> a.FileData).ToList();
            List<AttachmentDto> attachs = input.UserAttachments.ToList();
             _fileService.CopyFileToCloud(ref attachs);
            //if (!res)
            //    throw new AppException(ExceptionEnum.CouldNotMoveFiles);
            input.UserAttachments = attachs;
            var user = MapperObject.Mapper.Map<ApplicationUser>(input);
            if(user.UserType == 0)
            {
                user.UserType = (int)UserTypeEnum.Employee;//default if not selected
            }
            _unitOfWork.BeginTran();

            //saving user
            var result = await _userManager.CreateAsync(user, input.Password);
            if (!result.Succeeded)
            {
                if(result.Errors != null && result.Errors.Count() > 0)
                {
                    var msg = result.Errors.Select(a => a.Description ).Aggregate((a,b) => a + " /r/n " + b);
                    throw new AppException(msg);
                }
                throw new AppException(ExceptionEnum.RecordCreationFailed);
            }
                
            input.Id = user.Id;

            //saving userRoles
            if(input.UserRoles == null || input.UserRoles.Count == 0)
            {
                var employeeRole = await _roleManager.FindByNameAsync("Employee");
                if (employeeRole != null)
                {
                    await _userManager.AddToRoleAsync(user, "Employee");
                }
            }
            else
            {
                var userRoles = MapperObject.Mapper.Map<List<IdentityUserRole<string>>>(input.UserRoles);
                foreach (var role in userRoles)
                {
                    role.UserId = user.Id;
                    if (await _roleManager.FindByIdAsync(role.RoleId) == null)
                        throw new AppException(ExceptionEnum.RecordNotExist);
                    var roleOb = input.UserRoles?.FirstOrDefault(r => r.RoleId == role.RoleId);
                    var roleName = roleOb != null ? roleOb.RoleName : "Employee";
                    await _userManager.AddToRoleAsync(user, roleName);
                }
            }

            // await _userRole.AddRangeAsync(userRoles);

            await _unitOfWork.CompleteAsync();
            _unitOfWork.CommitTran();
            try
            {
                var resultPassReset = await GetConfirmEmailURL(user.Id);

                var sendMailResult = await _emailSender.SendEmail(new EmailMessage
                {
                    Subject = "Register Confirmation",
                    To = input.Email,
                    Body = "Please Set Your Password (this link will expired after 24 hours)"
                    ,
                    url = resultPassReset.Item1,
                    userId = user.Id
                });
                if (!sendMailResult)
                {
                    throw new AppException("User created, but could not send the email!");
                }
            }
            catch
            {
                throw new AppException("User created, but could not send the email!");
            }

            return input;
        }

        public async Task<BlobObject> Download(string filePath)
        {
            var file = await _fileService.Download(filePath);
                return file;
        }
        public async Task<bool> ConfirmEmail(ConfirmEmailDto input)
        {
            var user = await _userManager.FindByIdAsync(input.UserId);
            if (user == null)
                throw new AppException(ExceptionEnum.UserNotExist);
            var result = await _userManager.ConfirmEmailAsync(user, input.Token);
            return result.Succeeded;
        }
        private async Task<Tuple<string, string>> GetResetPasswordURL(string userId)
        {
            var user = await _userManager.Users.FirstOrDefaultAsync(x => !x.IsDeleted && x.Id.Equals(userId));
            if (user == null)
                throw new AppException(ExceptionEnum.UserNotExist);

            string code = await _userManager.GeneratePasswordResetTokenAsync(user);
            var route = "auth/ConfirmEmail";
            var origin = _configuration.JwtSettings.Audience;
            var endpointUri = new Uri(string.Concat($"{origin}/", route));
            var userURL = QueryHelpers.AddQueryString(endpointUri.ToString(), "userId", user.Id);
            var passwordResetURL = QueryHelpers.AddQueryString(userURL.ToString(), "token", code);
            return new Tuple<string, string>(passwordResetURL, user.Email);
        }

        private async Task<Tuple<string, string>> GetConfirmEmailURL(string userId)
        {
            var user = await _userManager.Users.FirstOrDefaultAsync(x => !x.IsDeleted && x.Id.Equals(userId));
            if (user == null)
                throw new AppException(ExceptionEnum.UserNotExist);

            string token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            string codeHtmlVersion = HttpUtility.UrlEncode(token);

            var route = "auth/ConfirmEmail";
            var origin = _configuration.JwtSettings.Audience;
            var endpointUri = new Uri(string.Concat($"{origin}/", route));
            var userURL = QueryHelpers.AddQueryString(endpointUri.ToString(), "userId", user.Id);
            var confirmEmailUrl = QueryHelpers.AddQueryString(userURL.ToString(), "token", codeHtmlVersion);
            return new Tuple<string, string>(confirmEmailUrl, user.Email);
        }

        public async Task<UserUpdateDto> Update(UserUpdateDto input)
        {
            try
            {
                var entity =  _userManager.Users.Include(x => x.UserAttachments).FirstOrDefault(x=> x.Id == input.Id);

                if (entity == null)
                    throw new AppException(ExceptionEnum.UserNotExist);
                if (input.UserAttachments == null)
                    input.UserAttachments = new List<AttachmentDto>();
                var oldAttachList = entity.UserAttachments;
                if (input.ProfileImage != null)
                {
                    var oldAttach = oldAttachList.Where(x => x.AttachmentTypeId == 9 || x.OriginalName == input.ProfileImage?.Name).FirstOrDefault();
                    if(oldAttach != null) entity.UserAttachments.Remove(oldAttach);
                    input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfileImage, OriginalName = input.ProfileImage?.Name, FileName = input.ProfileImage?.FileName, AttachmentTypeId = 9 });
                }
                if (input.CVAttach != null)
                {
                    var oldAttach = oldAttachList.Where(x => x.AttachmentTypeId == 1 || x.OriginalName == input.CVAttach?.Name).FirstOrDefault();
                    if (oldAttach != null) entity.UserAttachments.Remove(oldAttach);
                    input.UserAttachments.Add(new AttachmentDto { FileData = input.CVAttach, OriginalName = input.CVAttach?.Name, FileName = input.CVAttach?.FileName, AttachmentTypeId = 1 });
                }
                if (input.PassportAttach != null)
                {
                    var oldAttach = oldAttachList.Where(x => x.AttachmentTypeId == 2 || x.OriginalName == input.PassportAttach?.Name).FirstOrDefault();
                    if (oldAttach != null) entity.UserAttachments.Remove(oldAttach);
                    input.UserAttachments.Add(new AttachmentDto { FileData = input.PassportAttach, OriginalName = input.PassportAttach?.Name, FileName = input.PassportAttach?.FileName, AttachmentTypeId = 2 });
                }
                if (input.EduCertificateAttach != null)
                {
                    var oldAttach = oldAttachList.Where(x => x.AttachmentTypeId == 3 || x.OriginalName == input.EduCertificateAttach?.Name).FirstOrDefault();
                    if (oldAttach != null) entity.UserAttachments.Remove(oldAttach);
                    input.UserAttachments.Add(new AttachmentDto { FileData = input.EduCertificateAttach, OriginalName = input.EduCertificateAttach?.Name, FileName = input.EduCertificateAttach?.FileName, AttachmentTypeId = 3 });
                }
                if (input.ExperienceCertificateAttach != null)
                {
                    var oldAttach = oldAttachList.Where(x => x.AttachmentTypeId == 4 || x.OriginalName == input.ExperienceCertificateAttach?.Name).FirstOrDefault();
                    if (oldAttach != null) entity.UserAttachments.Remove(oldAttach);
                    input.UserAttachments.Add(new AttachmentDto { FileData = input.ExperienceCertificateAttach, OriginalName = input.ExperienceCertificateAttach?.Name, FileName = input.ExperienceCertificateAttach?.FileName, AttachmentTypeId = 4 });
                }
                if (input.ProfCertificateAttach != null)
                {
                    var oldAttach = oldAttachList.Where(x => x.AttachmentTypeId == 5 || x.OriginalName == input.ProfCertificateAttach?.Name).FirstOrDefault();
                    if (oldAttach != null) entity.UserAttachments.Remove(oldAttach);
                    input.UserAttachments.Add(new AttachmentDto { FileData = input.ProfCertificateAttach, OriginalName = input.ProfCertificateAttach?.Name, FileName = input.ProfCertificateAttach?.FileName, AttachmentTypeId = 5 });
                }
                List<AttachmentDto> attachs = input.UserAttachments.ToList();
                _fileService.CopyFileToCloud(ref attachs);
                input.UserAttachments = attachs;

                //if (!await _fileService.CopyFileToActualFolder(input.UserAttachments.ToList()))
                //    throw new AppException(ExceptionEnum.CouldNotMoveFiles);


                MapperObject.Mapper.Map(input, entity);

                _unitOfWork.BeginTran();

                //saving user
                var result = await _userManager.UpdateAsync(entity);
                if (!result.Succeeded)
                    throw new AppException(ExceptionEnum.RecordUpdateFailed);

                //**saving userRoles

                //add new user roles
                //var exsitedRolesIds = await _userRole.GetUserRoleIdsByUserID(input.Id);
                //if (input.UserRoles == null)
                //    input.UserRoles = new List<UserRoleDto>();
                //var newAddedRoles = MapperObject.Mapper.Map<List<IdentityUserRole<string>>>(input.UserRoles.Where(x => !exsitedRolesIds.Contains(x.RoleId)));
                //newAddedRoles.ForEach(x => x.UserId = input.Id);
                //await _userRole.AddRangeAsync(newAddedRoles);

                ////delete removed roles
                //var rolesIds = input.UserRoles.Select(x => x.RoleId).ToArray();
                //var removedRoles = await _userRole.GetRemovedUserRoleIdsByUserID(input.Id, rolesIds);
                //await _userRole.DeleteAsync(removedRoles.AsEnumerable());


                await _unitOfWork.CompleteAsync();
                _unitOfWork.CommitTran();
            }
            catch (Exception e)
            {
                throw e;
            }
            var userResponse = await GetById(input.Id);
            var user = MapperObject.Mapper.Map<UserUpdateDto>(userResponse);
            return user;
        }
        

        public async Task<bool> IsExpiredToken(ConfirmEmailDto input)
        {
            var user = await _userManager.Users.IgnoreQueryFilters().FirstOrDefaultAsync(x => x.Id == input.UserId);
            if (user == null)
                throw new AppException(ExceptionEnum.UserNotExist);
            var purpose = UserManager<ApplicationUser>.ResetPasswordTokenPurpose;
            var result = await _userManager.VerifyUserTokenAsync(user, "Default", purpose, input.Token);
            return !result;
        }

        public async Task<bool> ResetPassword(ResetPasswordDto input)
        {
            var user = await _userManager.FindByIdAsync(_globalInfo.UserId);

            if (user == null)
                throw new AppException(ExceptionEnum.UserNotExist);

            if (!await _userManager.CheckPasswordAsync(user, input.OldPassword))
                throw new AppException(ExceptionEnum.WrongCredentials);

            var token = await _userManager.GeneratePasswordResetTokenAsync(user);

            var result = await _userManager.ResetPasswordAsync(user, token, input.NewPassword);
            if (!result.Succeeded)
                throw new AppException(ExceptionEnum.RecordUpdateFailed);

            return true;
        }
     
        public async Task<ForgetPasswordResponseDto> ForgetPasswordMail(string email) //Begin forget password
        {
            var foundUser = await _userManager.FindByEmailAsync(email);
            if (foundUser != null)
            {
                string oneTimePassword = await _oTPService.RandomOneTimePassword(foundUser.Id);
                await _oTPService.SentOTPByMail(foundUser.Id, foundUser.Email, oneTimePassword);
                ForgetPasswordResponseDto res = new ForgetPasswordResponseDto { UserId = foundUser.Id};
                return res;
            }
            else
            {
                throw new AppException(ExceptionEnum.UserNotExist);
            }
        }
        public async Task<bool> VerifyOTP(VerifyOTPDto input)
        {
            if (! await _oTPService.VerifyOTP(input.UserId, input.OTP))
                throw new AppException(ExceptionEnum.WrongOTP);
            return true;
        }
        public async Task<bool> ForgetPassword(ForgetPasswordDto input)
        {
            var user = await _userManager.Users.IgnoreQueryFilters().FirstOrDefaultAsync(x => x.Id == input.UserId);
            if (user == null)
                throw new AppException(ExceptionEnum.UserNotExist);
           
            string resetToken = await _userManager.GeneratePasswordResetTokenAsync(user);

            var result = await _userManager.ResetPasswordAsync(user, resetToken, input.Password);
            if (!result.Succeeded)
            {
                if (result.Errors != null && result.Errors.Count() > 0)
                {
                    var msg = result.Errors.Select(a => a.Description).Aggregate((a, b) => a + " /r/n " + b);
                    throw new AppException(msg);
                }
                throw new AppException(ExceptionEnum.RecordCreationFailed);
            }
            return result.Succeeded;
        }


        public async Task StopUser(string userId)
        {
            var entity = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == userId);
            if (entity == null)
                throw new AppException(ExceptionEnum.UserNotExist);
            if (!entity.IsStopped)
            {
                entity.IsStopped = true;
                await _unitOfWork.CompleteAsync();
            }
        }
        public async Task ActiveUser(string userId)
        {
            var entity = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == userId);
            if (entity == null)
                throw new AppException(ExceptionEnum.UserNotExist);

            entity.IsStopped = false;
            entity.AccessFailedCount = 0;
            entity.LockoutEnabled = false;
            entity.LockoutEnd = null;
            await _unitOfWork.CompleteAsync();

        }
    }
}