/// <summary>
        /// Generate token for logged in user
        /// </summary>
        /// <param name="user"></param>
        /// <param name="Config"></param>
        /// <returns></returns>
        public static UsersExtModel_Auth GenerateToken(this UsersExtModel_Auth user, IConfiguration Config)
        {
            if (Config != null && user != null)
            {
                // Create Claims
                var UserClaims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
                    new Claim(JwtRegisteredClaimNames.Sid, user.Id),
                    new Claim(JwtRegisteredClaimNames.Sub, String.IsNullOrEmpty(user.RoleID)? "": user.RoleID),
                    // new Claim("another", user.Email)
                };

                var secretBytes        = Encoding.UTF8.GetBytes(Config["Jwt:Key"]);
                var key                = new SymmetricSecurityKey(secretBytes);
                var algorith           = SecurityAlgorithms.HmacSha256;
                var signingcredentials = new SigningCredentials(key, algorith);
                var token              = new JwtSecurityToken(
                    issuer: Config["Jwt:Issuer"],
                    audience: Config["Jwt:Issuer"],
                    claims: UserClaims,
                    notBefore: DateTime.Now,
                    expires: DateTime.Now.AddDays(30),
                    signingCredentials: signingcredentials);

                user.Token = new JwtSecurityTokenHandler().WriteToken(token);
            }

            return(user);
        }
        public async Task <ActionResult <DataResponse <UsersExtModel_Auth> > > AuthenticateAsync([FromBody] LoginModel model)
        {
            DataResponse <UsersExtModel_Auth> response = new DataResponse <UsersExtModel_Auth>();
            UsersExtModel_Auth _DTO = null;

            try
            {
                if (ModelState.IsValid && model != null)
                {
                    var _user = await _userManager.FindByNameAsync(model.UserName).ConfigureAwait(false);

                    if (_user == null)
                    {
                        response.Code        = ResponseCode.LOGIN_FAILED;
                        response.Description = ResponseDescription.LOGIN_FAILED;
                        response.Message     = "Invalid login credential";
                        response.Data        = _DTO;
                        return(BadRequest(response));
                    }

                    var _signInRes = _userManager.PasswordHasher.VerifyHashedPassword(_user, _user.PasswordHash, model.Password);
                    if (_signInRes == PasswordVerificationResult.Success)
                    {
                        _DTO = _mapper.Map <UsersExtModel_Auth>(_user);
                        if (_DTO != null)
                        {
                            _DTO = _DTO.GenerateToken(_config);
                        }

                        response.Code        = ResponseCode.SUCCESS;
                        response.Description = ResponseDescription.SUCCESS;
                        response.Message     = null;
                        response.Data        = _DTO;
                        return(Ok(_DTO));
                    }
                }

                response.Code        = ResponseCode.LOGIN_FAILED;
                response.Description = ResponseDescription.LOGIN_FAILED;
                response.Message     = "Invalid login credential";
                response.Data        = _DTO;
                return(BadRequest(response));
            }
            catch (Exception ex)
            {
                Guid _ErrorCode = Guid.NewGuid();
                Log.Error("Fatal Error [{ErrorCode}]: {Message}", _ErrorCode, ex.Message);
                response.Code        = ResponseCode.SYSTEM_ERROR;
                response.Description = ResponseDescription.SYSTEM_ERROR;
                response.Message     = $"System Error: Something went wrong here! Kindly contact the support with this error code [{_ErrorCode}]";
                response.Data        = _DTO;
                return(BadRequest(response));
            }
        }
        public async Task <ActionResult <DataResponse <UsersExtModel_Auth> > > RegisterAsync([FromBody] RegisterModel model)
        {
            DataResponse <UsersExtModel_Auth> response = new DataResponse <UsersExtModel_Auth>();
            UsersExtModel_Auth _DTO = null;

            try
            {
                if (ModelState.IsValid && model != null)
                {
                    var user = new IUser()
                    {
                        Id = Guid.NewGuid().ToString(),
                        NormalizedEmail    = model.Email,
                        NormalizedUserName = model.UserName,
                        EmailConfirmed     = false,
                        UserName           = model.UserName,
                        Email = model.Email
                    };

                    var res = await _userManager.CreateAsync(user, model.Password).ConfigureAwait(false);

                    if (res.Succeeded)
                    {
                        // send mail to user
                        var code = await _userManager.GenerateEmailConfirmationTokenAsync(user).ConfigureAwait(false);

                        await _emailService.Send(user.Email, subject : "Email Verification", body : $"Content: {code}").ConfigureAwait(false);

                        var _user = await _userManager.FindByNameAsync(model.UserName).ConfigureAwait(false);

                        if (_user != null)
                        {
                            var _signInRes = _userManager.PasswordHasher.VerifyHashedPassword(_user, _user.PasswordHash, model.Password);

                            if (_signInRes == PasswordVerificationResult.Success)
                            {
                                _DTO = _mapper.Map <UsersExtModel_Auth>(_user);
                                if (_DTO != null)
                                {
                                    _DTO = _DTO.GenerateToken(_config);
                                }

                                response.Code        = ResponseCode.SUCCESS;
                                response.Description = ResponseDescription.SUCCESS;
                                response.Message     = null;
                                response.Data        = _DTO;
                                return(Ok(_DTO));
                            }
                        }
                    }

                    response.Code        = ResponseCode.LOGIN_FAILED;
                    response.Description = ResponseDescription.LOGIN_FAILED;
                    response.Message     = "Invalid login credential";
                    response.Errors      = res.Errors.Select(ex => ex.Description).ToList();
                    response.Data        = _DTO;
                    return(BadRequest(response));
                }
                else
                {
                    response.Code        = ResponseCode.LOGIN_FAILED;
                    response.Description = ResponseDescription.LOGIN_FAILED;
                    response.Message     = "Invalid login credential";
                    response.Data        = _DTO;
                    return(BadRequest(response));
                }
            }
            catch (Exception ex)
            {
                Guid _ErrorCode = Guid.NewGuid();
                Log.Error("Fatal Error [{ErrorCode}]: {Message}", _ErrorCode, ex.Message);
                response.Code        = ResponseCode.SYSTEM_ERROR;
                response.Description = ResponseDescription.SYSTEM_ERROR;
                response.Message     = $"System Error: Something went wrong here! Kindly contact the support with this error code [{_ErrorCode}]";
                response.Data        = _DTO;
                return(BadRequest(response));
            }
        }