using Microsoft.Extensions.Caching.Distributed;
using PARR.DAL.Migrations;
using System.Text.Json;

namespace PARR.DAL.Cache.Services.Base
{
    internal class RedisCacheService : IRedisCacheService
    {
        private readonly IDistributedCache cache;

        public RedisCacheService(IDistributedCache cache)
        {
            this.cache = cache;
        }

        public async Task<T?> GetCachedDataAsync<T>(string key)
        {
            var jsonData = await cache.GetStringAsync(key);

            if (jsonData == null)
                return default(T);

            return JsonSerializer.Deserialize<T>(jsonData);
        }


        public T? GetCachedData<T>(string key)
        {
            var jsonData = cache.GetString(key);

            if (jsonData == null)
                return default(T);

            return JsonSerializer.Deserialize<T>(jsonData);
        }


        public void SetCachedData<T>(string key, T data, TimeSpan cacheDuration)
        {
            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = cacheDuration
            };

            var jsonData = JsonSerializer.Serialize(data);
            cache.SetString(key, jsonData, options);
        }


        public async Task SetCachedDataAsync<T>(string key, T data, TimeSpan cacheDuration)
        {
            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = cacheDuration
            };

            var jsonData = JsonSerializer.Serialize(data);
            await cache.SetStringAsync(key, jsonData, options);
        }


        public async Task DeleteCachedDataAsync(string key)
        {
            await cache.RemoveAsync(key);
        }


        public void DeleteCachedData(string key)
        {
            cache.Remove(key);
        }


        public string GetKey(string[] keyParts, bool isUseHash = false)
        {
            if (keyParts.Length == 0)
            {
                throw new ArgumentNullException("keyParts не может быть пустым");
            }

            var keyStr = string.Join("_", keyParts);

            if (isUseHash)
            {
                using var sha256 = System.Security.Cryptography.SHA256.Create();
                var hashedBytes = sha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(keyStr));

                // return Convert.ToBase64String(hashedBytes).Replace('+', '-').Replace('/', '_').Substring(0, 16);
                return Convert.ToBase64String(hashedBytes).Substring(0, 16);
            }

            return keyStr;
        }

    }
}
