using PCUT.Entities;
using PCUT.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Http.Core;
using Http.Core.Extensions;
using static Http.Core.Constants.HttpConstants;
using PCUT.Entities.ApiResponse;
using PCUT.Models.Categories;
using Windows.ApplicationModel.Core;
using Http.Core.Exceptions;

namespace PCUT.ViewModels
{
    public class CategoriesViewModel : NotificationBase
    {
        public PaginationViewModel Pagination { get; } = new PaginationViewModel(withSearch: true);
        public SelectableCollection<CategoryModel> FilteredCategories { get; }
        public CategoriesViewModel()
        {
            FilteredCategories = new SelectableCollection<CategoryModel>();

            Pagination.TextSearched += async (sender, args) => await SearchCategoryAsync(args.Text);
            Pagination.PageChanged += OnPageChanged;
        }

        private async void OnPageChanged(object sender, PageChangedEventArgs args)
        {
            await LoadCategoryAsync(args.Page, args.PageSize, Pagination.SearchText);
        }

        public async Task SearchCategoryAsync(string searchText)
        {
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
            {
                await LoadCategoryAsync(Pagination.Page, Pagination.PageSize, searchText);
            });
        }

        public async Task Reload()
        {
            await LoadCategoryAsync(Pagination.Page, Pagination.PageSize, Pagination.SearchText);
        }

        public async Task LoadCategoryAsync(int page, int pageSize, string searchText)
        {
            var url = CreateFilterUrl(page, pageSize, searchText);
            using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                try
                {
                    var response = await httpClient.GetAsync(url);
                    if (response.IsSuccessStatusCode)
                    {
                        var apiResponse = await response.DeserializeObjectAsync<PaginationResponse<IEnumerable<CategoryModel>>>();
                        var data = apiResponse.Data;
                        Pagination.Page = apiResponse.Pagination.Page;
                        Pagination.TotalPage = apiResponse.Pagination.TotalPages;
                        Pagination.TotalRecords = apiResponse.Pagination.TotalRecords;

                        int displayId = (apiResponse.Pagination.Page - 1) * pageSize + 1;
                        var categories = data.Select(category =>
                        {
                            category.DisplayId = displayId.ToString();
                            displayId++;
                            return category;
                        });
                        FilteredCategories.Load(categories);
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException))
                {

                }
            }
        }

        public async Task LoadMetadataAsync(MetadataTypeModel metadataType, bool reload = false)
        {
            if (reload || !metadataType.IsLoaded)
            {
                metadataType.IsLoaded = true;
                using (var client = HttpClientFactory.CreateClient(ClientNames.ApiClient))
                {
                    try
                    {
                        var url = PathBuilder.FromRouteTemplate(Api.Metadata)
                                             .AddQuery("filter", $"[\"type:eq:{metadataType.Name.ToUpper()}\", \"categoryId:eq:{metadataType.Category.Id}\"]")
                                             .AddQuery("sort", "createdAt:desc")
                                             .Build();
                        var response = await client.GetAsync(url);
                        if (response.IsSuccessStatusCode)
                        {
                            var content = await response.DeserializeObjectAsync<PaginationResponse<IEnumerable<CategoryMetadataModel>>>();
                            metadataType.Metadata.Clear();
                            var id = 0;
                            foreach (var model in content.Data)
                            {
                                model.DisplayId = ++id;
                                model.MetadataType = metadataType;
                                metadataType.Metadata.Add(model);
                            }
                        }
                    }
                    catch (Exception ex) when (!(ex is AppOutdatedException))
                    {
                    }
                }
            }
        }

        private string CreateFilterUrl(int page, int pageSize, string searchText)
        {
            var builder = PathBuilder.FromRouteTemplate(Api.Categories)
                                     .AddQuery("page", page.ToString())
                                     .AddQuery("pageSize", pageSize.ToString());
            if (!string.IsNullOrEmpty(searchText))
            {
                var filter = new StringBuilder().AppendFilter("name", "cn", searchText).BuildFilter().ToString();
                builder.AddQuery("filter", filter);
            }
            return builder.Build();
        }
    }
}
