package api import ( "errors" "net/http" "strconv" "messenger/internal/store" ) func (h *apiHandler) searchUsers(w http.ResponseWriter, r *http.Request) { query := r.URL.Query().Get("q") users, err := h.store.SearchUsers(r.Context(), query, 20) if err != nil { writeError(w, http.StatusInternalServerError, "internal server error") return } out := make([]userJSON, 0, len(users)) for i := range users { out = append(out, toUserJSON(&users[i])) } writeJSON(w, http.StatusOK, out) } type contactJSON struct { User userJSON `json:"user"` AddedAt string `json:"added_at"` } func (h *apiHandler) listContacts(w http.ResponseWriter, r *http.Request) { userID, _ := userIDFrom(r.Context()) contacts, err := h.store.ListContacts(r.Context(), userID) if err != nil { writeError(w, http.StatusInternalServerError, "internal server error") return } out := make([]contactJSON, 0, len(contacts)) for _, c := range contacts { u, err := h.store.GetUserByID(r.Context(), c.ContactID) if err != nil { continue } out = append(out, contactJSON{User: toUserJSON(u), AddedAt: c.CreatedAt.Format("2006-01-02T15:04:05Z07:00")}) } writeJSON(w, http.StatusOK, out) } func (h *apiHandler) addContact(w http.ResponseWriter, r *http.Request) { userID, _ := userIDFrom(r.Context()) var req struct { UserID int64 `json:"user_id"` } if !decodeJSON(w, r, &req) { return } if req.UserID <= 0 { writeError(w, http.StatusBadRequest, "invalid user_id") return } if req.UserID == userID { writeError(w, http.StatusBadRequest, "cannot add yourself") return } if _, err := h.store.GetUserByID(r.Context(), req.UserID); err != nil { if errors.Is(err, store.ErrNotFound) { writeError(w, http.StatusNotFound, "user not found") return } writeError(w, http.StatusInternalServerError, "internal server error") return } if err := h.store.AddContact(r.Context(), userID, req.UserID); err != nil { if errors.Is(err, store.ErrDuplicate) { writeJSON(w, http.StatusOK, map[string]string{"status": "already a contact"}) return } writeError(w, http.StatusInternalServerError, "internal server error") return } writeJSON(w, http.StatusCreated, map[string]string{"status": "ok"}) } func (h *apiHandler) removeContact(w http.ResponseWriter, r *http.Request) { userID, _ := userIDFrom(r.Context()) contactID, err := strconv.ParseInt(r.PathValue("user_id"), 10, 64) if err != nil || contactID <= 0 { writeError(w, http.StatusBadRequest, "invalid user_id") return } if err := h.store.RemoveContact(r.Context(), userID, contactID); err != nil { writeError(w, http.StatusInternalServerError, "internal server error") return } writeJSON(w, http.StatusOK, map[string]string{"status": "ok"}) }