using Borepin.ViewModel;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;
using Prism.Commands;
using Prism.Navigation;
using Borepin.Base;
using FabAccessAPI.Schema;
using Prism.Services;
using System;
using NaturalSort.Extension;
using System.Linq;
using Borepin.Service;
using Xamarin.Forms;
using System.Globalization;

namespace Borepin.PageModel
{
    public class UserListPageModel : ConnectionModelBase
    {
        #region Constructors
        public UserListPageModel(INavigationService navigationService, IPageDialogService pageDialogService, IAPIService apiService) : base(navigationService, pageDialogService, apiService)
        {
            RefreshCommand = new DelegateCommand(async ()=> await RefreshCommandExecute().ConfigureAwait(true));
            AddUserCommand = new DelegateCommand(AddUserCommandExecute);
            SearchUserCommand = new DelegateCommand(SearchUserCommandExecute);
        }
        #endregion

        #region Data
        public override async Task LoadAPIData()
        {
            List<Task> tasks = new List<Task>();

            IReadOnlyList<User> user_list = await _API.Session.UserSystem.Manage.GetUserList().ConfigureAwait(false);

            List<UserListItemViewModel> viewmodel_list= new List<UserListItemViewModel>();
            foreach (User user in user_list)
            {
                UserListItemViewModel new_viewmodel = new UserListItemViewModel(_NavigationService, _PageDialogService);
                tasks.Add(new_viewmodel.LoadInstance(user));
                viewmodel_list.Add(new_viewmodel);
            }

            await Task.WhenAll(tasks).ConfigureAwait(false);
            UserListItemViewModel_List = new List<UserListItemViewModel>(viewmodel_list.OrderBy(x => x.User.Username, StringComparison.OrdinalIgnoreCase.WithNaturalSort()));
        
            FilteredUserListItemViewModel_List = new List<UserListItemViewModel>(viewmodel_list.OrderBy(x => x.User.Username, StringComparison.OrdinalIgnoreCase.WithNaturalSort()));
        }
        #endregion

        #region Fields
        private IList<UserListItemViewModel> _UserListItemViewModel_List;
        public IList<UserListItemViewModel> UserListItemViewModel_List
        {
            get => _UserListItemViewModel_List;
            set => SetProperty(ref _UserListItemViewModel_List, value);
        }

        private IList<UserListItemViewModel> _FilteredUserListItemViewModel_List;
        public IList<UserListItemViewModel> FilteredUserListItemViewModel_List
        {
            get => _FilteredUserListItemViewModel_List;
            set => SetProperty(ref _FilteredUserListItemViewModel_List, value);
        }

        private string _SearchUsername;
        public string SearchUsername
        {
            get => _SearchUsername;
            set => SetProperty(ref _SearchUsername, value);
        }
        #endregion

        #region Commands
        private ICommand _RefreshCommand;
        public ICommand RefreshCommand
        {
            get => _RefreshCommand;
            set => SetProperty(ref _RefreshCommand, value);
        }
        public async Task RefreshCommandExecute()
        {
            if(_API.IsConnected)
            {
                try
                {
                    await LoadAPIData().ConfigureAwait(true);
                }
                catch (Exception)
                {
                    // TODO
                }
            }
        }

        private ICommand _AddUserCommand;
        public ICommand AddUserCommand
        {
            get => _AddUserCommand;
            set => SetProperty(ref _AddUserCommand, value);
        }
        public void AddUserCommandExecute()
        {
            Device.BeginInvokeOnMainThread(async () =>
            {
                INavigationResult result = await _NavigationService.NavigateAsync("AddUserPage").ConfigureAwait(false);
                if (result.Exception != null)
                {
                    Log.Fatal(result.Exception, "Navigating failed");
                }
            });
        }

        private ICommand _SerachUserCommand;
        public ICommand SearchUserCommand
        {
            get => _SerachUserCommand;
            set => SetProperty(ref _SerachUserCommand, value);
        }
        public void SearchUserCommandExecute()
        {
            List<UserListItemViewModel> users = new List<UserListItemViewModel>(UserListItemViewModel_List);
            FilteredUserListItemViewModel_List = users.FindAll(x => x.User.Username.ToLower(CultureInfo.InvariantCulture).Contains(SearchUsername.ToLower(CultureInfo.InvariantCulture)));
        }
        #endregion
    }
}
