// ***********************************************************************
// 
//     AgileWebs
// 
// ***********************************************************************
using Core.Blueprint.Mongo;
using Core.Blueprint.Redis;
using Core.Blueprint.Redis.Helpers;
using Core.Thalos.BuildingBlocks;
using Core.Thalos.Domain.Contexts.Onboarding.Request;
using Core.Thalos.Provider.Contracts;
using Mapster;
namespace Core.Thalos.Provider.Providers.Onboarding
{
    /// 
    /// Handles all services and business rules related to .
    /// 
    public class TenantProvider : ITenantProvider
    {
        private readonly CollectionRepository repository;
        private readonly ICacheSettings cacheSettings;
        private readonly IRedisCacheProvider cacheProvider;
        public TenantProvider(
            CollectionRepository repository,
            IRedisCacheProvider cacheProvider,
            ICacheSettings cacheSettings)
        {
            this.repository = repository;
            this.repository.CollectionInitialization();
            this.cacheSettings = cacheSettings;
            this.cacheProvider = cacheProvider;
        }
        /// 
        /// Creates a new Tenant.
        /// 
        /// The Tenant to be created.
        /// A token to cancel the asynchronous operation.
        /// 
        /// A  representing the asynchronous execution of the service.
        /// 
        public async ValueTask CreateTenant(TenantRequest newTenant, CancellationToken cancellationToken)
        {
            var tenant = newTenant.Adapt();
            await repository.InsertOneAsync(tenant);
            return tenant;
        }
        /// 
        /// Gets a Tenant by identifier.
        /// 
        /// The Tenant Mongo identifier.
        /// A token to cancel the asynchronous operation.
        /// 
        /// A  representing the asynchronous execution of the service.
        /// 
        public async ValueTask GetTenantById(string _id, CancellationToken cancellationToken)
        {
            var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetTenantById", _id);
            var cachedData = await cacheProvider.GetAsync(cacheKey);
            if (cachedData is not null) return cachedData;
            var tenant = await repository.FindByIdAsync(_id);
            await cacheProvider.SetAsync(cacheKey, tenant, TimeSpan.FromMinutes(cacheSettings.DefaultCacheDurationInMinutes));
            return tenant;
        }
        /// 
        /// Gets all Tenants.
        /// 
        /// A token to cancel the asynchronous operation.
        /// 
        /// A  representing the asynchronous execution of the service.
        /// 
        public async ValueTask> GetAllTenants(CancellationToken cancellationToken)
        {
            var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetTenants");
            var cachedData = await cacheProvider.GetAsync>(cacheKey) ?? [];
            //if (cachedData.Any()) return cachedData;
            var tenants = await repository.AsQueryable();
            await cacheProvider.SetAsync(cacheKey, tenants, TimeSpan.FromMinutes(cacheSettings.DefaultCacheDurationInMinutes));
            return tenants;
        }
        /// 
        /// Changes the status of a Tenant.
        /// 
        /// The Tenant Mongo identifier.
        /// The new status of the Tenant.
        /// A token to cancel the asynchronous operation.
        /// 
        /// A  representing the asynchronous execution of the service.
        /// 
        public async ValueTask ChangeTenantStatus(string _id, Blueprint.Mongo.StatusEnum newStatus, CancellationToken cancellationToken)
        {
            var entity = await repository.FindByIdAsync(_id);
            entity.Status = newStatus;
            await repository.ReplaceOneAsync(entity);
            return entity;
        }
        /// 
        /// Updates a Tenant.
        /// 
        /// The Tenant to be updated.
        /// A token to cancel the asynchronous operation.
        /// 
        /// A  representing the asynchronous execution of the service.
        /// 
        public async ValueTask UpdateTenant(TenantAdapter entity, CancellationToken cancellationToken)
        {
            await repository.ReplaceOneAsync(entity);
            return entity;
        }
        /// 
        /// Deletes a Tenant by identifier.
        /// 
        /// The Tenant Mongo identifier.
        /// A token to cancel the asynchronous operation.
        /// 
        /// A  representing the asynchronous deletion result.
        /// The deleted Tenant entity if found; otherwise, null.
        /// 
        public async ValueTask DeleteTenant(string _id, CancellationToken cancellationToken)
        {
            var entity = await repository.DeleteOneAsync(doc => doc._Id == _id);
            return entity;
        }
    }
}