public Task <Result <object> > GenerateToken(LoginModel model)
        => Result <object> .TryAsync(async() =>
        {
            if (string.IsNullOrWhiteSpace(model.Username))
            {
                return(Result <object> .Failed(
                           Error.WithCode(ErrorCodes.AuthModelValidtionOneOfMobileOrEmailOrUsernameIsRequired)));
            }

            model.Password = _cryptoService.ComputeSha512Hash(model.Password);

            var userResult = await repository.FirstOrDefaultAsNoTrackingAsync <User>(u =>
                                                                                     (string.IsNullOrEmpty(model.Username) || u.Username == model.Username ||
                                                                                      u.Email == model.Username) && u.Password == model.Password,
                                                                                     u => u.Role);
            if (!userResult.Success || userResult.Data == null)
            {
                return(Result <object> .Failed(Error.WithCode(ErrorCodes.UserNotFound)));
            }

            if (!userResult.Data.Enabled)
            {
                return(Result <object> .Failed(Error.WithData(1000,
                                                              new[]
                {
                    "Your Credentials Are Not Allowed Anymore , Please Contact Support If You Have Any Questions."
                })));
            }

            var roleResult = await repository.FirstOrDefaultAsNoTrackingAsync <Role>(r => r.Id == userResult.Data.RoleId,
                                                                                     r => r.RoleFeature.Select(rf => rf.Feature.FeaturePermission));
            var role      = roleResult.Data;
            var roleModel = new RoleModel
            {
                Id      = role.Id,
                Name    = role.Name,
                Feature = role.RoleFeature?.Select(rf => new FeatureModel
                {
                    Id          = rf.Feature.Id,
                    Name        = rf.Feature.Name,
                    Permissions = rf.Feature?.FeaturePermission?.Select(fp => new PermissionModel
                    {
                        Id = (PermissionType)fp.PermissionId,
                    }).ToList()
                }).ToList()
            };

            var token    = GenerateJsonWebToken(userResult.Data, role);
            var response = new
            {
                Token = token,
                Role  = roleModel
            };
            return(Result <object> .Successful(response));
        });
        public Task <Result <object> > Register(RegisterModel model)
        => Result <object> .TryAsync(async() =>
        {
            model.Password        = _cryptoService.ComputeSha512Hash(model.Password);
            var username          = model.FirstName.ToCharArray()[0] + "." + model.LastName;
            var duplicateUsername = await _repository.FirstOrDefaultAsNoTrackingAsync <User>(u =>
                                                                                             u.Username == username);
            if (duplicateUsername.Success && duplicateUsername.Data != null)
            {
                username = model.FirstName + "." + model.LastName;
            }
            duplicateUsername = await _repository.FirstOrDefaultAsNoTrackingAsync <User>(u =>
                                                                                         u.Username == username);
            if (duplicateUsername.Success && duplicateUsername.Data != null)
            {
                username = model.FirstName + "." + model.LastName + new Random(1000).Next();
            }

            var duplicateMobile = await _repository.FirstOrDefaultAsNoTrackingAsync <User>(u =>
                                                                                           u.Mobile == model.Mobile);
            if (duplicateMobile.Success && duplicateMobile.Data != null)
            {
                return(Result <object> .Failed(Error.WithData(1000, new[] { "Duplicate Mobile Number " })));
            }

            var duplicateEmail = await _repository.FirstOrDefaultAsNoTrackingAsync <User>(u =>
                                                                                          u.Email == model.Email);
            if (duplicateEmail.Success && duplicateEmail.Data != null)
            {
                return(Result <object> .Failed(Error.WithData(1000, new[] { "Duplicate Email Address " })));
            }

            var result = await _repository.FirstOrDefaultAsync <Role>(r => r.Name == "NormalUser",
                                                                      r => r.RoleFeature.Select(rf => rf.Feature.FeaturePermission.Select(fp => fp.Permission)));
            var role = result.Data;
            var user = new User
            {
                Id            = Guid.NewGuid(),
                CreationDate  = DateTime.Now,
                Address       = "",
                Email         = model.Email,
                Password      = model.Password,
                Enabled       = true,
                Firstname     = model.FirstName,
                Lastname      = model.LastName,
                Mobile        = model.Mobile,
                Gender        = model.Gender,
                Role          = role,
                Username      = username,
                MaritalStatus = (byte)MaritalStatus.Single,
            };


            var roleModel = new RoleModel
            {
                Id      = role.Id,
                Name    = role.Name,
                Feature = role.RoleFeature?.Select(rf => new FeatureModel
                {
                    Id          = rf.Feature.Id,
                    Name        = rf.Feature.Name,
                    Permissions = rf.Feature?.FeaturePermission?.Select(fp => new PermissionModel
                    {
                        Id   = (PermissionType)fp.Permission.Id,
                        Name = fp.Permission.Name
                    }).ToList()
                }).ToList()
            };

            var token    = _authBiz.GenerateJsonWebToken(user, user.Role);
            var response = new
            {
                Token    = token,
                Username = user.Username,
                Role     = roleModel
            };
            _repository.Add(user);
            try
            {
                await _repository.CommitAsync();
            }
            catch (Exception e)
            {
                return(Result <object> .Failed(Error.WithData(1000, new[] { "Duplicate username " })));
            }

            return(Result <object> .Successful(response));
        });