using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using System.Text;

namespace QRRapidoApp.Services
{
    public class MemoryDistributedCacheWrapper : IDistributedCache
    {
        private readonly IMemoryCache _memoryCache;

        public MemoryDistributedCacheWrapper(IMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }

        public byte[]? Get(string key)
        {
            var value = _memoryCache.Get<string>(key);
            return value != null ? Encoding.UTF8.GetBytes(value) : null;
        }

        public Task<byte[]?> GetAsync(string key, CancellationToken token = default)
        {
            return Task.FromResult(Get(key));
        }

        public void Set(string key, byte[] value, DistributedCacheEntryOptions options)
        {
            var stringValue = Encoding.UTF8.GetString(value);
            var memoryCacheOptions = new MemoryCacheEntryOptions();

            if (options.AbsoluteExpiration.HasValue)
                memoryCacheOptions.AbsoluteExpiration = options.AbsoluteExpiration;
            else if (options.AbsoluteExpirationRelativeToNow.HasValue)
                memoryCacheOptions.AbsoluteExpirationRelativeToNow = options.AbsoluteExpirationRelativeToNow;

            if (options.SlidingExpiration.HasValue)
                memoryCacheOptions.SlidingExpiration = options.SlidingExpiration;

            _memoryCache.Set(key, stringValue, memoryCacheOptions);
        }

        public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default)
        {
            Set(key, value, options);
            return Task.CompletedTask;
        }

        public void Refresh(string key)
        {
            // Memory cache doesn't need refresh
        }

        public Task RefreshAsync(string key, CancellationToken token = default)
        {
            return Task.CompletedTask;
        }

        public void Remove(string key)
        {
            _memoryCache.Remove(key);
        }

        public Task RemoveAsync(string key, CancellationToken token = default)
        {
            Remove(key);
            return Task.CompletedTask;
        }
    }
}