/// <summary>
        /// Method for searching for specified user
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void SearchForUser(User admin)
        {
            AdminView.SearchForUser(admin);
            var searchKeyword = SharedController.GetSearchInput();
            var listWithUsers = api.FindUser(admin.Id, searchKeyword);

            if (listWithUsers.Count > 0)
            {
                var continueLoop = true;
                do
                {
                    AdminView.ListAllUsers(listWithUsers);
                    var input = SharedController.GetAndValidateInput();
                    if (input.validatedInput == 0 || input.validatedInput > listWithUsers.Count)
                    {
                        SharedError.PrintWrongMenuInput();
                    }
                    else
                    {
                        EditUser(admin, listWithUsers[input.validatedInput - 1]);
                        continueLoop = false;
                    }
                } while (continueLoop);
            }
            else
            {
                SharedError.NothingFound();
            }
        }
        /// <summary>
        /// Method for getting and selecting a category to be updated
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void UpdateCategory(User admin)
        {
            var continueLoop = true;

            do
            {
                Console.Clear();
                AdminView.UpdateCategory();
                var categories = api.GetCategories();
                SharedView.ListCategories(categories);
                var input = SharedController.GetAndValidateInput();
                if (input.validatedInput > 0 &&
                    input.validatedInput <= categories.Count)
                {
                    UpdateCategory(admin, categories[input.validatedInput - 1]);
                }
                else
                {
                    if (input.validatedInput == 0 &&
                        input.menuInput.ToLower() == "x")
                    {
                        continueLoop = false;
                    }
                    else
                    {
                        SharedError.PrintWrongInput();
                    }
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Sets the amount of books specified by the user.
        /// </summary>
        /// <param name="book">Takes a book to change amount on</param>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void SetAmount(Book book, User admin)
        {
            AdminView.SetAmount();
            var input = SharedController.GetAndValidateInput();

            if (input.validatedInput != 0)
            {
                WebShopApi api = new WebShopApi();
                if (api.SetAmount(admin.Id, book.Id, input.validatedInput))
                {
                    if (book.Amount <= 0)
                    {
                        book.Amount = 0;
                    }
                    SharedError.Success();
                    BookView.ChangedNumberOfBooks(book);
                }
                else
                {
                    SharedError.Failed();
                    BookView.ChangedNumberOfBooks(book);
                }
            }
            else
            {
                SharedError.PrintWrongMenuInput();
            }
        }
        /// <summary>
        /// Deletes the number of books typed in when asked.
        /// </summary>
        /// <param name="book">Takes a book to delete from</param>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void DeleteBook(Book book, User admin)
        {
            bool continueLoop = true;

            do
            {
                Console.Clear();
                AdminView.DeleteBook(book);
                var input = SharedController.GetAndValidateInput();
                if (input.validatedInput > 0)
                {
                    var originalBookAmount = book.Amount;
                    if (api.DeleteBook(admin.Id, book.Id, input.validatedInput))
                    {
                        SharedError.Success();
                        if (book.Amount == originalBookAmount &&
                            book.Amount - input.validatedInput <= 0)
                        {
                            book.Amount = 0;
                        }
                    }
                    else
                    {
                        SharedError.Failed();
                    }
                    continueLoop = false;
                }
                else
                {
                    SharedError.PrintWrongInput();
                }
            } while (continueLoop);
        }
        /// <summary>
        /// First menu that the user see when standard user logs in.
        /// </summary>
        /// <param name="user">Takes a user to be connected with eventual purchase.</param>
        internal static void UserSelectionMenu(User user)
        {
            var continueLoop = true;

            do
            {
                UserView.PrintBuyMenuOptions();
                var input = SharedController.GetAndValidateInput();
                switch (input.validatedInput)
                {
                case 1:
                    SharedController.BuyBookMenu(user);
                    break;

                case 0:
                    if (SharedController.LogoutIf_X_IsPressed(
                            user,
                            input.menuInput,
                            input.validatedInput))
                    {
                        continueLoop = false;
                    }
                    else
                    {
                        SharedError.PrintWrongMenuInput();
                    }

                    break;
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Method for editing the user. Promote, Demote, activate or deactivate
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        /// <param name="editUser">Takes a user to edit</param>
        private static void EditUser(User admin, User editUser)
        {
            var continueLoop = true;

            do
            {
                AdminView.EditUser(editUser);
                var input = SharedController.GetAndValidateInput();
                switch (input.validatedInput)
                {
                case 1:
                    if (api.Promote(admin.Id, editUser.Id))
                    {
                        SharedError.Success();
                        break;
                    }
                    SharedError.Failed();
                    break;

                case 2:
                    if (api.Demote(admin.Id, editUser.Id))
                    {
                        SharedError.Success();
                        break;
                    }
                    SharedError.Failed();
                    break;

                case 3:
                    if (api.ActivateUser(admin.Id, editUser.Id))
                    {
                        SharedError.Success();
                        break;
                    }
                    SharedError.Failed();
                    break;

                case 4:
                    if (api.InactivateUser(admin.Id, editUser.Id))
                    {
                        SharedError.Success();
                        break;
                    }
                    SharedError.Failed();
                    break;

                case 0:
                    continueLoop = SharedController.GoBackIf_X_IsPressedOrPrintErrorMsg(input.menuInput);
                    break;

                default:
                    SharedError.PrintWrongMenuInput();
                    break;
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Gets all availible books and sends the user
        /// to edit book options of specified book
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void GetAllBooksAndEnterBookOptions(User admin)
        {
            var availibleBooks = api.GetAvailibleBooks();

            BookView.ListAllBooks(availibleBooks);
            var input = SharedController.GetAndValidateInput();

            if (input.validatedInput != 0 &&
                input.validatedInput <= availibleBooks.Count)
            {
                AdminController.BookOptions(availibleBooks[input.validatedInput - 1], admin);
            }
            else
            {
                SharedError.PrintWrongInput();
            }
        }
        /// <summary>
        /// Method for handling the input for the book options
        /// </summary>
        /// <param name="book">Takes a book</param>
        /// <param name="admin">Takes a user with admin priviliges</param>
        public static void BookOptions(Book book, User admin)
        {
            var continueLoop = true;

            do
            {
                Console.Clear();
                if (book.Amount == 0)
                {
                    continueLoop = false;
                    continue;
                }
                AdminView.UpdateBook(book);
                var input = SharedController.GetAndValidateInput();
                switch (input.validatedInput)
                {
                case 1:
                    Console.Clear();
                    SetAmount(book, admin);
                    break;

                case 2:
                    Console.Clear();
                    UpdateBookInfo(book, admin);
                    break;

                case 3:
                    Console.Clear();
                    ChangeCategory(book, admin);
                    break;

                case 4:
                    DeleteBook(book, admin);
                    break;

                case 0:
                    continueLoop = SharedController.GoBackIf_X_IsPressedOrPrintErrorMsg(input.menuInput);
                    break;

                default:
                    SharedError.PrintWrongMenuInput();
                    break;
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Method for updating the information of a book
        /// </summary>
        /// <param name="book">Takes a book to update</param>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void UpdateBookInfo(Book book, User admin)
        {
            var continueLoop = true;

            do
            {
                Console.Clear();
                AdminView.UpdateBookInfo(book);
                var input = SharedController.GetAndValidateInput();
                switch (input.validatedInput)
                {
                case 1:
                    Console.Clear();
                    ChangeTitle(admin, book);
                    break;

                case 2:
                    Console.Clear();
                    ChangeAuthor(admin, book);
                    break;

                case 3:
                    Console.Clear();
                    ChangePrice(admin, book);
                    break;

                case 4:
                    Console.Clear();
                    ChangeCategory(book, admin);
                    break;

                case 0:
                    continueLoop = SharedController.GoBackIf_X_IsPressedOrPrintErrorMsg(input.menuInput);
                    break;

                default:
                    SharedError.PrintWrongMenuInput();
                    break;
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Lists all users
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void ListAllUsers(User admin)
        {
            var listWithUsers = api.ListUsers(admin.Id);
            var continueLoop  = true;

            do
            {
                Console.Clear();
                AdminView.ListAllUsers(listWithUsers);
                var input = SharedController.GetAndValidateInput();
                if (input.validatedInput == 0 || input.validatedInput > listWithUsers.Count)
                {
                    SharedError.PrintWrongMenuInput();
                }
                else
                {
                    EditUser(admin, listWithUsers[input.validatedInput - 1]);
                    continueLoop = false;
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Delete category (if empty)
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void DeleteCategory(User admin)
        {
            var continueLoop = true;

            do
            {
                Console.Clear();
                AdminView.DeleteCategory();
                var categories = api.GetCategories();
                SharedView.ListCategories(categories);
                var input = SharedController.GetAndValidateInput();
                if (input.validatedInput > 0 &&
                    input.validatedInput <= categories.Count)
                {
                    if (api.DeleteCategory(
                            admin.Id,
                            categories[input.validatedInput - 1].Id))
                    {
                        SharedError.Success();
                    }
                    else
                    {
                        var books = api.GetBooksInCategory(categories[input.validatedInput - 1].Id);
                        SharedError.BooksStillInCategory(books.Count);
                    }
                }
                else
                {
                    if (input.validatedInput == 0 &&
                        input.menuInput.ToLower() == "x")
                    {
                        continueLoop = false;
                    }
                    else
                    {
                        SharedError.PrintWrongInput();
                    }
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Listing categories to be chosen from. Returns one single category
        /// </summary>
        /// <param name="categories">Takes a  list of categories</param>
        /// <returns>Returns one single category</returns>
        private static BookCategory ChooseCategoryToView(List <BookCategory> categories)
        {
            var continueLoop = true;
            Tuple <string, int> input;

            do
            {
                input = SharedController.GetAndValidateInput().ToTuple();

                if (input.Item2 > 0 &&
                    input.Item2 <= categories.Count)
                {
                    continueLoop = false;
                }
                else
                {
                    SharedError.PrintWrongInput();
                    continueLoop = true;
                }
            } while (continueLoop);

            return(categories[input.Item2 - 1]);
        }
        /// <summary>
        /// Method for getting input and searching for a book
        /// </summary>
        /// <returns>A specific book</returns>
        public static Book SearchForBook()
        {
            WebShopApi api = new WebShopApi();

            Console.Clear();
            BookView.SearchForBook();
            var searchKeyword = SharedController.GetSearchInput();

            if (searchKeyword.ToLower() == "x")
            {
                return(null);
            }
            var listWithMatchingBooks = api.GetBooks(searchKeyword);

            if (listWithMatchingBooks.Count > 0)
            {
                Console.Clear();
                BookView.ListAllBooks(listWithMatchingBooks);
                var input = SharedController.GetAndValidateInput();
                if (input.validatedInput != 0 &&
                    input.validatedInput <= listWithMatchingBooks.Count)
                {
                    return(api.GetBook(listWithMatchingBooks[input.validatedInput - 1].Id));
                }
                else
                {
                    SharedError.PrintWrongInput();
                    return(null);
                }
            }
            else
            {
                SharedError.NothingFound();
                return(null);
            }
        }
 /// <summary>
 /// List all books and choose one to return
 /// </summary>
 /// <param name="listWithMatchingBooks">Takes a list of books</param>
 /// <returns>returns a book</returns>
 internal static Book ListAndChooseBook(List <Book> listWithMatchingBooks)
 {
     if (listWithMatchingBooks.Count > 0)
     {
         Console.Clear();
         BookView.ListAllBooks(listWithMatchingBooks);
         var input = SharedController.GetAndValidateInput();
         if (input.validatedInput != 0 &&
             input.validatedInput <= listWithMatchingBooks.Count)
         {
             return(api.GetBook(listWithMatchingBooks[input.validatedInput - 1].Id));
         }
         else
         {
             SharedError.PrintWrongInput();
             return(null);
         }
     }
     else
     {
         SharedError.NothingFound();
         return(null);
     }
 }
        /// <summary>
        /// Method for changing the category that a book is connected to.
        /// </summary>
        /// <param name="book">Takes abook to change</param>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void ChangeCategory(Book book, User admin)
        {
            var categories   = api.GetCategories();
            var continueLoop = true;

            do
            {
                Console.Clear();
                AdminView.ChangeCategory(book, categories);
                if (categories.Count() > 0)
                {
                    var input = SharedController.GetAndValidateInput();
                    if (input.validatedInput > 0 &&
                        input.validatedInput <= categories.Count())
                    {
                        var success = api.AddBookToCategory(
                            admin.Id,
                            book.Id,
                            categories[input.validatedInput - 1].Id);
                        continueLoop = false;
                        if (success)
                        {
                            SharedError.Success();
                        }
                        else
                        {
                            SharedError.Failed();
                        }
                    }
                    else
                    {
                        SharedError.PrintWrongInput();
                    }
                }
            } while (continueLoop);
        }
        /// <summary>
        /// Prints all admin functions and takes a menuinput
        /// </summary>
        /// <param name="admin">Takes a user with admin priviliges</param>
        private static void AdminFunctions(User admin)
        {
            var continueLoop = true;

            do
            {
                AdminView.PrintAdminFunctions();
                var input = SharedController.GetAndValidateInput();
                switch (input.validatedInput)
                {
                case 1:
                    AddUser(admin);
                    break;

                case 2:
                    ListAllUsers(admin);
                    break;

                case 3:
                    SearchForUser(admin);
                    break;

                case 4:
                    AddBook(admin);
                    break;

                case 5:
                    GetBookAndEnterBookOptions(admin);
                    break;

                case 6:
                    GetBookAndEnterBookOptions(admin);
                    break;

                case 7:
                    GetAllBooksAndEnterBookOptions(admin);
                    break;

                case 8:
                    AddCategory(admin);
                    break;

                case 9:
                    DeleteCategory(admin);
                    break;

                case 10:
                    UpdateCategory(admin);
                    break;

                case 11:
                    SoldBooks(admin);
                    break;

                case 12:
                    Earnings(admin);
                    break;

                case 13:
                    BestCustomer(admin);
                    break;

                case 0:
                    continueLoop = SharedController.GoBackIf_X_IsPressedOrPrintErrorMsg(input.menuInput);
                    break;
                }
            } while (continueLoop);
        }