using FrontOffice.BFF.Commission.Protobuf.Protos.Commission; namespace FrontOffice.Main.Utilities; /// /// Service for Commission operations /// Connected to FrontOffice.BFF gRPC CommissionCQ /// public class CommissionService { private readonly CommissionContract.CommissionContractClient _client; public CommissionService(CommissionContract.CommissionContractClient client) { _client = client; } /// /// Get commission payouts with pagination and filters /// Maps to: CommissionCQ.GetMyCommissionPayouts /// public async Task GetMyCommissionPayoutsAsync( int? weekNumber, string? status, int pageNumber, int pageSize) { try { var request = new GetMyCommissionPayoutsRequest { PageNumber = pageNumber, PageSize = pageSize }; if (weekNumber.HasValue) { request.WeekNumber = $"2025-W{weekNumber:D2}"; } // Map status string to int if (!string.IsNullOrEmpty(status)) { request.Status = status switch { "Pending" or "ایجاد شده" => 0, "Calculated" or "محاسبه شده" => 1, "Paid" or "پرداخت شده" => 2, "Withdrawn" or "برداشت شده" => 3, _ => null }; } var response = await _client.GetMyCommissionPayoutsAsync(request); return new CommissionPayoutsResponseDto { Payouts = response.Payouts.Select(p => new CommissionPayoutDto { Id = p.Id, WeekNumber = ExtractWeekNumber(p.WeekNumber), WeekLabel = p.WeekLabel, BalancesEarned = p.BalancesEarned, TotalAmount = p.TotalAmount, AmountFormatted = p.AmountFormatted, Status = p.Status, StatusBadgeColor = p.StatusBadgeColor, DatePersian = p.DatePersian }).ToList(), TotalCount = (int)(response.MetaData?.TotalCount ?? 0), PageNumber = pageNumber, PageSize = pageSize }; } catch { // Fallback to mock data if backend is unavailable return GenerateMockPayoutsResponse(weekNumber, status, pageNumber, pageSize); } } /// /// Get weekly balance details for a specific week /// Maps to: CommissionCQ.GetMyWeeklyBalances /// public async Task GetMyWeeklyBalanceAsync(int? weekNumber = null) { try { var request = new GetMyWeeklyBalancesRequest { PageNumber = 1, PageSize = 1, OnlyActive = false }; if (weekNumber.HasValue) { request.WeekNumber = $"2025-W{weekNumber:D2}"; } var response = await _client.GetMyWeeklyBalancesAsync(request); if (response.Balances.Count > 0) { var balance = response.Balances[0]; return new WeeklyBalanceDto { WeekNumber = ExtractWeekNumber(balance.WeekNumber), WeekLabel = $"هفته {ExtractWeekNumber(balance.WeekNumber)} - سال 1404", LeftBalance = balance.LeftLegBalances, RightBalance = balance.RightLegBalances, MinBalance = Math.Min(balance.LeftLegBalances, balance.RightLegBalances), BalanceCount = balance.TotalBalances, CalculatedCommission = balance.WeeklyPoolContribution, LeftCarryover = Math.Max(0, balance.LeftLegBalances - balance.RightLegBalances), RightCarryover = Math.Max(0, balance.RightLegBalances - balance.LeftLegBalances), StartDate = balance.CalculatedAt?.ToDateTime().AddDays(-7) ?? DateTime.Now.AddDays(-7), EndDate = balance.CalculatedAt?.ToDateTime() ?? DateTime.Now }; } return CreateMockWeeklyBalance(weekNumber ?? 45); } catch { return CreateMockWeeklyBalance(weekNumber ?? 45); } } #region Helper Methods private static int ExtractWeekNumber(string weekNumberStr) { // Format: "2025-W48" → 48 if (string.IsNullOrEmpty(weekNumberStr)) return 0; var parts = weekNumberStr.Split('W'); if (parts.Length > 1 && int.TryParse(parts[1], out var week)) { return week; } return 0; } private static WeeklyBalanceDto CreateMockWeeklyBalance(int weekNumber) { return new WeeklyBalanceDto { WeekNumber = weekNumber, WeekLabel = $"هفته {weekNumber} - سال 1404", LeftBalance = 15_000_000, RightBalance = 12_000_000, MinBalance = 12_000_000, BalanceCount = 12, CalculatedCommission = 1_200_000, LeftCarryover = 3_000_000, RightCarryover = 0, StartDate = DateTime.Now.AddDays(-7), EndDate = DateTime.Now }; } private static CommissionPayoutsResponseDto GenerateMockPayoutsResponse( int? weekNumber, string? status, int pageNumber, int pageSize) { var allPayouts = GenerateMockPayouts(50); var filtered = allPayouts.AsEnumerable(); if (weekNumber.HasValue) filtered = filtered.Where(p => p.WeekNumber == weekNumber.Value); if (!string.IsNullOrEmpty(status)) filtered = filtered.Where(p => p.Status == status); var total = filtered.Count(); var paged = filtered.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList(); return new CommissionPayoutsResponseDto { Payouts = paged, TotalCount = total, PageNumber = pageNumber, PageSize = pageSize }; } private static List GenerateMockPayouts(int count) { var payouts = new List(); var random = new Random(); var statusTexts = new[] { "ایجاد شده", "پرداخت شده", "درخواست برداشت", "برداشت شده", "لغو شده" }; var statusColors = new[] { "Info", "Success", "Warning", "Success", "Error" }; for (int i = 0; i < count; i++) { var statusIndex = random.Next(statusTexts.Length); var weekNum = 50 - i; var balances = random.Next(5, 20); var amount = balances * 100_000; payouts.Add(new CommissionPayoutDto { Id = i + 1, WeekNumber = weekNum, WeekLabel = $"هفته {weekNum} - سال 1404", BalancesEarned = balances, TotalAmount = amount, AmountFormatted = $"{amount:N0} تومان", Status = statusTexts[statusIndex], StatusBadgeColor = statusColors[statusIndex], DatePersian = DateTime.Now.AddDays(-i * 7).ToString("yyyy/MM/dd") }); } return payouts; } #endregion }