using Blazored.LocalStorage;
using CurrieTechnologies.Razor.SweetAlert2;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using BlazorPages.Tools;

namespace AbrBlazorTools
{
    public class HttpClientWithLoginToken : IHttpClientWithLoginToken
    {
        private readonly HttpClient _httpClient = new HttpClient();
        private readonly ILocalStorageService _localStorage;
        private readonly CurrieTechnologies.Razor.SweetAlert2.SweetAlertService _swal;
        private readonly AbrBlazorTools.ILoadingSpinner _loadingSpinner;
        private readonly NavigationManager _navigationManager;
        private readonly IBrowserTools _browserTools;

        public HttpClientWithLoginToken(ILocalStorageService localStorage, CurrieTechnologies.Razor.SweetAlert2.SweetAlertService swal
            , AbrBlazorTools.ILoadingSpinner loadingSpinner, NavigationManager navigationManager, IBrowserTools browserTools)
        {
            _localStorage = localStorage;
            _swal = swal;
            _loadingSpinner = loadingSpinner;
            _navigationManager = navigationManager;
            _browserTools = browserTools;
            _httpClient.BaseAddress = new Uri(Statics.BaseAddress);
        }
        public async Task<HttpClient> GetInstance()
        {
            var hasToken = await _localStorage.ContainKeyAsync(Statics.LoginTokenKey);
            if (hasToken)
            {
                var token = await _localStorage.GetItemAsStringAsync(Statics.LoginTokenKey);
                if (token.StartsWith('"'))
                    token = token.Substring(1);
                if (token.EndsWith('"'))
                    token = token.Substring(0, token.Length - 1);
                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            }
            return _httpClient;
        }

        public async Task<HttpResponseMessage> HttpGet(string url, bool hasLoading = true, bool goToLogin = true)
        {
            var res=new HttpResponseMessage();
            Console.WriteLine("Get : " + url);

            if (hasLoading)
                await _loadingSpinner.ShowLoading();
            var http = await GetInstance();
            try
            {
                 res= await http.GetAsync(url);
                await _loadingSpinner.HideLoading();
                if (res.IsSuccessStatusCode)
                {

                    return res;
                }

                if (res.StatusCode == HttpStatusCode.Unauthorized)
                {
                    await _loadingSpinner.HideLoading();
                    if (goToLogin)
                    {
                        Console.WriteLine("خطای دسترسی");
                        _navigationManager.NavigateTo("/");
                    }
                }
                else if (res.StatusCode == HttpStatusCode.BadRequest)
                {
                    await _swal.FireAsync( message: res.ReasonPhrase, icon: SweetAlertIcon.Error);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                await _loadingSpinner.HideLoading();
                await _swal.FireAsync( message: res.ReasonPhrase, icon: SweetAlertIcon.Error);

            }
            await _loadingSpinner.HideLoading();
            return new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest };
        }
        public async Task<HttpResponseMessage> HttpDelete(string url, bool hasLoading = true)
        {
            Console.WriteLine("Delete : " + url);
            var res = new HttpResponseMessage();
            if (hasLoading)
                await _loadingSpinner.ShowLoading();
            var http = await GetInstance();
            try
            {
                 res = await http.DeleteAsync(url);
                await _loadingSpinner.HideLoading();
                if (res.IsSuccessStatusCode)
                {

                    return res;
                }
                if (res.StatusCode == HttpStatusCode.Unauthorized)
                {
                    await _loadingSpinner.HideLoading();
                    _navigationManager.NavigateTo("/");
                }
                else
                {
                    dynamic error = JsonConvert.DeserializeObject<object>(await res.Content.ReadAsStringAsync());
                    await _swal.FireAsync( message: await ErrorMessage(res), icon: SweetAlertIcon.Error);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                await _loadingSpinner.HideLoading();
                dynamic error = JsonConvert.DeserializeObject<object>(await res.Content.ReadAsStringAsync());
                await _swal.FireAsync( message: await ErrorMessage(res), icon: SweetAlertIcon.Error);
                Statics.CurrentLoginInfo = new();
            }
            await _loadingSpinner.HideLoading();
            return new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest };
        }

        public async Task<HttpResponseMessage> HttpPut(string url, object model, bool hasLoading = true)
        {
            Console.WriteLine("Put : " + url);
            var res = new HttpResponseMessage();

            if (hasLoading)
                await _loadingSpinner.ShowLoading();
            var http = await GetInstance();
            try
            {
                var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json");
                res = await http.PutAsync(url, content);
                await _loadingSpinner.HideLoading();
                if (res.IsSuccessStatusCode)
                {

                    return res;
                }
                if (res.StatusCode == HttpStatusCode.Unauthorized)
                {
                    await _loadingSpinner.HideLoading();
                    Statics.CurrentLoginInfo = new();
                }
                else
                {
                    await _swal.FireAsync( message: await ErrorMessage(res), icon: SweetAlertIcon.Error);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                await _loadingSpinner.HideLoading();                
                await _swal.FireAsync( message: await ErrorMessage(res), icon: SweetAlertIcon.Error);
                Statics.CurrentLoginInfo = new();
            }
            await _loadingSpinner.HideLoading();
            return new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest };
        }

        public async Task<HttpResponseMessage> HttpPost(string url, object model, bool hasLoading = true, bool multiPart = false)
        {
            Console.WriteLine("Post : " + url);
            var res = new HttpResponseMessage();

            if (hasLoading)
                await _loadingSpinner.ShowLoading();
            var http = await GetInstance();
            try
            {
                res = new HttpResponseMessage();
                var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json");
                res = await http.PostAsync(url, content);

                await _loadingSpinner.HideLoading();
                if (res.IsSuccessStatusCode)
                {

                    return res;
                }
                if (res.StatusCode == HttpStatusCode.Unauthorized)
                {
                    await _loadingSpinner.HideLoading();
                    _navigationManager.NavigateTo("/");
                }
                else
                {                    
                    await _swal.FireAsync( message: await ErrorMessage(res), icon: SweetAlertIcon.Error);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                await _loadingSpinner.HideLoading();                            
            }
            await _loadingSpinner.HideLoading();
            return res;
        }
        private async Task<string> ErrorMessage(HttpResponseMessage res)
        {
            var errStr = "خطای نامشخص";
            dynamic error = JsonConvert.DeserializeObject<object>(await res.Content.ReadAsStringAsync());
            if (error.errors != null)
            {
                errStr = (string)("" + error.errors);
                if (errStr.Contains(":"))
                    errStr = errStr.Split(':')[1].Replace(":", "").Replace("{", "")
                        .Replace("}", "").Replace("[", "").Replace("]","").Replace("\"","");
            }
            return errStr;
        }
    }
    public interface IHttpClientWithLoginToken
    {
        Task<HttpClient> GetInstance();
        Task<HttpResponseMessage> HttpPost(string url, object model, bool hasLoading = true, bool multiPart = false);
        Task<HttpResponseMessage> HttpGet(string url, bool hasLoading = true, bool goToLogin = true);
        Task<HttpResponseMessage> HttpDelete(string url, bool hasLoading = true);
        Task<HttpResponseMessage> HttpPut(string url, object model, bool hasLoading = true);
    }
}
