using adas_core.Application.Services.Interfaces;
using adas_core.Domain.Models.GroupedObservations;
using MongoDB.Bson;

namespace adas_core.Application.Services.Caching
{
    /// <summary>
    /// Implementación nula de ICacheService.
    /// No almacena nada, no devuelve nada y no interfiere con el flujo.
    /// Se usa cuando el CacheMode es "None".
    /// </summary>
    public class NoCacheService : ICacheService
    {
        public void SetValue(string key, string value)
        {
            // No hacer nada
        }

        public string? GetValue(string key)
        {
            return null;
        }

        public Task<T?> GetObjectAsync<T>(string key, bool updateExpiration = true)
        {
            return Task.FromResult<T?>(default);
        }

        public Task SetObjectAsync<T>(string key, T obj, bool updateExpiration = true)
        {
            return Task.CompletedTask;
        }

        public Task<T?> GetObjectAsync<T>(string key, TimeSpan? ttlOverride, bool updateExpiration)
        {
            return Task.FromResult<T?>(default);
        }

        public Task SetObjectAsync<T>(string key, T obj, TimeSpan? ttlOverride, bool updateExpiration)
        {
            return Task.CompletedTask;
        }

        public Task<long> DeleteByPatternAsync(string pattern)
        {
            return Task.FromResult(0L);
        }

        public Task DeleteObjectAsync(string key)
        {
            return Task.CompletedTask;
        }

        public void CleanCache()
        {
            // Nada que limpiar
        }

        // ============================================================
        // GET OR SET - STRING KEY
        // ============================================================

        public async Task<T> GetOrSetObjectAsync<T>(
            string key,
            Func<Task<T>> factory,
            TimeSpan? ttl = null,
            CancellationToken cancellationToken = default)
        {
            // En modo NONE no hay caché → siempre ejecutar factory
            return await factory();
        }

        public async Task<string?> GetOrSetValueAsync(
            string key,
            Func<Task<string>> loader,
            TimeSpan? ttl = null)
        {
            var result = await loader();
            return (string?)result;
        }

        // ============================================================
        // GET OR SET - GroupedField + patientId
        // ============================================================

        public async Task<T> GetOrSetObjectAsync<T>(
            GroupedField groupedField,
            ObjectId patientId,
            Func<Task<T>> factory,
            TimeSpan? ttl = null,
            CancellationToken cancellationToken = default)
        {
            // Igual que arriba: en modo NONE no hay caché
            return await factory();
        }
    }
}