package handlers import ( "fmt" "strconv" "time" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/gofiber/fiber/v2" ) // @Summary Retrieve all upcoming events // @Description Retrieve all upcoming events from the database // @Tags prematch // @Accept json // @Produce json // @Param page query int false "Page number" // @Param page_size query int false "Page size" // @Param league_id query string false "League ID Filter" // @Param sport_id query string false "Sport ID Filter" // @Param cc query string false "Country Code Filter" // @Param first_start_time query string false "Start Time" // @Param last_start_time query string false "End Time" // @Success 200 {array} domain.UpcomingEvent // @Failure 500 {object} response.APIResponse // @Router /events [get] func (h *Handler) GetAllUpcomingEvents(c *fiber.Ctx) error { page := c.QueryInt("page", 1) pageSize := c.QueryInt("page_size", 10) limit := domain.ValidInt64{ Value: int64(pageSize), Valid: true, } offset := domain.ValidInt64{ Value: int64(page - 1), Valid: true, } leagueIDQuery := c.Query("league_id") var leagueID domain.ValidInt32 if leagueIDQuery != "" { leagueIDInt, err := strconv.Atoi(leagueIDQuery) if err != nil { h.logger.Error("invalid league id", "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "invalid league id", nil, nil) } leagueID = domain.ValidInt32{ Value: int32(leagueIDInt), Valid: true, } } sportIDQuery := c.Query("sport_id") var sportID domain.ValidInt32 if sportIDQuery != "" { sportIDint, err := strconv.Atoi(sportIDQuery) if err != nil { h.logger.Error("invalid sport id", "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "invalid sport id", nil, nil) } sportID = domain.ValidInt32{ Value: int32(sportIDint), Valid: true, } } firstStartTimeQuery := c.Query("first_start_time") var firstStartTime domain.ValidTime if firstStartTimeQuery != "" { firstStartTimeParsed, err := time.Parse(time.RFC3339, firstStartTimeQuery) if err != nil { h.logger.Error("invalid start_time format", "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil) } firstStartTime = domain.ValidTime{ Value: firstStartTimeParsed, Valid: true, } } lastStartTimeQuery := c.Query("last_start_time") var lastStartTime domain.ValidTime if lastStartTimeQuery != "" { lastStartTimeParsed, err := time.Parse(time.RFC3339, lastStartTimeQuery) if err != nil { h.logger.Error("invalid start_time format", "error", err) return response.WriteJSON(c, fiber.StatusBadRequest, "Invalid start_time format", nil, nil) } lastStartTime = domain.ValidTime{ Value: lastStartTimeParsed, Valid: true, } } countryCodeQuery := c.Query("cc") countryCode := domain.ValidString{ Value: countryCodeQuery, Valid: countryCodeQuery != "", } flaggedQuery := c.Query("flagged") if flaggedQuery != "" && events, total, err := h.eventSvc.GetPaginatedUpcomingEvents( c.Context(), domain.EventFilter{ SportID: sportID, LeagueID: leagueID, FirstStartTime: firstStartTime, LastStartTime: lastStartTime, Limit: limit, Offset: offset, CountryCode: countryCode, }) // fmt.Printf("League ID: %v", leagueID) if err != nil { h.logger.Error("getting error", "error", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve all upcoming events", nil, nil) } return response.WritePaginatedJSON(c, fiber.StatusOK, "All upcoming events retrieved successfully", events, nil, page, int(total)) } type TopLeaguesRes struct { Leagues []TopLeague `json:"leagues"` } type TopLeague struct { LeagueID int64 `json:"league_id"` LeagueName string `json:"league_name"` LeagueCC string `json:"league_cc"` LeagueSportID int32 `json:"league_sport_id"` Events []domain.UpcomingEvent `json:"events"` // Total int64 `json:"total"` } // @Summary Retrieve all top leagues // @Description Retrieve all top leagues // @Tags prematch // @Accept json // @Produce json // @Success 200 {array} TopLeague // @Failure 500 {object} response.APIResponse // @Router /top-leagues [get] func (h *Handler) GetTopLeagues(c *fiber.Ctx) error { leagues, err := h.leagueSvc.GetFeaturedLeagues(c.Context()) if err != nil { h.logger.Error("Error while fetching top leagues", "err", err) return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to get featured leagues", nil, nil) } var topLeague []TopLeague = make([]TopLeague, 0, len(leagues)) for _, league := range leagues { events, _, err := h.eventSvc.GetPaginatedUpcomingEvents( c.Context(), domain.EventFilter{ LeagueID: domain.ValidInt32{ Value: int32(league.ID), Valid: true, }, }) if err != nil { fmt.Printf("Error while fetching events for top league %v \n", league.ID) h.logger.Error("Error while fetching events for top league", "League ID", league.ID) } topLeague = append(topLeague, TopLeague{ LeagueID: league.ID, LeagueName: league.Name, LeagueCC: league.CountryCode, LeagueSportID: league.SportID, Events: events, }) } res := TopLeaguesRes{ Leagues: topLeague, } return response.WriteJSON(c, fiber.StatusOK, "All top leagues events retrieved successfully", res, nil) } // @Summary Retrieve an upcoming by ID // @Description Retrieve an upcoming event by ID // @Tags prematch // @Accept json // @Produce json // @Param id path string true "ID" // @Success 200 {object} domain.UpcomingEvent // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /events/{id} [get] func (h *Handler) GetUpcomingEventByID(c *fiber.Ctx) error { id := c.Params("id") if id == "" { return response.WriteJSON(c, fiber.StatusBadRequest, "Missing id", nil, nil) } event, err := h.eventSvc.GetUpcomingEventByID(c.Context(), id) if err != nil { return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve upcoming event", nil, nil) } return response.WriteJSON(c, fiber.StatusOK, "Upcoming event retrieved successfully", event, nil) } type UpdateEventStatusReq struct { } // SetEventStatusToRemoved godoc // @Summary Set the event status to removed // @Description Set the event status to removed // @Tags event // @Accept json // @Produce json // @Param id path int true "Event ID" // @Success 200 {object} response.APIResponse // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /events/{id} [delete] func (h *Handler) SetEventStatusToRemoved(c *fiber.Ctx) error { eventID := c.Params("id") err := h.eventSvc.UpdateEventStatus(c.Context(), eventID, domain.STATUS_REMOVED) if err != nil { h.logger.Error("Failed to update event status", "eventID", eventID, "error", err) } return response.WriteJSON(c, fiber.StatusOK, "Event updated successfully", nil, nil) } type UpdateEventFlaggedReq struct { Flagged bool `json:"flagged" example:"true"` } // UpdateEventFlagged godoc // @Summary update the event flagged // @Description Update the event flagged // @Tags event // @Accept json // @Produce json // @Param id path int true "Event ID" // @Success 200 {object} response.APIResponse // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /events/{id}/flag [put] func (h *Handler) UpdateEventFlagged(c *fiber.Ctx) error { eventID := c.Params("id") var req UpdateEventFlaggedReq if err := c.BodyParser(&req); err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } valErrs, ok := h.validator.Validate(c, req) if !ok { var errMsg string for field, msg := range valErrs { errMsg += fmt.Sprintf("%s: %s; ", field, msg) } return fiber.NewError(fiber.StatusBadRequest, errMsg) } err := h.eventSvc.UpdateFlagged(c.Context(), eventID, req.Flagged) if err != nil { h.logger.Error("Failed to update event flagged", "eventID", eventID, "error", err) } return response.WriteJSON(c, fiber.StatusOK, "Event updated successfully", nil, nil) }