using PCUT.ViewModels;
using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Http.Core;
using Http.Core.Extensions;
using PCUT.Pages.CategoriesManagement;
using static Http.Core.Constants.HttpConstants;
using PCUT.Models.Categories;
using System.Linq;
using Windows.UI.Popups;
using System.Reflection;
using Http.Core.Exceptions;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace PCUT.Pages
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class CategoriesViewPage : Page
    {
        private CategoriesViewModel _categoriesViewModel { get; set; }
        private bool _buttonClicked { get; set; }
        public CategoriesViewPage()
        {
            this.InitializeComponent();
            _categoriesViewModel = new CategoriesViewModel();
            this.DataContext = _categoriesViewModel;
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            _categoriesViewModel.Pagination.Page = 1;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            _categoriesViewModel.Pagination.Dispose();
        }

        private async void AddCategory_Button(object sender, RoutedEventArgs e)
        {
            var dialog = new CategoryUpsertDialog();
            var result = await dialog.ShowAsync();
            if (result == ContentDialogResult.Primary)
                RefreshList();
        }

        private async void EditCategory_Click(object sender, RoutedEventArgs e)
        {
            _buttonClicked = true;
            if (sender is Button button && button.CommandParameter is string categoryId)
            {
                var categoryEditDialog = new CategoryUpsertDialog(categoryId);
                var result = await categoryEditDialog.ShowAsync();
                if (result == ContentDialogResult.Primary)
                    RefreshList();
            }
            _buttonClicked = false;
        }
        private async void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            _buttonClicked = true;
            if (sender is Button button && button.CommandParameter is string userId)
            {
                //Confirm diaglog before delete
                ContentDialog deleteDialog = new ContentDialog
                {
                    Title = "Confirm Delete?",
                    Content = "Are you sure want delete this category?",
                    PrimaryButtonText = "Delete",
                    CloseButtonText = "Cancel"
                };
                deleteDialog.PrimaryButtonStyle = Application.Current.Resources["PrimaryDialogButton"] as Style;
                deleteDialog.CloseButtonStyle = Application.Current.Resources["CloseDialogButton"] as Style;

                var result = await deleteDialog.ShowAsync();
                if (result == ContentDialogResult.Primary)
                {
                    await DeleteCategoryAsync(userId);
                    RefreshList();
                }
            }
            _buttonClicked = false;
        }

        private async void RefreshList()
        {
            await _categoriesViewModel.Reload();
        }

        private async Task DeleteCategoryAsync(string categoryId)
        {
            using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                try
                {
                    var response = await httpClient.DeleteAsync(Api.CategoryById.FormatRoute(categoryId));
                    if (response.IsSuccessStatusCode)
                    {
                        await ShowDialog("Delete Success", "Category Deleted!");
                    }
                    else
                    {
                        await ShowDialog("Error!", "Cant delete category");
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException))
                {
                    await ShowDialog("Error!", $"Got exception: {ex.Message}");
                }
            }
        }

        private async Task ShowDialog(string title, string content)
        {
            ContentDialog dialog = new ContentDialog
            {
                Title = title,
                Content = content,
                CloseButtonText = "OK"
            };
            dialog.CloseButtonStyle = Application.Current.Resources["CloseDialogButton"] as Style;

            await dialog.ShowAsync();
        }

        private void btnFirst_Click(object sender, RoutedEventArgs e)
        {
            _categoriesViewModel.Pagination.Page = 1;
        }

        private void btnLast_Click(object sender, RoutedEventArgs e)
        {
            _categoriesViewModel.Pagination.Page = _categoriesViewModel.Pagination.TotalPage;
        }

        private void btnPrevious_Click(object sender, RoutedEventArgs e)
        {
            _categoriesViewModel.Pagination.Page--;
        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            _categoriesViewModel.Pagination.Page++;
        }

        private async void AddMetadataButton_Click(object sender, RoutedEventArgs e)
        {
            _buttonClicked = true;
            if (sender is Button button)
            {
                var param = button.CommandParameter as MetadataTypeModel;
                var result = await new MetadataUpsertDialog(param.Category.Id, param.Name).ShowAsync();
                if (result == ContentDialogResult.Primary)
                    await _categoriesViewModel.LoadMetadataAsync(param, reload: true);
            }
            _buttonClicked = false;
        }

        private async void EditMetadataButton_Click(object sender, RoutedEventArgs e)
        {
            if (sender is Button button)
            {
                var param = button.CommandParameter as CategoryMetadataModel;
                var result = await new MetadataUpsertDialog(param.CategoryId, param.MetadataType.Name, param.Id).ShowAsync();
                if (result == ContentDialogResult.Primary)
                    await _categoriesViewModel.LoadMetadataAsync(param.MetadataType, reload: true);
            }
        }

        private async void DeleteMetadataButton_Click(object sender, RoutedEventArgs e)
        {
            if (sender is Button button && button.CommandParameter is string id)
            {
                //Confirm diaglog before delete
                ContentDialog deleteDialog = new ContentDialog
                {
                    Title = "Confirm Delete?",
                    Content = "Are you sure want delete this metadata?",
                    PrimaryButtonText = "Delete",
                    CloseButtonText = "Cancel"
                };
                deleteDialog.PrimaryButtonStyle = Application.Current.Resources["PrimaryDialogButton"] as Style;
                deleteDialog.CloseButtonStyle = Application.Current.Resources["CloseDialogButton"] as Style;

                var result = await deleteDialog.ShowAsync();
                if (result == ContentDialogResult.Primary)
                {
                    var model = button.DataContext as CategoryMetadataModel;
                    await DeleteMetadataAsync(id);
                    await _categoriesViewModel.LoadMetadataAsync(model.MetadataType, reload: true);
                    model.MetadataType.IsExpanded = model.MetadataType.Metadata.Any();
                }
            }
        }

        private async Task DeleteMetadataAsync(string id)
        {
            if (id == null)
                return;
            using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                try
                {
                    var response = await httpClient.DeleteAsync(Api.MetadataById.FormatRoute(id));
                    if (response.IsSuccessStatusCode)
                    {
                        var messegaDialog = new MessageDialog("Category deleted successfully!");
                        await messegaDialog.ShowAsync();
                    }
                    else
                    {
                        var messegaDialog = new MessageDialog("Failed to delete category!");
                        await messegaDialog.ShowAsync();
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException))
                {

                }
            }
        }

        private async void TreeViewItem_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
        {
            if (_buttonClicked)
                return;

            var treeViewItem = sender as TreeViewItem;
            if (treeViewItem.IsExpanded)
            {
                treeViewItem.IsExpanded = false;
                return;
            }

            var shouldExpand = true;
            if (treeViewItem.Tag is string tag && !string.IsNullOrEmpty(tag) && tag == "Load")
            {
                var item = treeViewItem.DataContext as MetadataTypeModel;
                await _categoriesViewModel.LoadMetadataAsync(item);
                shouldExpand = item.Metadata.Any();
            }

            treeViewItem.IsExpanded = shouldExpand;
        }
    }
}
