package handlers import ( "fmt" "strconv" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/response" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) // GetAllLeagues godoc // @Summary Gets all leagues // @Description Gets all leagues // @Tags leagues // @Accept json // @Produce json // @Success 200 {array} domain.BaseLeague // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /api/v1/leagues [get] func (h *Handler) GetAllLeagues(c *fiber.Ctx) error { page := c.QueryInt("page", 1) pageSize := c.QueryInt("page_size", 10) limit := domain.ValidInt64{ Value: int64(pageSize), Valid: pageSize != 0, } offset := domain.ValidInt64{ Value: int64(page - 1), Valid: true, } searchQuery := c.Query("query") searchString := domain.ValidString{ Value: searchQuery, Valid: searchQuery != "", } countryCodeQuery := c.Query("cc") countryCode := domain.ValidString{ Value: countryCodeQuery, Valid: countryCodeQuery != "", } isActiveQuery := c.QueryBool("is_active", false) isActiveFilter := c.QueryBool("is_active_filter", false) isActive := domain.ValidBool{ Value: isActiveQuery, Valid: isActiveFilter, } sportIDQuery := c.Query("sport_id") var sportID domain.ValidInt32 if sportIDQuery != "" { sportIDint, err := strconv.ParseInt(sportIDQuery, 10, 64) if err != nil { h.BadRequestLogger().Info("invalid sport id", zap.String("sport_id", sportIDQuery), zap.Error(err), ) return fiber.NewError(fiber.StatusBadRequest, "invalid sport id") } sportID = domain.ValidInt32{ Value: int32(sportIDint), Valid: true, } } queryLogFields := []zap.Field{ zap.Int("page", page), zap.Int("page_size", pageSize), zap.Int64("limit_value", limit.Value), zap.Bool("limit_valid", limit.Valid), zap.Int64("offset_value", offset.Value), zap.Bool("offset_valid", offset.Valid), zap.Bool("is_active_value", isActive.Value), zap.Bool("is_active_valid", isActive.Valid), zap.String("cc_query", countryCodeQuery), zap.String("cc", countryCode.Value), zap.String("query", searchQuery), zap.Bool("cc_valid", countryCode.Valid), zap.String("sport_id_query", sportIDQuery), zap.Int32("sport_id", sportID.Value), zap.Bool("sport_id_valid", sportID.Valid), } leagues, total, err := h.leagueSvc.GetAllLeagues(c.Context(), domain.LeagueFilter{ CountryCode: countryCode, IsActive: isActive, SportID: sportID, Limit: limit, Offset: offset, Query: searchString, }) if err != nil { fmt.Printf("Error fetching league %v \n", err) h.InternalServerErrorLogger().Error("Failed to get all leagues", append(queryLogFields, zap.Error(err))..., ) return fiber.NewError(fiber.StatusInternalServerError, "Failed to get leagues:"+err.Error()) } res := domain.ConvertBaseLeagueResList(leagues) return response.WritePaginatedJSON(c, fiber.StatusOK, "All leagues retrieved successfully", res, nil, page, int(total)) } // GetAllLeaguesForTenant godoc // @Summary Gets all leagues // @Description Gets all leagues // @Tags leagues // @Accept json // @Produce json // @Success 200 {array} domain.BaseLeague // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /api/v1/{tenant_slug}/leagues [get] func (h *Handler) GetAllLeaguesForTenant(c *fiber.Ctx) error { companyID := c.Locals("company_id").(domain.ValidInt64) if !companyID.Valid { h.BadRequestLogger().Error("invalid company id") return fiber.NewError(fiber.StatusBadRequest, "invalid company id") } page := c.QueryInt("page", 1) pageSize := c.QueryInt("page_size", 10) limit := domain.ValidInt64{ Value: int64(pageSize), Valid: pageSize == 0, } offset := domain.ValidInt64{ Value: int64(page - 1), Valid: true, } searchQuery := c.Query("query") searchString := domain.ValidString{ Value: searchQuery, Valid: searchQuery != "", } countryCodeQuery := c.Query("cc") countryCode := domain.ValidString{ Value: countryCodeQuery, Valid: countryCodeQuery != "", } isActiveQuery := c.QueryBool("is_active", false) isActiveFilter := c.QueryBool("is_active_filter", false) isActive := domain.ValidBool{ Value: isActiveQuery, Valid: isActiveFilter, } sportIDQuery := c.Query("sport_id") var sportID domain.ValidInt32 if sportIDQuery != "" { sportIDint, err := strconv.ParseInt(sportIDQuery, 10, 64) if err != nil { h.BadRequestLogger().Info("invalid sport id", zap.String("sport_id", sportIDQuery), zap.Error(err), ) return fiber.NewError(fiber.StatusBadRequest, "invalid sport id") } sportID = domain.ValidInt32{ Value: int32(sportIDint), Valid: true, } } queryLogFields := []zap.Field{ zap.Int64("company_id", companyID.Value), zap.Bool("company_valid", companyID.Valid), zap.Int("page", page), zap.Int("page_size", pageSize), zap.Int64("limit_value", limit.Value), zap.Bool("limit_valid", limit.Valid), zap.Int64("offset_value", offset.Value), zap.Bool("offset_valid", offset.Valid), zap.Bool("is_active_value", isActive.Value), zap.Bool("is_active_valid", isActive.Valid), zap.String("cc_query", countryCodeQuery), zap.String("cc", countryCode.Value), zap.Bool("cc_valid", countryCode.Valid), zap.String("sport_id_query", sportIDQuery), zap.Int32("sport_id", sportID.Value), zap.Bool("sport_id_valid", sportID.Valid), } leagues, total, err := h.leagueSvc.GetAllLeaguesByCompany(c.Context(), companyID.Value, domain.LeagueFilter{ CountryCode: countryCode, IsActive: isActive, SportID: sportID, Limit: limit, Offset: offset, Query: searchString, }) if err != nil { fmt.Printf("Error fetching league %v \n", err) h.InternalServerErrorLogger().Error("Failed to get all leagues", append(queryLogFields, zap.Error(err))...) return fiber.NewError(fiber.StatusInternalServerError, "Failed to get leagues:"+err.Error()) } res := domain.ConvertLeagueWithSettingResList(leagues) return response.WritePaginatedJSON(c, fiber.StatusOK, "All leagues retrieved", res, nil, page, int(total)) } type SetLeagueActiveReq struct { IsActive bool `json:"is_active"` } // SetLeagueActive godoc // @Summary Set the league to active // @Description Set the league to active // @Tags leagues // @Accept json // @Produce json // @Param id path int true "League ID" // @Param active body SetLeagueActiveReq true "League Active Request" // @Success 200 {object} response.APIResponse // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /api/v1/{tenant_slug}/leagues/{id}/set-active [put] func (h *Handler) SetLeagueActive(c *fiber.Ctx) error { companyID := c.Locals("company_id").(domain.ValidInt64) if !companyID.Valid { h.mongoLoggerSvc.Error("invalid company id") return fiber.NewError(fiber.StatusBadRequest, "invalid company id") } leagueIdStr := c.Params("id") if leagueIdStr == "" { return fiber.NewError(fiber.StatusBadRequest, "Missing league id") } leagueId, err := strconv.ParseInt(leagueIdStr, 10, 64) if err != nil { return fiber.NewError(fiber.StatusBadRequest, "invalid league id") } queryLogFields := []zap.Field{ zap.Int64("company_id", companyID.Value), zap.Bool("company_valid", companyID.Valid), zap.String("league_id", leagueIdStr), } var req SetLeagueActiveReq if err := c.BodyParser(&req); err != nil { h.InternalServerErrorLogger().Error("SetLeagueReq failed to parse request body", append(queryLogFields, zap.Error(err))..., ) return fiber.NewError(fiber.StatusBadRequest, "Failed to parse request:"+err.Error()) } queryLogFields = append(queryLogFields, zap.Any("is_active", req.IsActive)) valErrs, ok := h.validator.Validate(c, req) if !ok { var errMsg string for field, msg := range valErrs { errMsg += fmt.Sprintf("%s: %s; ", field, msg) } h.BadRequestLogger().Info("Failed to validate SetLeagueActiveReq", append(queryLogFields, zap.Error(err))...) return fiber.NewError(fiber.StatusBadRequest, errMsg) } if err := h.leagueSvc.SaveLeagueSettings(c.Context(), domain.CreateLeagueSettings{ LeagueID: leagueId, CompanyID: companyID.Value, IsActive: domain.ValidBool{ Value: req.IsActive, Valid: true, }, }); err != nil { h.InternalServerErrorLogger().Error("Failed to update league active", append(queryLogFields, zap.Error(err))...) return fiber.NewError(fiber.StatusInternalServerError, "Failed to update league:"+err.Error()) } h.SuccessResLogger().Info("League Active has been successfully updated", queryLogFields...) return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil) } type SetLeagueAsFeatured struct { IsFeatured bool `json:"is_featured" example:"true"` } // SetLeagueFeatured godoc // @Summary Set the league to featured/un-featured // @Description Set the league to featured/un-featured // @Tags leagues // @Accept json // @Produce json // @Param id path int true "League ID" // @Param active body SetLeagueAsFeatured true "League Featured Request" // @Success 200 {object} response.APIResponse // @Failure 400 {object} response.APIResponse // @Failure 500 {object} response.APIResponse // @Router /api/v1/{tenant_slug}/leagues/{id}/featured [put] func (h *Handler) SetLeagueFeatured(c *fiber.Ctx) error { companyID := c.Locals("company_id").(domain.ValidInt64) if !companyID.Valid { h.mongoLoggerSvc.Error("invalid company id") return fiber.NewError(fiber.StatusBadRequest, "invalid company id") } leagueIdStr := c.Params("id") if leagueIdStr == "" { return fiber.NewError(fiber.StatusBadRequest, "Missing league id") } leagueId, err := strconv.ParseInt(leagueIdStr, 10, 64) if err != nil { return fiber.NewError(fiber.StatusBadRequest, "invalid league id") } queryLogFields := []zap.Field{ zap.Int64("company_id", companyID.Value), zap.Bool("company_valid", companyID.Valid), zap.String("league_id", leagueIdStr), } var req SetLeagueAsFeatured if err := c.BodyParser(&req); err != nil { h.BadRequestLogger().Info("SetLeagueFeaturedReq failed to parse request body", append(queryLogFields, zap.Error(err))...) return fiber.NewError(fiber.StatusBadRequest, "Failed to parse request body:"+err.Error()) } valErrs, ok := h.validator.Validate(c, req) queryLogFields = append(queryLogFields, zap.Bool("is_featured", req.IsFeatured)) if !ok { var errMsg string for field, msg := range valErrs { errMsg += fmt.Sprintf("%s: %s; ", field, msg) } h.BadRequestLogger().Info("Failed to validate SetLeagueFeaturedReq", append(queryLogFields, zap.Error(err))...) return fiber.NewError(fiber.StatusBadRequest, errMsg) } err = h.leagueSvc.SaveLeagueSettings(c.Context(), domain.CreateLeagueSettings{ LeagueID: leagueId, CompanyID: companyID.Value, IsFeatured: domain.ValidBool{ Value: req.IsFeatured, Valid: true, }, }) if err != nil { h.InternalServerErrorLogger().Error("Failed to update league", append(queryLogFields, zap.Error(err))...) return fiber.NewError(fiber.StatusInternalServerError, "Failed to update league:"+err.Error()) } h.SuccessResLogger().Info("League Featured has been successfully updated", queryLogFields...) return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil) } func (h *Handler) UpdateGlobalLeagueSetting(c *fiber.Ctx) error { leagueIdStr := c.Params("id") if leagueIdStr == "" { return fiber.NewError(fiber.StatusBadRequest, "Missing league id") } leagueId, err := strconv.ParseInt(leagueIdStr, 10, 64) if err != nil { return fiber.NewError(fiber.StatusBadRequest, "invalid league id") } var req domain.UpdateLeagueSettingsReq if err := c.BodyParser(&req); err != nil { h.BadRequestLogger().Info("UpdateLeagueSettingsReq failed to parse request body", zap.String("league_id", leagueIdStr), zap.Error(err)) return fiber.NewError(fiber.StatusBadRequest, "Failed to parse request body:"+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) } h.BadRequestLogger().Info("Failed to validate UpdateLeagueSettingsReq", zap.Error(err)) return fiber.NewError(fiber.StatusBadRequest, errMsg) } err = h.leagueSvc.UpdateGlobalLeagueSettings(c.Context(), domain.UpdateGlobalLeagueSettings{ ID: leagueId, DefaultIsActive: domain.ConvertBoolPtr(req.IsActive), DefaultIsFeatured: domain.ConvertBoolPtr(req.IsFeatured), }) if err != nil { h.InternalServerErrorLogger().Error("Failed to update league", zap.Error(err), zap.String("leagueId", leagueIdStr)) return fiber.NewError(fiber.StatusInternalServerError, "Failed to update league:"+err.Error()) } return response.WriteJSON(c, fiber.StatusOK, "League updated successfully", nil, nil) }