package report import ( "context" "fmt" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "go.uber.org/zap" ) type BetIntervalRow struct { Period string `csv:"Period"` TotalBets int64 `csv:"Total Bets"` TotalStake int64 `csv:"Total Stake"` ActiveBets int64 `csv:"Active Bets"` TotalWins int64 `csv:"Total Wins"` TotalLosses int64 `csv:"Total Losses"` WinBalance int64 `csv:"Win Balance"` NumberOfUnsettled int64 `csv:"Number Of Unsettled"` TotalUnsettledAmount int64 `csv:"Total Unsettled Amount"` TotalShopBets int64 `csv:"Total Shop Bets"` } func (s *Service) GenerateBetIntervalReport(ctx context.Context, request domain.ReportRequestDetail) (string, error) { if request.Metadata.Interval == nil { s.mongoLogger.Error("[GenerateBetIntervalReport] Metadata interval is empty") return "", domain.ErrInvalidInterval } interval, err := domain.ParseDateInterval(*request.Metadata.Interval) if err != nil { s.mongoLogger.Error("[GenerateBetIntervalReport] Failed to parse date interval", zap.String("interval", *request.Metadata.Interval), zap.Error(err), ) return "", domain.ErrInvalidInterval } stats, err := s.statService.GetBetStatsByInterval(ctx, domain.BetStatsByIntervalFilter{ Interval: domain.ValidDateInterval{ Value: interval, Valid: true, }, CompanyID: request.CompanyID, }) if err != nil { s.mongoLogger.Error("[GenerateBetIntervalReport] Failed to fetch bet stats", zap.String("interval", string(interval)), zap.Error(err), ) return "", fmt.Errorf("fetching bet stats: %w", err) } var rows [][]string var headers []string for _, stat := range stats { endDate, err := domain.GetEndDateFromInterval(interval, stat.Date) if err != nil { s.mongoLogger.Error("[GenerateBetIntervalReport] Failed to get end date from interval", zap.String("interval", string(interval)), zap.Error(err), ) return "", fmt.Errorf("invalid interval end date: %w", err) } period := fmt.Sprintf("%s to %s", stat.Date.Format("2006-01-02"), endDate.Format("2006-01-02"), ) r := BetIntervalRow{ Period: period, TotalBets: stat.TotalBets, TotalStake: stat.TotalStake, ActiveBets: stat.ActiveBets, TotalWins: stat.TotalWins, TotalLosses: stat.TotalLosses, WinBalance: stat.WinBalance, NumberOfUnsettled: stat.NumberOfUnsettled, TotalUnsettledAmount: stat.TotalUnsettledAmount, TotalShopBets: stat.TotalShopBets, } if headers == nil { headers, _ = StructToCSVRow(r) rows = append(rows, headers) } _, row := StructToCSVRow(r) rows = append(rows, row) } return s.WriteCSV(rows, "bet_interval") }