/// <summary>
        /// Saves a category to the database
        /// </summary>
        /// <param name="profile"></param>
        /// <param name="category"></param>
        /// <param name="passphrase"></param>
        /// <returns></returns>
        public static async Task<SuccessResponse> SaveCategoryAsync(ApiCategory category)
        {
            using (var client = new HttpClient())
            {
                // Authorize the request.
                await AuthorizeRequest(client);
                // Add passphrase to message
                AddPassphraseHeader(client);
                // Create JSON content.
                var content = JsonContent(category);
                // Send request and get a response
                HttpResponseMessage response;

                if (category.Id == 0)
                {
                    // Create
                    response = await client.PostAsync(GetUrl($"api/profiles/{CurrentProfile.Id}/categories"), content);
                }
                else
                {
                    // Update
                    response = await client.PutAsync(GetUrl($"api/profiles/{CurrentProfile.Id}/categories/{category.Id}"), content);
                }

                // Read the data
                var data = await response.Content.ReadAsStringAsync();

                // Deserialize the object based on the result
                if (response.IsSuccessStatusCode)
                {
                    // Deserialize the response as an ApiResponse object
                    return new SuccessResponse(Convert.ToInt32(data));
                }
                else
                {
                    throw await CreateException(response);
                }
            }

        }
        /// <summary>
        /// Registers commands for UI elements
        /// </summary>
        private void RegisterCommands()
        {
            // Handle add category
            AddCategoryCommand = new Command(async (p) =>
            {
                // Prompt for name
                await DialogHelper.ShowClosableDialog<NamePromptDialog>(async (d) =>
                {
                    try
                    {
                        //create new category
                        var category = new ApiCategory()
                        {
                            Name = d.Value
                        };

                        // Send the category to the api
                        var resp = await KryptPadApi.SaveCategoryAsync(category);

                        // Set the id of the newly created category
                        category.Id = resp.Id;

                        // Add the category to the list
                        Categories.Add(category);

                        // Add view to the ItemsView object
                        ItemsView.Source = Categories;

                        // Refresh
                        OnPropertyChanged(nameof(ItemsView));

                        // Hide empty message
                        EmptyMessageVisibility = Visibility.Collapsed;
                    }
                    catch (WebException ex)
                    {
                        // Something went wrong in the api
                        await DialogHelper.ShowMessageDialogAsync(ex.Message);
                    }
                    catch (Exception)
                    {
                        // Failed
                        await DialogHelper.ShowConnectionErrorMessageDialog();
                    }

                }, "Add Category");
            });

            // Handle add new item
            AddItemCommand = new Command(AddItemCommandHandler);

            // Handle item click
            ItemClickCommand = new Command((p) =>
            {
                var item = p as ApiItem;
                var category = (from c in Categories
                                where c.Items.Contains(item)
                                select c).FirstOrDefault();

                // Navigate to edit
                NavigationHelper.Navigate(typeof(NewItemPage),
                    new EditItemPageParams()
                    {
                        Category = category,
                        Item = item
                    });


            });

            // Handle change passphrase command
            ChangePassphraseCommand = new Command(async (p) =>
            {

                var dialog = new ChangePassphraseDialog();

                await dialog.ShowAsync();

            });

            // Handle rename command
            RenameProfileCommand = new Command(async (p) =>
            {

                // Prompt for name
                await DialogHelper.ShowNameDialog(async (d) =>
                {
                    try
                    {
                        // Set new name
                        var profile = KryptPadApi.CurrentProfile;
                        profile.Name = d.Value;

                        // Send the category to the api
                        var resp = await KryptPadApi.SaveProfileAsync(profile);

                    }
                    catch (WebException ex)
                    {
                        // Something went wrong in the api
                        await DialogHelper.ShowMessageDialogAsync(ex.Message);
                    }
                    catch (Exception)
                    {
                        // Failed
                        await DialogHelper.ShowConnectionErrorMessageDialog();
                    }
                }, "RENAME PROFILE", KryptPadApi.CurrentProfile.Name);
            });

            // Handle delete command
            DeleteProfileCommand = new Command(async (p) =>
            {

                var res = await DialogHelper.Confirm(
                    "All of your data in this profile will be deleted permanently. THIS ACTION CANNOT BE UNDONE. Are you sure you want to delete this entire profile?",
                    "WARNING - CONFIRM DELETE",
                    async (ap) =>
                    {
                        try
                        {
                            // Delete the selected profile
                            await KryptPadApi.DeleteProfileAsync(KryptPadApi.CurrentProfile);

                            // Navigate back to the profiles list
                            NavigationHelper.Navigate(typeof(SelectProfilePage), null);

                            // Clear backstack
                            NavigationHelper.ClearBackStack();

                        }
                        catch (WebException ex)
                        {
                            // Something went wrong in the api
                            await DialogHelper.ShowMessageDialogAsync(ex.Message);
                        }
                        catch (Exception)
                        {
                            // Failed
                            await DialogHelper.ShowConnectionErrorMessageDialog();
                        }

                    }
                );


            });

            // Download profile handler
            DownloadProfileCommand = new Command(async (prop) =>
            {
                try
                {
                    // Prompt for a place to save the file
                    var sfd = new FileSavePicker()
                    {
                        SuggestedFileName = KryptPadApi.CurrentProfile.Name,

                    };

                    //sfd.FileTypeChoices.Add("KryptPad Document Format", new List<string>(new[] { ".kdf" }));
                    sfd.FileTypeChoices.Add("KryptPad Document Format", new[] { ".kdf" });

                    // Show the picker
                    var file = await sfd.PickSaveFileAsync();

                    if (file != null)
                    {

                        // Get profile
                        var profileData = await KryptPadApi.DownloadCurrentProfileAsync();

                        // Save profile to file
                        using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
                        using (var sw = new StreamWriter(fs.AsStreamForWrite()))
                        {
                            // Write the data
                            sw.Write(profileData);
                        }

                        await DialogHelper.ShowMessageDialogAsync("Profile downloaded successfully");
                    }
                }
                catch (WebException ex)
                {
                    // Something went wrong in the api
                    await DialogHelper.ShowMessageDialogAsync(ex.Message);
                }
                catch (Exception)
                {
                    // Failed
                    await DialogHelper.ShowConnectionErrorMessageDialog();
                }

            });

            // Handle category rename
            RenameCategoryCommand = new Command(RenameCategoryCommandHandler);

            // Handle category delete
            DeleteCategoryCommand = new Command(DeleteCategoryCommandHandler);

            // Handle selection mode
            SelectModeCommand = new Command(SelectModeCommandHandler);

            // Handle the move command
            MoveItemsCommand = new Command(MoveItemsCommandHandler, CanMoveItems);
        }
        /// <summary>
        /// Loads an item into the view model
        /// </summary>
        /// <param name="item"></param>
        public async Task LoadItemAsync(ApiItem selectedItem, ApiCategory category)
        {

            // Prevent change triggers
            _isLoading = true;
            IsBusy = true;

            try
            {
                // Get list of categories for the combobox control
                var categories = await KryptPadApi.GetCategoriesAsync();

                // Set the category view source for the combobox
                CategoriesView.Source = categories.Categories;

                // Update view
                OnPropertyChanged(nameof(CategoriesView));

                // Set the selected category in the list
                Category = (from c in categories.Categories
                            where c.Id == category.Id
                            select c).SingleOrDefault();

                // Check to make sure our parameters are set
                if (Category == null)
                {
                    // Show error
                    throw new WarningException("The item you are trying to edit does not exist in this category.");
                }

                // Get the item
                var itemResp = await KryptPadApi.GetItemAsync(Category.Id, selectedItem.Id);

                // Get the item
                var item = itemResp.Items.FirstOrDefault();

                // Set item
                Item = item;

                // Set properties
                ItemName = item.Name;
                Notes = item.Notes;
                SelectedColor = item.Background;

                // Set fields
                foreach (var field in item.Fields)
                {
                    // Add field to the list
                    AddFieldToCollection(new FieldModel(field));
                }


            }
            catch (WarningException ex)
            {
                // Operation failed
                await DialogHelper.ShowMessageDialogAsync(ex.Message);
            }
            catch (WebException ex)
            {
                // Operation failed
                await DialogHelper.ShowMessageDialogAsync(ex.Message);
                // Navigate back to the items page
                NavigationHelper.Navigate(typeof(ItemsPage), null);
            }
            catch (Exception)
            {
                // Failed
                await DialogHelper.ShowConnectionErrorMessageDialog();
                // Navigate back to the items page
                NavigationHelper.Navigate(typeof(ItemsPage), null);
            }

            _isLoading = false;
            IsBusy = false;
        }