package report import ( "context" "fmt" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "go.uber.org/zap" ) type EventIntervalRow struct { Period string `csv:"Period"` TotalEvents int64 `csv:"Total Events"` ActiveEvents int64 `csv:"Active Events"` InActiveEvents int64 `csv:"In-Active Events"` FeaturedEvents int64 `csv:"Featured Events"` Leagues int64 `csv:"Leagues"` Pending int64 `csv:"Pending"` InPlay int64 `csv:"In-Play"` ToBeFixed int64 `csv:"To-Be-Fixed"` Ended int64 `csv:"Ended"` Postponed int64 `csv:"Postponed"` Cancelled int64 `csv:"Cancelled"` Walkover int64 `csv:"Walkover"` Interrupted int64 `csv:"Interrupted"` Abandoned int64 `csv:"Abandoned"` Retired int64 `csv:"Retired"` Suspended int64 `csv:"Suspended"` DecidedByFA int64 `csv:"Decided-By-FA"` Removed int64 `csv:"Removed"` } func (s *Service) GenerateEventIntervalReport(ctx context.Context, request domain.ReportRequestDetail) (string, error) { // Only a super-admin is allowed to generate this type of report if request.RequesterRole.Valid && request.RequesterRole.Value != domain.RoleSuperAdmin { s.mongoLogger.Error("[GenerateEventIntervalReport] Unauthorized user report") return "", ErrUnauthorizedUserReport } if request.Metadata.Interval == nil { s.mongoLogger.Error("[GenerateEventIntervalReport] Metadata interval is empty") return "", domain.ErrInvalidInterval } interval, err := domain.ParseDateInterval(*request.Metadata.Interval) if err != nil { s.mongoLogger.Error("[GenerateEventIntervalReport] Failed to parse date interval", zap.String("interval", *request.Metadata.Interval), zap.Error(err), ) return "", domain.ErrInvalidInterval } stats, err := s.statService.GetTotalEventStatsByInterval(ctx, domain.EventStatsByIntervalFilter{ Interval: domain.ValidDateInterval{ Value: interval, Valid: true, }, }) if err != nil { s.mongoLogger.Error("[GenerateEventIntervalReport] Failed to fetch event stats", zap.String("interval", string(interval)), zap.Error(err), ) return "", fmt.Errorf("fetching event 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("[GenerateEventIntervalReport] 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 := EventIntervalRow{ Period: period, TotalEvents: stat.EventCount, ActiveEvents: stat.TotalActiveEvents, InActiveEvents: stat.TotalInActiveEvents, FeaturedEvents: stat.TotalFeaturedEvents, Leagues: stat.TotalLeagues, Pending: stat.Pending, InPlay: stat.InPlay, ToBeFixed: stat.ToBeFixed, Ended: stat.Ended, Postponed: stat.Postponed, Cancelled: stat.Cancelled, Walkover: stat.Walkover, Interrupted: stat.Interrupted, Abandoned: stat.Abandoned, Retired: stat.Retired, Suspended: stat.Suspended, DecidedByFA: stat.DecidedByFa, Removed: stat.Removed, } if headers == nil { headers, _ = StructToCSVRow(r) rows = append(rows, headers) } _, row := StructToCSVRow(r) rows = append(rows, row) } return s.WriteCSV(rows, "event_interval") }