// Copyright © Selmo Technology GmbH. All Rights Reserved

using Frontend.Blazor.Code;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using SelmoStudio.Hmi.Plugin.Services;
using System.Security.Claims;
using System.Security.Cryptography;

namespace SelmoStudio.Hmi.Server.Service
{
    public class CachingService : ICachingService
    {
        private const string AccessToken = nameof(AccessToken);
        private const string RefreshToken = nameof(RefreshToken);
        private readonly ProtectedLocalStorage _localStorage;
        private readonly IConfiguration _configuration;

        public CachingService(ProtectedLocalStorage localStorage, IConfiguration configuration)
        {
            _localStorage = localStorage;
            _configuration = configuration;
        }

        public async Task StoreTokenInBrowserCache(string jwtToken, string refreshToken)
        {
            await _localStorage.SetAsync(AccessToken, jwtToken);
            await _localStorage.SetAsync(RefreshToken, refreshToken);
        }

        public async Task CleanupTokenInBrowserCache()
        {
            await _localStorage.DeleteAsync(AccessToken);
            await _localStorage.DeleteAsync(RefreshToken);
        }

        public async Task<List<Claim>> GetClaimsAsync()
        {
            var emptyResult = new List<Claim>();
            ProtectedBrowserStorageResult<string> accessToken;
            ProtectedBrowserStorageResult<string> refreshToken;
            try
            {
                accessToken = await _localStorage.GetAsync<string>(AccessToken);
                refreshToken = await _localStorage.GetAsync<string>(RefreshToken);
            }
            catch (CryptographicException)
            {
                await StoreTokenInBrowserCache(string.Empty, string.Empty);
                return emptyResult;
            }

            if (accessToken.Success is false || accessToken.Value == default)
                return emptyResult;

            var claims = JwtTokenHelper.ValidateDecodeToken(accessToken.Value, _configuration);

            if (claims.Count != 0)
                return claims;

            if (refreshToken.Value != default)
            {
                ////var response = await _backendApiHttpClient.RefreshTokenAsync(refreshToken.Value);
                //if (string.IsNullOrWhiteSpace(response?.Result?.JwtToken) is false)
                //{
                //    await _localStorage.SetAsync(AccessToken, response.Result.JwtToken);
                //    //await _localStorage.SetAsync(RefreshToken, response.Result.RefreshToken);
                //    claims = JwtTokenHelper.ValidateDecodeToken(response.Result.JwtToken, _configuration);
                //    return claims;
                //}
            }

            return claims;
        }

        public string? LastToken { get; set; }
        public ClaimsPrincipal LastClaimsPrincipal { get; private set; }

        public void SetLastClaimsPrincipal(ClaimsPrincipal lastClaimsPrincipal)
        {
            LastClaimsPrincipal = lastClaimsPrincipal;
        }

        public async Task<TValue> GetAsync<TValue>(string key, TValue defaultValue)
        {
            try
            {
                var value = await _localStorage.GetAsync<TValue>(key);
                return value.Value;
            }
            catch (CryptographicException)
            {
                return defaultValue;
            }
        }

        public async Task SetAsync(string key, object value)
        {
            await _localStorage.SetAsync(key, value);
        }
    }
}