package handler import ( "errors" "net/http" "strconv" "github.com/gin-gonic/gin" "dating-app/internal/dto" "dating-app/internal/models" "dating-app/internal/service" "dating-app/internal/utils" ) type DiscoveryHandler struct { discoveryService *service.DiscoveryService } func NewDiscoveryHandler(discoveryService *service.DiscoveryService) *DiscoveryHandler { return &DiscoveryHandler{discoveryService: discoveryService} } // Feed GET /discover?max_distance_km=&min_age=&max_age= func (h *DiscoveryHandler) Feed(c *gin.Context) { user, ok := currentUser(c) if !ok { return } var maxDistance *float64 if raw := c.Query("max_distance_km"); raw != "" { if v, err := strconv.ParseFloat(raw, 64); err == nil { maxDistance = &v } } minAge, _ := strconv.Atoi(c.Query("min_age")) maxAge, _ := strconv.Atoi(c.Query("max_age")) candidates, err := h.discoveryService.GetFeed(user, maxDistance, minAge, maxAge) if err != nil { h.handleError(c, err) return } utils.Success(c, http.StatusOK, "", candidates) } // CandidateDetail GET /discover/:id func (h *DiscoveryHandler) CandidateDetail(c *gin.Context) { user, ok := currentUser(c) if !ok { return } targetID, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { utils.Fail(c, http.StatusBadRequest, "شناسه نامعتبر است", nil) return } detail, err := h.discoveryService.GetCandidateDetail(user, uint(targetID)) if err != nil { utils.Fail(c, http.StatusNotFound, "پروفایل یافت نشد", nil) return } utils.Success(c, http.StatusOK, "", detail) } // Swipe POST /discover/:id/swipe body: {action: "like"|"pass"|"superlike"} func (h *DiscoveryHandler) Swipe(c *gin.Context) { user, ok := currentUser(c) if !ok { return } targetID, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { utils.Fail(c, http.StatusBadRequest, "شناسه نامعتبر است", nil) return } var req dto.SwipeRequest if err := c.ShouldBindJSON(&req); err != nil { utils.Fail(c, http.StatusBadRequest, "ورودی نامعتبر است", err.Error()) return } result, err := h.discoveryService.Swipe(user, uint(targetID), models.SwipeAction(req.Action)) if err != nil { h.handleError(c, err) return } utils.Success(c, http.StatusOK, "", result) } func (h *DiscoveryHandler) handleError(c *gin.Context, err error) { switch { case errors.Is(err, service.ErrGenderNotSet): utils.Fail(c, http.StatusConflict, err.Error(), nil) case errors.Is(err, service.ErrCannotSwipeSelf), errors.Is(err, service.ErrAlreadySwiped): utils.Fail(c, http.StatusBadRequest, err.Error(), nil) default: utils.Fail(c, http.StatusInternalServerError, "خطای داخلی سرور", nil) } }