189 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C#
		
	
	
| using BankSampahApp.Models;
 | |
| 
 | |
| namespace BankSampahApp.Services;
 | |
| 
 | |
| /// <summary>
 | |
| /// Service implementation untuk menangani statistik aplikasi
 | |
| /// Menggunakan base service untuk common functionality
 | |
| /// </summary>
 | |
| public class StatisticsService : BaseService, IStatisticsService
 | |
| {
 | |
|     private readonly ICacheService _cacheService;
 | |
|     private readonly IAppConfigurationService _appConfig;
 | |
|     private readonly IValidationService _validationService;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Cache key untuk statistik
 | |
|     /// </summary>
 | |
|     private const string StatisticsCacheKey = "current_statistics";
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Constructor dengan dependency injection
 | |
|     /// </summary>
 | |
|     /// <param name="logger">Logger untuk logging</param>
 | |
|     /// <param name="cache">Memory cache untuk caching</param>
 | |
|     /// <param name="configuration">Configuration untuk settings</param>
 | |
|     /// <param name="cacheService">Cache service</param>
 | |
|     /// <param name="appConfig">Application configuration service</param>
 | |
|     /// <param name="validationService">Validation service</param>
 | |
|     public StatisticsService(
 | |
|         ILogger<StatisticsService> logger,
 | |
|         Microsoft.Extensions.Caching.Memory.IMemoryCache cache,
 | |
|         IConfiguration configuration,
 | |
|         ICacheService cacheService,
 | |
|         IAppConfigurationService appConfig,
 | |
|         IValidationService validationService) : base(logger, cache, configuration)
 | |
|     {
 | |
|         _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService));
 | |
|         _appConfig = appConfig ?? throw new ArgumentNullException(nameof(appConfig));
 | |
|         _validationService = validationService ?? throw new ArgumentNullException(nameof(validationService));
 | |
|     }
 | |
| 
 | |
|     /// <inheritdoc/>
 | |
|     public async Task<StatisticsModel> GetCurrentStatisticsAsync()
 | |
|     {
 | |
|         return await ExecuteWithErrorHandlingAsync(
 | |
|             async () => await _cacheService.GetOrSetWithSlidingAsync(
 | |
|                 StatisticsCacheKey,
 | |
|                 LoadStatisticsFromSourceAsync,
 | |
|                 _appConfig.CacheSettings.StatisticsSlidingExpiration,
 | |
|                 _appConfig.CacheSettings.StatisticsExpiration,
 | |
|                 Microsoft.Extensions.Caching.Memory.CacheItemPriority.High),
 | |
|             "Fetching current statistics",
 | |
|             GetDefaultStatistics());
 | |
|     }
 | |
| 
 | |
|     /// <inheritdoc/>
 | |
|     public async Task<StatisticsModel> GetStatisticsByPeriodAsync(DateTime startDate, DateTime endDate)
 | |
|     {
 | |
|         return await ExecuteWithErrorHandlingAsync(
 | |
|             async () =>
 | |
|             {
 | |
|                 var validation = _validationService.ValidateDateRange(startDate, endDate);
 | |
|                 if (!validation.IsValid)
 | |
|                 {
 | |
|                     throw new ArgumentException(string.Join("; ", validation.Errors));
 | |
|                 }
 | |
| 
 | |
|                 return await LoadStatisticsByPeriodFromSourceAsync(startDate, endDate);
 | |
|             },
 | |
|             $"Fetching statistics for period {startDate:yyyy-MM-dd} to {endDate:yyyy-MM-dd}");
 | |
|     }
 | |
| 
 | |
|     /// <inheritdoc/>
 | |
|     public async Task<bool> UpdateStatisticsAsync(StatisticsModel statistics)
 | |
|     {
 | |
|         return await ExecuteWithErrorHandlingAsync(
 | |
|             async () =>
 | |
|             {
 | |
|                 ArgumentNullException.ThrowIfNull(statistics);
 | |
| 
 | |
|                 var validation = _validationService.ValidateStatistics(statistics);
 | |
|                 if (!validation.IsValid)
 | |
|                 {
 | |
|                     _logger.LogWarning("Invalid statistics data: {Errors}", string.Join("; ", validation.Errors));
 | |
|                     return false;
 | |
|                 }
 | |
| 
 | |
|                 // Simulate async update operation
 | |
|                 if (_appConfig.DevelopmentSettings.SimulatedDelayMs > 0)
 | |
|                 {
 | |
|                     await Task.Delay(_appConfig.DevelopmentSettings.SimulatedDelayMs);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     await Task.Delay(10);
 | |
|                 }
 | |
| 
 | |
|                 // Clear cache after update
 | |
|                 _cacheService.Remove(StatisticsCacheKey);
 | |
| 
 | |
|                 return true;
 | |
|             },
 | |
|             "Updating statistics",
 | |
|             false);
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Load statistics from data source (placeholder for actual implementation)
 | |
|     /// </summary>
 | |
|     /// <returns>Current statistics</returns>
 | |
|     private async Task<StatisticsModel> LoadStatisticsFromSourceAsync()
 | |
|     {
 | |
|         // In a real application, this would load from database, API, etc.
 | |
|         await Task.CompletedTask;
 | |
| 
 | |
|         // Get base values from configuration
 | |
|         var baseUsers = _appConfig.StatisticsSettings.BaseUsers;
 | |
|         var baseWaste = _appConfig.StatisticsSettings.BaseWaste;
 | |
| 
 | |
|         // Simulate some growth over time
 | |
|         var daysSinceStart = (DateTime.UtcNow - new DateTime(2024, 1, 1)).Days;
 | |
|         var growthFactor = Math.Min(_appConfig.StatisticsSettings.MaxGrowthFactor,
 | |
|             1.0 + (daysSinceStart * _appConfig.StatisticsSettings.GrowthFactorMultiplier));
 | |
| 
 | |
|         return new StatisticsModel
 | |
|         {
 | |
|             TotalUsers = (int)(baseUsers * growthFactor),
 | |
|             WasteCollected = baseWaste * (decimal)growthFactor,
 | |
|             RewardsDistributed = (int)(_appConfig.StatisticsSettings.BaseRewards * growthFactor),
 | |
|             EnvironmentImpact = Math.Min(99.9m, _appConfig.StatisticsSettings.BaseEnvironmentImpact + (decimal)(growthFactor * 2))
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Load statistics for specific period (placeholder)
 | |
|     /// </summary>
 | |
|     /// <param name="startDate">Start date</param>
 | |
|     /// <param name="endDate">End date</param>
 | |
|     /// <returns>Period statistics</returns>
 | |
|     private async Task<StatisticsModel> LoadStatisticsByPeriodFromSourceAsync(DateTime startDate, DateTime endDate)
 | |
|     {
 | |
|         await Task.CompletedTask;
 | |
| 
 | |
|         // Calculate period-specific statistics
 | |
|         var days = (endDate - startDate).Days + 1;
 | |
|         var dailyAverage = await GetDailyAverageAsync();
 | |
| 
 | |
|         return new StatisticsModel
 | |
|         {
 | |
|             TotalUsers = dailyAverage.TotalUsers * days / 365,
 | |
|             WasteCollected = dailyAverage.WasteCollected * days,
 | |
|             RewardsDistributed = dailyAverage.RewardsDistributed * days,
 | |
|             EnvironmentImpact = dailyAverage.EnvironmentImpact
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Get daily average statistics
 | |
|     /// </summary>
 | |
|     /// <returns>Daily average statistics</returns>
 | |
|     private async Task<StatisticsModel> GetDailyAverageAsync()
 | |
|     {
 | |
|         await Task.CompletedTask;
 | |
| 
 | |
|         return new StatisticsModel
 | |
|         {
 | |
|             TotalUsers = 3, // New users per day
 | |
|             WasteCollected = 0.1m, // Tons per day
 | |
|             RewardsDistributed = 5, // Rewards per day
 | |
|             EnvironmentImpact = 98.5m // Overall impact
 | |
|         };
 | |
|     }
 | |
| 
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Get default statistics when error occurs
 | |
|     /// </summary>
 | |
|     /// <returns>Default statistics</returns>
 | |
|     private StatisticsModel GetDefaultStatistics()
 | |
|     {
 | |
|         return new StatisticsModel
 | |
|         {
 | |
|             TotalUsers = _appConfig.StatisticsSettings.BaseUsers,
 | |
|             WasteCollected = _appConfig.StatisticsSettings.BaseWaste,
 | |
|             RewardsDistributed = _appConfig.StatisticsSettings.BaseRewards,
 | |
|             EnvironmentImpact = _appConfig.StatisticsSettings.BaseEnvironmentImpact
 | |
|         };
 | |
|     }
 | |
| } |