using Fitness_core_BE.Helpers; using Fitness_core_BE.Interfaces; using Fitness_core_BE.Interfaces.Services; namespace Fitness_core_BE.Services { public class ClientStatService : IClientStatService { // Muscle Beast Gym (gymos_musslbeast) -- the only gym that gets the "Today's Payments" // stat, per their explicit request. Not a general feature-flag system; if another gym // wants this later, promote it to a real per-client setting instead of adding more IDs here. private static readonly Guid MuscleBeastClientId = Guid.Parse("b2abf7b3-a9f0-11f1-945a-54e8d4bf1eca"); private readonly IClientStatRepository _clientStatRepository; private readonly IOverdueLockRepository _overdueLockRepository; private readonly UserRoleHelper _userRoleHelper; public ClientStatService( IClientStatRepository clientStatRepository, IOverdueLockRepository overdueLockRepository, UserRoleHelper userRoleHelper) { _clientStatRepository = clientStatRepository; _overdueLockRepository = overdueLockRepository; _userRoleHelper = userRoleHelper; } public async Task GetTotalCustomerCount(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var count = await _clientStatRepository.GetTotalCustomerCountAsync(clientId); return new { totalCustomerCount = count }; } public async Task GetMonthlyCustomerCount(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var count = await _clientStatRepository.GetMonthlyCustomerCountAsync(clientId); return new { monthlyCustomerCount = count }; } public async Task GetTotalWorkoutPlanCount(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var count = await _clientStatRepository.GetTotalWorkoutPlanCountAsync(clientId); return new { totalWorkoutPlanCount = count }; } public async Task GetTotalMealPlanCount(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var count = await _clientStatRepository.GetTotalMealPlanCountAsync(clientId); return new { totalMealPlanCount = count }; } public async Task GetLastMonthCustomerCount(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var count = await _clientStatRepository.GetLastMonthCustomerCountAsync(clientId); return new { lastMonthCustomerCount = count }; } public async Task GetLastFiveAttendances(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var records = await _clientStatRepository.GetLastFiveAttendancesAsync(clientId); return records; } public async Task GetLastFivePayments(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var records = await _clientStatRepository.GetLastFivePaymentsAsync(clientId); return records; } public async Task GetLastMonthRevenue(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var revenue = await _clientStatRepository.GetLastMonthRevenueAsync(clientId); return new { lastMonthRevenue = revenue }; } public async Task GetMonthlyRevenueVariation(object payload, HttpContext httpContext, DateTime? from = null, DateTime? to = null) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var stats = await _clientStatRepository.GetMonthlyRevenueVariationAsync(clientId, from, to); var isOwner = (await _userRoleHelper.GetOwnedClientId(userId)).HasValue; if (!isOwner) { // Revenue is owner-only, enforced here (not just hidden client-side) — staff // still get real NewMemberCount points, just no Revenue figures. foreach (var point in stats) point.Revenue = 0m; } return stats; } public async Task GetTotalRevenue(object payload, HttpContext httpContext) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var revenue = await _clientStatRepository.GetTotalRevenueAsync(clientId); return new { totalRevenue = revenue }; } public async Task GetClientStatSummary(object payload, HttpContext httpContext, DateTime? from = null, DateTime? to = null) { Guid userId = DataExtractor.GetUserIdFromContext(httpContext); Guid clientId = await _userRoleHelper.GetClientId(userId); var summary = await _clientStatRepository.GetClientStatSummaryAsync(clientId, from, to); summary.OverdueCount = (await _overdueLockRepository.GetOverdueCustomerIdsAsync(clientId, DateTime.UtcNow)).Count; summary.ShowTodayPayments = clientId == MuscleBeastClientId; var isOwner = (await _userRoleHelper.GetOwnedClientId(userId)).HasValue; if (!isOwner) { // Revenue is owner-only, enforced here (not just hidden client-side) — a staff // member calling this endpoint directly still gets zeros, not real figures. summary.ThisMonthRevenue = 0m; summary.LastMonthRevenue = 0m; summary.RevenueGrowthPercentage = 0m; summary.TotalRevenue = 0m; } return summary; } } }