using inutralia.Models;
using System.Threading.Tasks;
using MvvmHelpers;    // Este namespace está en el paquete Refractored.MvvmHelpers
using Xamarin.Forms;
using System.Collections.Generic;
using System.Diagnostics;

namespace inutralia.ViewModels
{
	public class ArticleListViewModel : BaseViewModel
	{
		public ArticleListViewModel()
		{
		}

		// Lista de articulos
		ObservableRangeCollection<Article> _Articles;

		// Comando de update del listadd
		Command _RefreshArticlesCommand;

        // Acceso a la lista de articulos
        public ObservableRangeCollection<Article> Articles
		{ 
			// Getter (lazy load), crea la lista si no existe
			get { return _Articles ?? (_Articles = new ObservableRangeCollection<Article>()); }

			// Setter. cambiar el valor y notifica a la vista de dicho cambio
			set
			{
				_Articles = value;
				OnPropertyChanged("Articles");
			}
		}

		/// <summary>
		/// Método que realiza la carga inicial del listado
		/// </summary>
		public async Task ExecuteLoadArticlesCommand()
		{
			// Realiza el proceso de actualización si hay menos de un 
			// elemento en el listado
			if (Articles.Count < 1)
				await FetchArticles();
		}

		/// <summary>
		/// Acceso al comando de actualización del listado
		/// </summary>
		public Command RefreshArticlesCommand
		{
			// Getter (lazy load), crea el comando si no existe
			get { return _RefreshArticlesCommand ?? (_RefreshArticlesCommand = new Command(async () => await ExecuteRefreshArticlesCommand())); }
		}


		/// <summary>
		/// Proceso de ejecución del comando de actualización del listado
		/// </summary>
		async Task ExecuteRefreshArticlesCommand()
		{
			// Hace que el comando no se pueda ejecutar de nuevo
			RefreshArticlesCommand.ChangeCanExecute();

			// Realiza el proceso de actualización
			await FetchArticles();

			// Hace que el comando pueda volver a ejecutarse
			RefreshArticlesCommand.ChangeCanExecute();
		}

		/// <summary>
		/// Proceso de actualización del listado
		/// </summary>
		async Task FetchArticles()
		{
			// Indicamos que estamos ocupados (provoca que aparezca el indicador de carga)
			IsBusy = true;

			// Llamada al API para coger el listado (provoca que se actualize la vista del listado)
			// Nota: Al obtener el listado, el controlador Rest del servidor no retorna el cuerpo de
			// la notificación (campo Body)
			try
			{
				Articles = new ObservableRangeCollection<Article>(await App.API.RefreshListAsync<Article>());
			}
			catch (System.Exception e)
			{
                Debug.WriteLine(e.Message);
                    Articles.Clear();
			}

			// Indicamos que ya no estamos ocupados (provoca que desaparezca el indicador de carga)
			IsBusy = false;
		}
	}
}