using System;
using Kreta.Core;
using Kreta.Ellenorzo.Domain.VN.Ertekeles.Atlag.TantargyiAtlag;
using Kreta.Framework.Caching;

namespace Kreta.BusinessLogic.Caching
{
    public class TantargyiAtlagCache : GenericCache<object>
    {
        private static readonly string TantargyiAtlagCacheKeyPrefix = $"{Constants.Cache.CacheKeyPrefix}TantargyiAtlagCache_";
        private static readonly string TantargyiAtlagRegionPrefix = $"{Constants.Cache.CacheKeyPrefix}TantargyiAtlagCacheRegion_";
        private static readonly string TantargyiAtlagTriggerPrefix = $"{Constants.Cache.CacheKeyPrefix}TantargyiAtlagTrigger_";

        public TantargyiAtlagCache(Framework.Caching.CacheManager cacheManager) : base(cacheManager, nameof(TantargyiAtlagCache))
        {
        }

        private string GetCacheKey(string keyPrefix, int userId, string instituteCode, string tantargyUid, int? oktatasiNevelesiFeladatId)
        {
            return $"{keyPrefix}{instituteCode}.{userId}.{tantargyUid}.{oktatasiNevelesiFeladatId}";
        }
        private static string GetTantargyiAtlagRegionKey(string instituteCode) => $"{TantargyiAtlagRegionPrefix}{instituteCode}";

        public TantargyiAtlagListResponse GetTantargyiAtlag(int userId, string instituteCode, string tantargyUid, int? oktatasiNevelesiFeladatId)
        {
            string key = GetCacheKey(TantargyiAtlagCacheKeyPrefix, userId, instituteCode, tantargyUid, oktatasiNevelesiFeladatId);
            string region = GetTantargyiAtlagRegionKey(instituteCode);

            return (TantargyiAtlagListResponse)GetByKeyAndRegion(key, region);
        }

        public void AddOrUpdateTantargyiAtlag(int userId, string instituteCode, string tantargyUid, int? oktatasiNevelesiFeladatId, TantargyiAtlagListResponse value)
        {
            AddOrUpdateWithRegion(GetCacheKey(TantargyiAtlagCacheKeyPrefix, userId, instituteCode, tantargyUid, oktatasiNevelesiFeladatId), GetTantargyiAtlagRegionKey(instituteCode), value, k => value);
        }

        public void RemoveTantargyiAtlag(int userId, string instituteCode, string tantargyUid, int? oktatasiNevelesiFeladatId)
        {
            string key = GetCacheKey(TantargyiAtlagCacheKeyPrefix, userId, instituteCode, tantargyUid, oktatasiNevelesiFeladatId);

            RemoveFromRegion(key, GetTantargyiAtlagRegionKey(instituteCode));
        }

        /// <summary>
        /// Értékelés adásánál szükséges készítenünk egy fake kulcsot ami majd adott késleltetés lejáratakor ki fogja ütni az adott tantárgyi atlag cache hogy frissülni tudjon.
        /// </summary>
        /// <param name="userId">user id-ja</param>
        /// <param name="instituteCode">intézmény</param>
        /// <param name="tantargyUid">tantargy uid</param>
        /// <param name="oktatasiNevelesiFeladatId">oktatasnevelesfeladat id</param>
        /// <param name="timeSpan">késleltetés időtartama</param>
        public void SetTantargyiAtlagExpiration(int userId, string instituteCode, string tantargyUid, int? oktatasiNevelesiFeladatId, TimeSpan timeSpan)
        {
            string cacheKey = GetCacheKey(TantargyiAtlagCacheKeyPrefix, userId, instituteCode, tantargyUid, oktatasiNevelesiFeladatId);
            var triggerKey = $"{TantargyiAtlagTriggerPrefix}{DateTime.Now.Add(timeSpan):yyyyMMddHHmmss}:{GetTantargyiAtlagRegionKey(instituteCode)}:{cacheKey}";
            AddWithAbsoluteExpiration(triggerKey, timeSpan, string.Empty);
        }

        /// <summary>
        ///Adott intézményben az összes tantárgyi átlaghoz tartozó cache-t törlése
        /// </summary>
        public void ClearTantargyiAtlagRegion(string instituteCode)
        {
            ClearRegion(GetTantargyiAtlagRegionKey(instituteCode));
        }
    }
}