KoogleApp/KoogleApp/Data/SharedDataService.cs

197 lines
6.1 KiB
C#

using KoogleApp.Data.Repository;
using KoogleApp.Model;
using KoogleApp.Services;
using Microsoft.Extensions.Caching.Memory;
namespace KoogleApp.Data
{
public class SharedDataService
{
private readonly IPlayerRepository _playerRepository;
private readonly IPlayerExpenseRepository _playerExpenseRepository;
private readonly IDayRepository _dayRepository;
private readonly IMemoryCache _cache;
private readonly ILogger<SharedDataService> _logger;
private const string CacheKey = "AllDataItems";
private const string CacheKeyPrefix = "DataItem_";
private const string CacheKeyAll = "AllDataItems";
private static readonly TimeSpan CacheExpiration = TimeSpan.FromMinutes(5);
private SessionStorage _sessionStorage;
// Events für UI-Updates
public event Func<Task>? OnDataChanged;
public SharedDataService(
IPlayerRepository playerRepository,
IPlayerExpenseRepository playerExpenseRepository,
IDayRepository dayRepository,
IMemoryCache cache,
SessionStorage sessionStorage,
ILogger<SharedDataService> logger)
{
_playerRepository = playerRepository;
_playerExpenseRepository = playerExpenseRepository;
_dayRepository = dayRepository;
_cache = cache;
_logger = logger;
_sessionStorage = sessionStorage;
}
public async Task<List<Player>> GetAllPlayersAsync(bool forceRefresh = false, bool includePositions = false)
{
var cacheKey = includePositions ? $"{CacheKeyAll}_WithPositions" : CacheKeyAll;
if (forceRefresh)
{
_cache.Remove(CacheKey);
}
if (_cache.TryGetValue(CacheKey, out List<Player>? cachedData))
{
_logger.LogDebug("Returning cached data");
return cachedData!;
}
_logger.LogDebug("Loading data from repository");
var data = await _playerRepository.GetAllAsync();
_cache.Set(CacheKey, data, new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = CacheExpiration,
Priority = CacheItemPriority.Normal
});
return data;
}
public async Task<Player?> GetByIdAsync(int id, bool includePositions = true)
{
var cacheKey = $"{CacheKeyPrefix}{id}";
if (_cache.TryGetValue(cacheKey, out Player? cachedItem))
{
return cachedItem;
}
var item = await _playerRepository.GetByIdAsync(id, includePositions);
if (item != null)
{
_cache.Set(cacheKey, item, CacheExpiration);
}
return item;
}
public async Task<Player> CreatePlayerAsync(Player item, string userName)
{
item.ModifiedBy = userName;
var created = await _playerRepository.CreateAsync(item);
await InvalidateCacheAndNotifyAsync();
_logger.LogInformation("Created item {Id} by {User}", created.Id, userName);
return created;
}
public async Task<Player> UpdatePlayerAsync(Player item, string userName)
{
item.ModifiedBy = userName;
var updated = await _playerRepository.UpdateAsync(item);
await InvalidateCacheAndNotifyAsync();
_cache.Remove($"{CacheKeyPrefix}{item.Id}");
_logger.LogInformation(
"Updated item {Id} with {PositionCount} positions by {User}",
updated.Id, updated.Expenses.Count, userName);
return updated;
}
public async Task<bool> DeleteAsync(int id, string userName)
{
var result = await _playerRepository.DeleteAsync(id);
if (result)
{
await InvalidateCacheAndNotifyAsync();
_cache.Remove($"{CacheKeyPrefix}{id}");
_logger.LogInformation("Deleted item {Id} by {User}", id, userName);
}
return result;
}
// Hilfsmethode: Gesamtsumme aller Positionen berechnen
//public async Task<decimal> GetTotalAmountAsync(int dataItemId)
//{
// var item = await GetByIdAsync(dataItemId);
// return item?.Positions.Sum(p => p.TotalPrice) ?? 0;
//}
private async Task InvalidateCacheAndNotifyAsync()
{
_cache.Remove(CacheKeyAll);
_cache.Remove($"{CacheKeyAll}_WithPositions");
// Benachrichtige alle Subscriber
if (OnDataChanged != null)
{
await OnDataChanged.Invoke();
}
}
public void ClearCache()
{
_cache.Remove(CacheKey);
_logger.LogDebug("Cache cleared");
}
public async Task SetSelectedPlayerAsync(Player? player)
{
_sessionStorage.SetSelectedPlayerAsync(player);
}
public async Task<Player?> GetSelectedPlayerAsync()
{
return await _sessionStorage.GetSelectedPlayerAsync();
}
public async Task<Player> GetPlayerWithExpensesAsync()
{
var player = await GetSelectedPlayerAsync();
if (player != null)
{
return await _playerRepository.GetByIdAsync(player.Id, true);
}
return null;
}
public async Task<List<Day>> GetAllDaysAsync(int year)
{
var days = await _dayRepository.GetAllAsync(year);
return days;
}
public async Task<Day?> GetActiveDayAsync()
{
var day = await _dayRepository.GetActiveDayAsync();
return day;
}
public async Task<Day> AddDayAsync(Day day)
{
var newDay = await _dayRepository.AddAsync(day);
return newDay;
}
public async Task<Day> UpdateDayAsync(Day day)
{
var modifiedDay = await _dayRepository.UpdateAsync(day);
return modifiedDay;
}
}
}