Ctrl K
ComunidadGuías…

internal/handler/workout_wod_handler.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package handler

import (
	"encoding/json"
	"net/http"
	"strconv"

	"github.com/go-chi/chi/v5"
	"github.com/johnzastrow/actalog/internal/service"
	"github.com/johnzastrow/actalog/pkg/middleware"
)

// WorkoutWODHandler handles linking WODs to workout templates
type WorkoutWODHandler struct {
	workoutWODService *service.WorkoutWODService
}

// NewWorkoutWODHandler creates a new workout WOD handler
func NewWorkoutWODHandler(workoutWODService *service.WorkoutWODService) *WorkoutWODHandler {
	return &WorkoutWODHandler{
		workoutWODService: workoutWODService,
	}
}

// AddWODToWorkoutRequest represents a request to add a WOD to a workout template
type AddWODToWorkoutRequest struct {
	WODID      int64   `json:"wod_id"`
	OrderIndex int     `json:"order_index"`
	Division   *string `json:"division,omitempty"`
}

// UpdateWorkoutWODRequest represents a request to update a WOD in a workout
type UpdateWorkoutWODRequest struct {
	ScoreValue *string `json:"score_value,omitempty"`
	Division   *string `json:"division,omitempty"`
}

// AddWODToWorkout adds a WOD to a workout template
func (h *WorkoutWODHandler) AddWODToWorkout(w http.ResponseWriter, r *http.Request) {
	// Extract user ID from JWT token in context
	userID, ok := middleware.GetUserID(r.Context())
	if !ok {
		respondError(w, http.StatusUnauthorized, "Unauthorized")
		return
	}

	// Get workout ID from URL
	workoutIDStr := chi.URLParam(r, "workout_id")
	workoutID, err := strconv.ParseInt(workoutIDStr, 10, 64)
	if err != nil {
		respondError(w, http.StatusBadRequest, "Invalid workout ID")
		return
	}

	var req AddWODToWorkoutRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		respondError(w, http.StatusBadRequest, "Invalid request body")
		return
	}

	// Validate required fields
	if req.WODID == 0 {
		respondError(w, http.StatusBadRequest, "WOD ID is required")
		return
	}

	// Add WOD to workout
	workoutWOD, err := h.workoutWODService.AddWODToWorkout(workoutID, req.WODID, userID, req.OrderIndex, req.Division)
	if err != nil {
		if err == service.ErrUnauthorized {
			respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
		} else {
			respondError(w, http.StatusInternalServerError, "Failed to add WOD to workout: "+err.Error())
		}
		return
	}

	respondJSON(w, http.StatusCreated, workoutWOD)
}

// RemoveWODFromWorkout removes a WOD from a workout template
func (h *WorkoutWODHandler) RemoveWODFromWorkout(w http.ResponseWriter, r *http.Request) {
	// Extract user ID from JWT token in context
	userID, ok := middleware.GetUserID(r.Context())
	if !ok {
		respondError(w, http.StatusUnauthorized, "Unauthorized")
		return
	}

	// Get workout WOD ID from URL
	workoutWODIDStr := chi.URLParam(r, "workout_wod_id")
	workoutWODID, err := strconv.ParseInt(workoutWODIDStr, 10, 64)
	if err != nil {
		respondError(w, http.StatusBadRequest, "Invalid workout WOD ID")
		return
	}

	// Remove WOD from workout
	if err := h.workoutWODService.RemoveWODFromWorkout(workoutWODID, userID); err != nil {
		if err == service.ErrUnauthorized {
			respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
		} else {
			respondError(w, http.StatusInternalServerError, "Failed to remove WOD from workout: "+err.Error())
		}
		return
	}

	respondJSON(w, http.StatusOK, map[string]string{"message": "WOD removed from workout successfully"})
}

// UpdateWorkoutWOD updates a WOD in a workout template
func (h *WorkoutWODHandler) UpdateWorkoutWOD(w http.ResponseWriter, r *http.Request) {
	// Extract user ID from JWT token in context
	userID, ok := middleware.GetUserID(r.Context())
	if !ok {
		respondError(w, http.StatusUnauthorized, "Unauthorized")
		return
	}

	// Get workout WOD ID from URL
	workoutWODIDStr := chi.URLParam(r, "workout_wod_id")
	workoutWODID, err := strconv.ParseInt(workoutWODIDStr, 10, 64)
	if err != nil {
		respondError(w, http.StatusBadRequest, "Invalid workout WOD ID")
		return
	}

	var req UpdateWorkoutWODRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		respondError(w, http.StatusBadRequest, "Invalid request body")
		return
	}

	// Update workout WOD
	if err := h.workoutWODService.UpdateWorkoutWOD(workoutWODID, userID, req.ScoreValue, req.Division); err != nil {
		if err == service.ErrUnauthorized {
			respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
		} else {
			respondError(w, http.StatusInternalServerError, "Failed to update workout WOD: "+err.Error())
		}
		return
	}

	respondJSON(w, http.StatusOK, map[string]string{"message": "Workout WOD updated successfully"})
}

// ToggleWODPR toggles the PR flag on a WOD in a workout
func (h *WorkoutWODHandler) ToggleWODPR(w http.ResponseWriter, r *http.Request) {
	// Extract user ID from JWT token in context
	userID, ok := middleware.GetUserID(r.Context())
	if !ok {
		respondError(w, http.StatusUnauthorized, "Unauthorized")
		return
	}

	// Get workout WOD ID from URL
	workoutWODIDStr := chi.URLParam(r, "workout_wod_id")
	workoutWODID, err := strconv.ParseInt(workoutWODIDStr, 10, 64)
	if err != nil {
		respondError(w, http.StatusBadRequest, "Invalid workout WOD ID")
		return
	}

	// Toggle PR flag
	if err := h.workoutWODService.ToggleWODPR(workoutWODID, userID); err != nil {
		if err == service.ErrUnauthorized {
			respondError(w, http.StatusForbidden, "You don't have permission to modify this workout")
		} else {
			respondError(w, http.StatusInternalServerError, "Failed to toggle WOD PR: "+err.Error())
		}
		return
	}

	respondJSON(w, http.StatusOK, map[string]string{"message": "WOD PR flag toggled successfully"})
}

// ListWODsForWorkout retrieves all WODs for a workout template
func (h *WorkoutWODHandler) ListWODsForWorkout(w http.ResponseWriter, r *http.Request) {
	// Get workout ID from URL
	workoutIDStr := chi.URLParam(r, "workout_id")
	workoutID, err := strconv.ParseInt(workoutIDStr, 10, 64)
	if err != nil {
		respondError(w, http.StatusBadRequest, "Invalid workout ID")
		return
	}

	wods, err := h.workoutWODService.ListWODsForWorkout(workoutID)
	if err != nil {
		respondError(w, http.StatusInternalServerError, "Failed to retrieve WODs for workout")
		return
	}

	respondJSON(w, http.StatusOK, map[string]interface{}{
		"wods": wods,
	})
}