namespace inutralia.ViewModels
{
    using inutralia.Models;
    using MvvmHelpers;
    using System.Diagnostics;
    using System.Threading.Tasks;
    using Xamarin.Forms;

    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;
        }
    }
}