using Blazor.Models;
using Blazor.ViewClasses;
using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components;
using static System.Net.WebRequestMethods;

namespace Blazor.Services
{
    public class DataLocalService : IDataService
    {
        private readonly HttpClient _http;
        private readonly ILocalStorageService _localStorage;
        private readonly NavigationManager _navigationManager;
        private readonly IWebHostEnvironment _webHostEnvironment;

        public DataLocalService(
            ILocalStorageService localStorage,
            HttpClient http,
            IWebHostEnvironment webHostEnvironment,
            NavigationManager navigationManager)
        {
            _localStorage = localStorage;
            _http = http;
            _webHostEnvironment = webHostEnvironment;
            _navigationManager = navigationManager;
        }

        public async Task<Chapter> GetById(int id)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Chapter>>("data");

            // Get the chapter int the list
            var chapter = currentData.FirstOrDefault(w => w.Id == id);

            // Check if chapter exist
            if (chapter == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            return chapter;
        }

        public async Task Update(int id, ChapterModel model)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Chapter>>("data");

            // Get the chapter int the list
            var chapter = currentData.FirstOrDefault(w => w.Id == id);

            // Check if chapter exist
            if (chapter == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            // Modify the content of the chapter
            chapter.Name = model.Name;

            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }


        public async Task Add(ChapterModel model)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Chapter>>("data");

            // Simulate the Id
            model.Id = currentData.Max(s => s.Id) + 1;

            // Add the chapter to the current data
            currentData.Add(new Chapter
            {
                Id = model.Id,
                Name = model.Name
            });

          
            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }

        public async Task Delete(int id)
        {
            // Get the current data
            //var currentData = await _localStorage.GetItemAsync<List<Chapter>>("data");
            var currentData = _http.GetFromJsonAsync<List<Chapter>>($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result;

            // Get the chapter int the list
            var chapter = currentData.FirstOrDefault(w => w.Id == id);

            // Delete chapter in
            currentData.Remove(chapter);

            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }

        public async Task<int> Count()
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Chapter[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Chapter[]>($"{_navigationManager.BaseUri}fake-data.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Chapter[]>("data")).Length;
        }

        public async Task<List<Chapter>> List(int currentPage, int pageSize)
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Chapter[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Chapter[]>($"{_navigationManager.BaseUri}fake-data.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Chapter[]>("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
        }

        public async Task<Administrator> GetAdminById(int id)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Administrator>>("data");

            // Get the admin int the list
            var admin = currentData.FirstOrDefault(w => w.Id == id);

            // Check if admin exist
            if (admin == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            return admin;
        }

        public async Task Update(int id, AdministratorModel model)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Administrator>>("data");

            // Get the admin int the list
            var admin = currentData.FirstOrDefault(w => w.Id == id);

            // Check if admin exist
            if (admin == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            // Modify the content of the adminnistrator
            admin.Username = model.Username;
            admin.HashedPassword = model.HashedPassword;

            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }

        public async Task Add(AdministratorModel model)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Administrator>>("data");

            // Simulate the Id
            model.Id = currentData.Max(s => s.Id) + 1;

            // Add the admin to the current data
            currentData.Add(new Administrator
            {
                Id = model.Id,
                Username = model.Username,
                HashedPassword = model.HashedPassword
            });


            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }

        public async Task<int> CountAdmin()
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Administrator[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Administrator[]>($"{_navigationManager.BaseUri}fake-administrator.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Administrator[]>("data")).Length;
        }

        public async Task<List<Administrator>> ListAdmin(int currentPage, int pageSize)
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Administrator[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Administrator[]>($"{_navigationManager.BaseUri}fake-administrator.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Administrator[]>("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
        }
        

        public async Task<Question> GetQuestionById(int id)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Question>>("data");

            // Get the question int the list
            var question = currentData.FirstOrDefault(w => w.Id == id);

            // Check if question exist
            if (question == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            return question;
        }

        //public async Task Update(int id, QuestionsModel model)
        //{
        //    // Get the current data
        //    var currentData = await _localStorage.GetItemAsync<List<Question>>("data");

        //    // Get the admin int the list
        //    var question = currentData.FirstOrDefault(w => w.Id == id);

        //    // Check if admin exist
        //    if (question == null)
        //    {
        //        throw new Exception($"Unable to found the item with ID: {id}");
        //    }

        //    // Modify the content of the adminnistrator
        //    question.Username = model.Username;
        //    question.HashedPassword = model.HashedPassword;

        //    // Save the data
        //    await _localStorage.SetItemAsync("data", currentData);
        //}

        //public async Task Add(QuestionsModel model)
        //{
        //    // Get the current data
        //    var currentData = await _localStorage.GetItemAsync<List<Question>>("data");

        //    // Simulate the Id
        //    model.Id = currentData.Max(s => s.Id) + 1;

        //    // Add the admin to the current data
        //    currentData.Add(new Question
        //    {
        //        Id = model.Id,
        //        Username = model.Username,
        //        HashedPassword = model.HashedPassword
        //    });


        //    // Save the data
        //    await _localStorage.SetItemAsync("data", currentData);
        //}

        public async Task<int> CountQuestion()
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Question[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Question[]>($"{_navigationManager.BaseUri}fake-question.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Question[]>("data")).Length;
        }

        public async Task<List<Question>> ListQuestion(int currentPage, int pageSize)
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Question[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Question[]>($"{_navigationManager.BaseUri}fake-question.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Question[]>("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
        }



        public async Task<Player> GetPlayerById(int id)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Player>>("data");

            // Get the player in the list
            var player = currentData.FirstOrDefault(w => w.Id == id);

            // Check if player exist
            if (player == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            return player;
        }

        public async Task Update(int id, PlayerModel model)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Player>>("data");

            // Get the admin int the list
            var player = currentData.FirstOrDefault(w => w.Id == id);

            // Check if admin exist
            if (player == null)
            {
                throw new Exception($"Unable to found the item with ID: {id}");
            }

            // Modify the content of the adminnistrator
            player.Nickname = model.Nickname;
            player.HashedPassword = model.HashedPassword;

            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }

        public async Task Add(PlayerModel model)
        {
            // Get the current data
            var currentData = await _localStorage.GetItemAsync<List<Player>>("data");

            // Simulate the Id
            model.Id = currentData.Max(s => s.Id) + 1;

            // Add the admin to the current data
            currentData.Add(new Player
            {
                Id = model.Id,
                Nickname = model.Nickname,
                HashedPassword = model.HashedPassword
            });


            // Save the data
            await _localStorage.SetItemAsync("data", currentData);
        }

        public async Task<int> CountPlayer()
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Player[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Player[]>($"{_navigationManager.BaseUri}fake-administrator.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Player[]>("data")).Length;
        }

        public async Task<List<Player>> ListPlayer(int currentPage, int pageSize)
        {
            // Load data from the local storage
            var currentData = await _localStorage.GetItemAsync<Player[]>("data");

            // Check if data exist in the local storage
            if (currentData == null)
            {
                // this code add in the local storage the fake data
                var originalData = await _http.GetFromJsonAsync<Player[]>($"{_navigationManager.BaseUri}fake-administrator.json");
                await _localStorage.SetItemAsync("data", originalData);
            }

            return (await _localStorage.GetItemAsync<Player[]>("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
        }
    }

}