package stats import ( "encoding/json" "net/http" "strconv" "rideaware/internal/config" "rideaware/internal/middleware" ) type Handler struct { service *Service } func NewHandler() *Handler { return &Handler{ service: NewService(), } } // GetSummary GET /api/protected/stats/summary func (h *Handler) GetSummary(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) if claims == nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"}) return } summary, err := h.service.GetSummary(claims.UserID) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to fetch stats"}) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(summary) } // GetWeeklyStats GET /api/protected/stats/weekly?weeks=12 func (h *Handler) GetWeeklyStats(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) if claims == nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"}) return } weeks := 12 if w_str := r.URL.Query().Get("weeks"); w_str != "" { if parsed, err := strconv.Atoi(w_str); err == nil { weeks = parsed } } stats, err := h.service.GetWeeklyStats(claims.UserID, weeks) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to fetch weekly stats"}) return } if stats == nil { stats = []PeriodStats{} } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(stats) } // GetMonthlyStats GET /api/protected/stats/monthly?months=12 func (h *Handler) GetMonthlyStats(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) if claims == nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"}) return } months := 12 if m_str := r.URL.Query().Get("months"); m_str != "" { if parsed, err := strconv.Atoi(m_str); err == nil { months = parsed } } stats, err := h.service.GetMonthlyStats(claims.UserID, months) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to fetch monthly stats"}) return } if stats == nil { stats = []PeriodStats{} } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(stats) } // GetPersonalBests GET /api/protected/stats/personal-bests func (h *Handler) GetPersonalBests(w http.ResponseWriter, r *http.Request) { claims := r.Context().Value(middleware.UserContextKey).(*config.CustomClaims) if claims == nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusUnauthorized) json.NewEncoder(w).Encode(map[string]string{"error": "unauthorized"}) return } pbs, err := h.service.GetPersonalBests(claims.UserID) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{"error": "failed to fetch personal bests"}) return } if pbs == nil { pbs = []PersonalBest{} } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(pbs) }