package amenity import ( "encoding/json" "errors" "net/http" "strconv" "api_yal/internal/logger" "api_yal/internal/middleware" "github.com/go-chi/chi/v5" "github.com/go-playground/validator/v10" "go.uber.org/zap" ) type AmenityHandler struct { service AmenityService validator *validator.Validate } func NewHandler(service AmenityService) *AmenityHandler { return &AmenityHandler{ service: service, validator: validator.New(), } } func (h *AmenityHandler) Create(w http.ResponseWriter, r *http.Request) { var req CreateAmenityRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } if err := h.validator.Struct(req); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } resp, err := h.service.Create(&req) if err != nil { logger.Get().Error("failed to create amenity", zap.Error(err)) http.Error(w, "Failed to create amenity", http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(resp) } func (h *AmenityHandler) GetByID(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32) if err != nil { http.Error(w, "Invalid amenity ID", http.StatusBadRequest) return } resp, err := h.service.GetByID(uint(id)) if err != nil { if errors.Is(err, errors.New("amenity not found")) { http.Error(w, err.Error(), http.StatusNotFound) return } http.Error(w, "Failed to get amenity", http.StatusInternalServerError) return } json.NewEncoder(w).Encode(resp) } func (h *AmenityHandler) Update(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32) if err != nil { http.Error(w, "Invalid amenity ID", http.StatusBadRequest) return } var req UpdateAmenityRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } resp, err := h.service.Update(uint(id), &req) if err != nil { logger.Get().Error("failed to update amenity", zap.Error(err)) http.Error(w, "Failed to update amenity", http.StatusInternalServerError) return } json.NewEncoder(w).Encode(resp) } func (h *AmenityHandler) Delete(w http.ResponseWriter, r *http.Request) { id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32) if err != nil { http.Error(w, "Invalid amenity ID", http.StatusBadRequest) return } if err := h.service.Delete(uint(id)); err != nil { logger.Get().Error("failed to delete amenity", zap.Error(err)) http.Error(w, "Failed to delete amenity", http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) } func (h *AmenityHandler) List(w http.ResponseWriter, r *http.Request) { category := r.URL.Query().Get("category") var resp []AmenityResponse var err error if category != "" { resp, err = h.service.ListByCategory(category) } else { resp, err = h.service.List() } if err != nil { logger.Get().Error("failed to list amenities", zap.Error(err)) http.Error(w, "Failed to list amenities", http.StatusInternalServerError) return } if resp == nil { resp = []AmenityResponse{} } json.NewEncoder(w).Encode(resp) } func (h *AmenityHandler) GetByObject(w http.ResponseWriter, r *http.Request) { objectID, err := strconv.ParseUint(chi.URLParam(r, "objectId"), 10, 32) if err != nil { http.Error(w, "Invalid object ID", http.StatusBadRequest) return } resp, err := h.service.GetByObject(uint(objectID)) if err != nil { logger.Get().Error("failed to get object amenities", zap.Error(err)) http.Error(w, "Failed to get object amenities", http.StatusInternalServerError) return } if resp == nil { resp = []AmenityResponse{} } json.NewEncoder(w).Encode(resp) } func (h *AmenityHandler) ReplaceObjectAmenities(w http.ResponseWriter, r *http.Request) { objectID, err := strconv.ParseUint(chi.URLParam(r, "objectId"), 10, 32) if err != nil { http.Error(w, "Invalid object ID", http.StatusBadRequest) return } userID, ok := r.Context().Value(middleware.UserIDKey).(uint) if !ok { http.Error(w, "Unauthorized", http.StatusUnauthorized) return } _ = userID var req struct { AmenityIDs []uint `json:"amenity_ids"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } if err := h.service.ReplaceObjectAmenities(uint(objectID), req.AmenityIDs); err != nil { logger.Get().Error("failed to replace object amenities", zap.Error(err)) http.Error(w, "Failed to replace amenities", http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"message": "Amenities updated"}) }