using System;
using System.Collections.Generic;
using BlazorApp.Components;
using BlazorApp.Factories;
using BlazorApp.Models;
using static System.Formats.Asn1.AsnWriter;

namespace BlazorApp.Services
{
    public class DataApiService : IDataService
    {
        private readonly HttpClient _http;

        public DataApiService(
            HttpClient http)
        {
            _http = http;
        }

        public async Task Add(ItemModel model)
        {
            // Get the item
            var item = ItemFactory.Create(model);

            // Save the data
            await _http.PostAsJsonAsync("https://localhost:7234/api/Crafting/", item);
        }

        public async Task<int> Count()
        {
            return await _http.GetFromJsonAsync<int>("https://localhost:7234/api/Crafting/count");
        }

        public async Task<List<Item>> List(int currentPage, int pageSize)
        {
            return await _http.GetFromJsonAsync<List<Item>>($"https://localhost:7234/api/Crafting/?currentPage={currentPage}&pageSize={pageSize}");
        }

        public async Task<Item> GetById(int id)
        {
            return await _http.GetFromJsonAsync<Item>($"https://localhost:7234/api/Crafting/{id}");
        }

        public async Task Update(int id, ItemModel model)
        {
            // Get the item
            var item = ItemFactory.Create(model);

            await _http.PutAsJsonAsync($"https://localhost:7234/api/Crafting/{id}", item);
        }

        public async Task Delete(int id)
        {
            await _http.DeleteAsync($"https://localhost:7234/api/Crafting/{id}");
        }

        public async Task<List<CraftingRecipe>> GetRecipes()
        {
            return await _http.GetFromJsonAsync<List<CraftingRecipe>>("https://localhost:7234/api/Crafting/recipe");
        }

        /// <summary>
        /// Method that gets the items from the api in a sorted way from a specified page and page size
        /// </summary>
        public async Task<List<Item>> SortedList(int currentPage, int pageSize)
        {
            List<Item> it = await _http.GetFromJsonAsync<List<Item>>($"https://localhost:7234/api/Crafting/all/");
            it = it.OrderBy(i => i.DisplayName).ToList(); //Sort the list

            int indexDeb = (currentPage - 1) * pageSize;

            if (indexDeb + pageSize > it.Count) //test to prevent the it.GetRange from searching in a index out of range 
            {
                int tmp = indexDeb + pageSize - it.Count;
                return it.GetRange(indexDeb, pageSize - tmp);
            }
            return it.GetRange(indexDeb, pageSize); //Get only the items we want

        }

        /// <summary>
        /// Method that gets the items from the api in a sorted way that start with a specified string from a specified page and page size
        /// </summary>
        public async Task<(List<Item>, int)> SearchList(int currentPage, int pageSize, string recherche)
        {
            IEnumerable<Item> it = await _http.GetFromJsonAsync<List<Item>>($"https://localhost:7234/api/Crafting/all/");
            it = it.OrderBy(i => i.DisplayName).ToList(); //Sort the item

            // Gets the items that start with the string
            it = from item in it
                 where item.DisplayName.StartsWith(recherche)
                 select item;

            //Changes the current page so it is not out of range
            if (currentPage*10 > it.Count())
            {
                currentPage = it.Count() / pageSize + 1;
            }

            int indexDeb = (currentPage - 1) * pageSize;

            if (it.Count() == 0)
            {
                return (it.ToList(), it.Count());
            }

            if (indexDeb + pageSize > it.Count()) //test to prevent the it.GetRange from searching in a index out of range 
            {
                int tmp = (indexDeb + pageSize) - it.Count();
                return( it.ToList().GetRange(indexDeb, pageSize - tmp), it.Count());
            }
            return (it.ToList().GetRange(indexDeb, pageSize), it.Count());

        }

    }
}