using inutralia.Models;
using MvvmHelpers;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace inutralia.ViewModels
{
    public class RecipeListViewModel : BaseNavigationViewModel
    {
        public RecipeListViewModel()
        {
            Title = "Recetas";

            Filters = new RecipeListOptionsViewModel();
        }

        public RecipeListOptionsViewModel Filters
        { get; private set; }

        // Lista de articulos
        ObservableRangeCollection<Recipe> _Recipes;

        // Comando de update del listadd
        Command _RefreshRecipesCommand;

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

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

        // Indica si hay resultados
        public bool IsEmpty => IsNotBusy && (Recipes.Count < 1);
        public bool IsNotEmpty => IsNotBusy && (Recipes.Count > 0);
        /// <summary>
        /// Método que realiza la carga inicial del listado
        /// </summary>
        public async Task ExecuteLoadRecipesCommand()
        {
            // Realiza el proceso de actualización si hay menos de un 
            // elemento en el listado
            if (Recipes.Count < 1)
                await FetchRecipes();
        }

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


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

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

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

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

            // 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
            {
                string flags = string.Empty;
                string orFlags = string.Empty;
                foreach (var gr in Filters.Groups)
                {
                    foreach (var cat in gr.Group.Options)
                    {
                        if (cat.Selected)
                        {
                            if (gr.Group.Id == 1)
                            {
                                if (orFlags.Length > 0)
                                    orFlags += ",";
                                orFlags += cat.Id.ToString ();
                            }
                            else
                            {
                                if (flags.Length > 0)
                                    flags += ",";
                                flags += cat.Id.ToString ();
                            } //endif
                        } //endif
                    } //endforeach
                } //endforeach

                if (string.IsNullOrEmpty (flags) && string.IsNullOrEmpty (orFlags) && string.IsNullOrEmpty(Filters?.Desc) )
                {
                    Recipes = new ObservableRangeCollection<Recipe> (await App.API.RefreshListAsync<Recipe> ());
                }
                else
                {
                    var options = new Dictionary<string, string> ();
                    if (!string.IsNullOrEmpty (flags)) options.Add ("flags", flags);
                    if (!string.IsNullOrEmpty (orFlags)) options.Add ("flags_or", orFlags);
                    if (!string.IsNullOrEmpty (Filters?.Desc)) options.Add ("desc", Filters.Desc);

                    var recipes = await App.API.RawMessage<List<Recipe>> (HttpMethod.Post, "recipes", options);
                    Recipes = new ObservableRangeCollection<Recipe> (recipes);
                } //endif
            }
            catch (System.Exception e)
            {
                Recipes.Clear();
            }

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

    }
}
