package api import ( "encoding/json" "net/http" "github.com/fujin/music-agregator/internal/database" "github.com/fujin/music-agregator/internal/services" "github.com/go-chi/chi/v5" ) func (h *Handlers) SearchArtists(w http.ResponseWriter, r *http.Request) { var req struct { Query string `json:"query"` Limit int32 `json:"limit,omitempty"` Offset int32 `json:"offset,omitempty"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } if req.Limit == 0 { req.Limit = 10 } result, err := h.MetadataClient.SearchArtists(r.Context(), req.Query, req.Limit, req.Offset) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, result) } func (h *Handlers) GetArtistAlbums(w http.ResponseWriter, r *http.Request) { artistID := chi.URLParam(r, "id") result, err := h.MetadataClient.GetArtistAlbums(r.Context(), artistID, 500, 0) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, result) } func (h *Handlers) GetArtist(w http.ResponseWriter, r *http.Request) { if h.DB == nil { writeError(w, http.StatusServiceUnavailable, "database not connected") return } artistID := chi.URLParam(r, "id") if artistID == "" { writeError(w, http.StatusBadRequest, "artist ID required") return } artist, err := h.DB.GetArtistByForeignID(r.Context(), artistID) if err != nil { writeError(w, http.StatusNotFound, "artist not found: "+artistID) return } writeJSON(w, http.StatusOK, artist) } func (h *Handlers) EditArtist(w http.ResponseWriter, r *http.Request) { if h.DB == nil { writeError(w, http.StatusServiceUnavailable, "database not connected") return } artistID := chi.URLParam(r, "id") if artistID == "" { writeError(w, http.StatusBadRequest, "artist ID required") return } var update database.ArtistUpdate if err := json.NewDecoder(r.Body).Decode(&update); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } artist, err := h.DB.UpdateArtistByForeignID(r.Context(), artistID, update) if err != nil { writeError(w, http.StatusNotFound, "artist not found: "+artistID) return } writeJSON(w, http.StatusOK, artist) } func (h *Handlers) DeleteArtist(w http.ResponseWriter, r *http.Request) { if h.DB == nil { writeError(w, http.StatusServiceUnavailable, "database not connected") return } artistID := chi.URLParam(r, "id") if artistID == "" { writeError(w, http.StatusBadRequest, "artist ID required") return } deleted, err := h.DB.DeleteArtistByForeignID(r.Context(), artistID) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } if !deleted { writeError(w, http.StatusNotFound, "artist not found: "+artistID) return } writeJSON(w, http.StatusOK, map[string]any{ "deleted": true, "message": "artist and related data deleted", }) } func (h *Handlers) RefreshArtist(w http.ResponseWriter, r *http.Request) { if h.DB == nil { writeError(w, http.StatusServiceUnavailable, "database not connected") return } artistID := chi.URLParam(r, "id") if artistID == "" { writeError(w, http.StatusBadRequest, "artist ID required") return } result, err := services.RefreshArtist(r.Context(), artistID, h.MetadataClient, h.DB) if err != nil { if _, ok := err.(*services.NotFoundError); ok { writeError(w, http.StatusNotFound, err.Error()) return } writeError(w, http.StatusInternalServerError, err.Error()) return } writeJSON(w, http.StatusOK, result) } func (h *Handlers) BulkMonitorArtistAlbums(w http.ResponseWriter, r *http.Request) { if h.DB == nil { writeError(w, http.StatusServiceUnavailable, "database not connected") return } artistID := chi.URLParam(r, "id") if artistID == "" { writeError(w, http.StatusBadRequest, "artist ID required") return } var req struct { Monitored bool `json:"monitored"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "invalid request body") return } artist, err := h.DB.GetArtistMetadataByForeignID(r.Context(), artistID) if err != nil { writeError(w, http.StatusNotFound, "artist not found") return } updatedCount, err := h.DB.BulkUpdateAlbumsMonitored(r.Context(), artist.ID, req.Monitored) if err != nil { writeError(w, http.StatusInternalServerError, err.Error()) return } albums, _ := h.DB.ListAlbumsByArtist(r.Context(), artist.ID) for _, album := range albums { if req.Monitored { hasFiles, _ := h.DB.HasTrackFiles(r.Context(), album.ID) if !hasFiles { h.DB.AddToWantedAlbums(r.Context(), album.ID) } } else { h.DB.RemoveFromWantedAlbums(r.Context(), album.ID) } } writeJSON(w, http.StatusOK, map[string]any{ "updated_count": updatedCount, "monitored": req.Monitored, }) } func (h *Handlers) SearchArtistAlbums(w http.ResponseWriter, r *http.Request) { if h.DB == nil { writeError(w, http.StatusServiceUnavailable, "database not connected") return } artistID := chi.URLParam(r, "id") if artistID == "" { writeError(w, http.StatusBadRequest, "artist ID required") return } result, err := services.SearchArtistAlbums(r.Context(), artistID, h.DB, h.IndexerService) if err != nil { writeError(w, http.StatusNotFound, "artist not found") return } writeJSON(w, http.StatusOK, result) }