public async Task <Result <int> > CreateUser(WebUserAccountModel webUserAccountModel, WebUserProfileModel webUserProfileModel)
        {
            var result = new Result <int>();

            result.WasSuccessful = false;
            if (_validationService.IsNull(webUserAccountModel))
            {
                result.ErrorMessage = ErrorMessage.Null;
                return(result);
            }
            if (await _validationService.UsernameExists(webUserAccountModel.Username))
            {
                result.ErrorMessage = ErrorMessage.UsernameExists;
                return(result);
            }
            if (await _validationService.EmailExists(webUserAccountModel.EmailAddress))
            {
                result.ErrorMessage = ErrorMessage.EmailExists;
                return(result);
            }

            var userAccountID = await _userAccountService.CreateAccount(webUserAccountModel);

            webUserProfileModel.UserAccountId = userAccountID;
            await _userProfileService.CreateUserProfile(webUserProfileModel);

            result.WasSuccessful = true;
            result.SuccessValue  = userAccountID;
            return(result);
        }
        public async Task <Result <int> > RegisterAccount(WebUserAccountModel accountModel,
                                                          WebUserProfileModel userModel, string password, string ipAddress)
        {
            try
            {
                // Create Result to determine the result and message the UI will present
                var resultModel = new Result <int>();
                if (accountModel.Username == null || accountModel.EmailAddress == null || userModel.FirstName == null ||
                    userModel.Surname == null || userModel.DateOfBirth == null || password == null)
                {
                    resultModel.WasSuccessful = false;
                    resultModel.ErrorMessage  = ErrorMessage.Null;
                    Console.WriteLine("Register user failed: " + resultModel.ErrorMessage.ToString());
                    return(resultModel);
                }
                else if (password.Length >= 8 && password.Any(char.IsDigit) &&
                         password.Any(char.IsUpper) && password.Any(char.IsLower))
                {
                    var usernameAlreadyExists = await _validationService.UsernameExists(accountModel.Username);

                    if (usernameAlreadyExists)
                    {
                        // Log and return Username existing result
                        _logger.Log(ErrorMessage.UsernameExists.ToString(), LogTarget.All, LogLevel.error, this.ToString(), "User_Logging");
                        resultModel.WasSuccessful = false;
                        resultModel.ErrorMessage  = ErrorMessage.UsernameExists;
                        Console.WriteLine("Register user failed: " + resultModel.ErrorMessage.ToString());
                        return(resultModel);
                    }

                    var emailAlreadyExists = await _validationService.EmailExists(accountModel.EmailAddress);

                    if (emailAlreadyExists)
                    {
                        // Log and return Email existing result
                        _logger.Log(ErrorMessage.EmailExists.ToString(), LogTarget.All, LogLevel.error, this.ToString(), "User_Logging");
                        resultModel.WasSuccessful = false;
                        resultModel.ErrorMessage  = ErrorMessage.EmailExists;
                        Console.WriteLine("Register user failed: " + resultModel.ErrorMessage.ToString());
                        return(resultModel);
                    }

                    // Creates User Account and gets Account ID to pass along
                    var accountID = await _userAccountService.CreateAccount(accountModel);

                    // Sets the password for the new Account
                    await _cryptographyService.newPasswordEncryptAsync(password, accountID);

                    await _publicUserProfileService.CeatePublicUserProfileAsync(new PublicUserProfileModel()
                    {
                        UserId = accountID
                    });

                    // Passes on the Account ID to the User Profile Model
                    userModel.UserAccountId = accountID;

                    // Create User Profile with the Passed on Account ID
                    var userProfileId = await _userProfileService.CreateUserProfile(userModel);

                    UserAccountSettingsModel userAccountSettingsModel = new UserAccountSettingsModel();
                    userAccountSettingsModel.FontSize   = 12;
                    userAccountSettingsModel.FontStyle  = "Default";
                    userAccountSettingsModel.ThemeColor = "Light";
                    userAccountSettingsModel.UserId     = accountID;
                    await _accountSettingsService.CreateUserAccountSettingsAsync(userAccountSettingsModel);

                    var assignmentPolicy = await _assignmentPolicyService.GetAssignmentPolicyByRole(accountModel.AccountType, 1);

                    var scopes     = assignmentPolicy.SuccessValue.AssignedScopes;
                    var userScopes = new List <UserScopeModel>();
                    var userClaims = new List <UserClaimModel>();

                    foreach (var scope in scopes)
                    {
                        var userScope = new UserScopeModel()
                        {
                            Type          = scope.Type,
                            UserAccountId = accountID
                        };

                        userScopes.Add(userScope);
                        foreach (var claim in scope.Claims)
                        {
                            var repeat = false;
                            foreach (var userClaim in userClaims)
                            {
                                if (userClaim.Type == claim.Type)
                                {
                                    repeat = true;
                                }
                            }
                            if (repeat)
                            {
                                continue;
                            }

                            var userClaimModel = new UserClaimModel()
                            {
                                Type          = claim.Type,
                                Value         = claim.Value,
                                UserAccountId = accountID
                            };

                            userClaims.Add(userClaimModel);
                        }
                    }

                    // Create a new claims principal
                    await _claimsPrincipalService.CreateClaimsPrincipal(new ClaimsPrincipal()
                    {
                        Scopes        = userScopes,
                        Claims        = userClaims,
                        Role          = accountModel.AccountType,
                        UserAccountId = accountID
                    });

                    //Log and Return result
                    _logger.Log("User: "******" was registered", LogTarget.All, LogLevel.info, this.ToString(), "User_Logging");
                    resultModel.WasSuccessful = true;
                    resultModel.SuccessValue  = accountID;

                    await _emailService.CreateVerificationToken(accountID);

                    var emailResult = await SendVerificationEmail(accountID);

                    //Log Email Result
                    if (emailResult == true)
                    {
                        _logger.Log("Verification email sent to " + accountModel.Username, LogTarget.All, LogLevel.info, this.ToString(), "User_Logging");
                    }
                    else
                    {
                        _logger.Log("Verification email failed to send to " + accountModel.Username, LogTarget.All, LogLevel.error, this.ToString(), "User_Logging");
                    }

                    return(resultModel);
                }

                resultModel.WasSuccessful = false;
                resultModel.ErrorMessage  = ErrorMessage.InvalidPassword;
                Console.WriteLine("Register user failed: " + resultModel.ErrorMessage.ToString());
                return(resultModel);
            }
            catch (SqlCustomException e)
            {
                Console.WriteLine("Register user failed" + e.Message);
                throw new SqlCustomException(e.Message, e.InnerException);
            }
            catch (NullReferenceException e)
            {
                Console.WriteLine("Register user failed" + e.InnerException.Message);
                throw new NullReferenceException(e.Message, e.InnerException);
            }
        }