using System;
using BlazorApp.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using BlazorApp.Services;
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Localization;
using System.Collections.Generic;
using BlazorApp.Pages;
using BlazorApp.Data;
using System.Text.Json;

namespace BlazorApp.Components
{
    public partial class InventoryComp : IDisposable
    {

        [Inject]
        public IConfiguration Configuration { get; set; }

        [Parameter]
        public int InventorySize { get; set; }

        public Item CurrentDragItem { get; set; }

        public int CurrentDragIndex { get; set; }

        public int CurrentDragNbItem { get; set; }

        [Inject]
        public IDataService DataService { get; set; }

        [Inject]
        public ISaverInventory SaverInventory { get; set; }

        [Inject]
        public ILoaderInventory LoaderInventory { get; set; }

        [Inject]
        public IStringLocalizer<InventoryComp> Localizer { get; set; }

        [Parameter]
        public List<Item> Items { get; set; }

        public List<SavableItem> InventoryItems { get; set; }

        public ObservableCollection<InventoryAction> Actions { get; set; }

        [Inject]
        internal IJSRuntime JavaScriptRuntime { get; set; }

        private int totalItem;

        public bool IsSorted { get; set; }

        private int PageSize { get; set; }

        private int CurrentPage { get; set; }

        private string Recherche { get; set; }


        public InventoryComp()
        {
            Actions = new ObservableCollection<InventoryAction>();

            Actions.CollectionChanged += OnActionsCollectionChanged;
        }

        protected override void OnInitialized()
        {

            InventorySize = int.Parse(Configuration["InventorySize"]);

            InventoryItems = LoaderInventory.LoadItems();

            if (InventorySize < InventoryItems.Count)
            {
                InventoryItems.RemoveRange(InventorySize, InventoryItems.Count - InventorySize);
            }

            for (int i=0; i<InventoryItems.Count; i++)
            {
                if (InventoryItems[i] == null)
                {
                    InventoryItems[i] = new SavableItem(null, -1);
                }
            }
            if (InventoryItems.Count < InventorySize)
            {
                for (int i = InventoryItems.Count; InventoryItems.Count < InventorySize; i++)
                {
                    InventoryItems.Add(new SavableItem(null, -1));
                }
            }
        }

        public void Dispose()
        {
            SaverInventory.SaveItems(InventoryItems);

        }



        private void OnActionsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            JavaScriptRuntime.InvokeVoidAsync("Inventory.AddActions", e.NewItems);
        }

        /// <summary>
        /// Event called when the dataGrid is initialized or when the user change page
        /// </summary>
        private async Task OnReadData(DataGridReadDataEventArgs<Item> e)
        {
            if (e.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            //Enable us to know the current page and the page size for the OnInput and SortByName event
            CurrentPage = e.Page;
            PageSize = e.PageSize;

            //Test if the dataGrid is not sorted and if there is nothing in the search bar to get the items in a unsorted way
            if (!e.CancellationToken.IsCancellationRequested && !IsSorted && string.IsNullOrWhiteSpace(Recherche))
            {
                Items = await DataService.List(e.Page, e.PageSize);
                totalItem = await DataService.Count();

            }
            //Test if there is something on the search bar to get the items that start with the string in the search bar
            else if (!string.IsNullOrWhiteSpace(Recherche))
            {
                (Items, totalItem) = await DataService.SearchList(CurrentPage, PageSize, Recherche);

            }
            //Get the items in a sorted way
            else
            {
                Items = await DataService.SortedList(CurrentPage, PageSize);
            }
        }

        /// <summary>
        /// Event called when the user click on the Sort button
        /// </summary>
        private async Task SortByName()
        {
            //Sort the list
            if (!IsSorted)
            {
                IsSorted = true;
                Items = await DataService.SortedList(CurrentPage, PageSize);
            }
            //Unsort the List
            else
            {
                IsSorted = false;
                Items = await DataService.List(CurrentPage, PageSize);
            }
        }

        /// <summary>
        /// Event called when the user input something on the search bar
        /// </summary>
        private async void OnInput(Microsoft.AspNetCore.Components.ChangeEventArgs args)
        {
            Recherche = (string)args.Value; //Get the value from the search bar

            //Test if it is empty
            if (string.IsNullOrWhiteSpace(Recherche))
            {
                if (!IsSorted)
                {
                    //Get item in an unsorted way from all the items with the specified page and page size
                    Items = await DataService.List(CurrentPage, PageSize);
                }
                else
                {
                    //Get item in an sorted way from all the items with the specified page and page size
                    Items = await DataService.SortedList(CurrentPage, PageSize);
                }
                totalItem = await DataService.Count();
            }
            else
            {
                //Get the items that stat with the search bar value with the specified page and page size
                (Items, totalItem) = await DataService.SearchList(CurrentPage, PageSize, Recherche);
            }
            StateHasChanged();
        }

    }
}