using Http.Core;
using Http.Core.Exceptions;
using Http.Core.Extensions;
using PCUT.Entities;
using PCUT.Entities.ApiResponse;
using PCUT.Models;
using PCUT.Models.Users;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using static Http.Core.Constants.HttpConstants;

namespace PCUT.ViewModels
{
    public class LogViewModel : NotificationBase
    {
        public PaginationViewModel Pagination { get; } = new PaginationViewModel(withSearch: false);
        public SelectableCollection<UsersModel> Users { get; set; } = new SelectableCollection<UsersModel>(new UsersModel { UserName = "-None-" });
        public SelectableCollection<string> Types { get; set; } = new SelectableCollection<string>("-None-", new string[] { "login", "logout", "download", "cut" });
        public ObservableCollection<Log> Logs { get; }

        public LogViewModel()
        {
            Logs = new ObservableCollection<Log>();
            Pagination.PageChanged += OnPageChanged;
            Users.PropertyChanged += OnFilterChanged;
            Types.PropertyChanged += OnFilterChanged;
        }

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

        public async Task LoadUsersAsync()
        {
            using (var httpClient = HttpClientFactory.CreateClient(ClientNames.ApiClient))
            {
                try
                {
                    var response = await httpClient.GetAsync($"{Api.Users}?page=1&pageSize={int.MaxValue}");
                    if (response.IsSuccessStatusCode)
                    {
                        var apiResponse = await response.DeserializeObjectAsync<PaginationResponse<IEnumerable<UsersModel>>>();
                        var data = apiResponse.Data;
                        Users.Load(data);
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException))
                {
                }
            }
        }

        private async void OnFilterChanged(object sender, PropertyChangedEventArgs e)
        {
            if (Pagination.Page == 1)
                await LoadLogsAsync(Pagination.Page, Pagination.PageSize);
            else
                Pagination.Page = 1;
        }

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

                        Logs.Clear();
                        foreach (var log in data)
                            Logs.Add(log);
                    }
                }
                catch (Exception ex) when (!(ex is AppOutdatedException))
                {

                }
            }
        }

        private string CreateFilterUrl(int page, int pageSize/*, string searchText*/)
        {
            var builder = PathBuilder.FromRouteTemplate(Api.Log)
                                     .AddQuery("page", page.ToString())
                                     .AddQuery("pageSize", pageSize.ToString());

            var filterBuilder = new StringBuilder();
            if (Users.SelectedItem != default)
                filterBuilder.AppendFilter("userId", Users.SelectedItem.Id);
            if (Types.SelectedItem != default)
                filterBuilder.AppendFilter("action", Types.SelectedItem);
            var filter = filterBuilder.BuildFilter().ToString();
            builder.AddQuery("filter", filter);
            //if (!string.IsNullOrEmpty(searchText))
            //{
            //    var filter = new StringBuilder().AppendFilter("username", "cn", searchText).BuildFilter().ToString();
            //    builder.AddQuery("filter", filter);
            //}
            return builder.Build();
        }
    }
}
