package handler import ( "net/http" "time" "github.com/prabhupadasays/spsays-bff/pkg/response" ) // ListShortURLs — GET /admin/short-urls?q=&limit=&offset= — paginated list of // shortened URLs, newest first. func (h *AdminHandler) ListShortURLs(w http.ResponseWriter, r *http.Request) { q, limit, offset := pageParams(r) items, total, err := h.svc.ListShortURLs(r.Context(), q, limit, offset) if err != nil { response.Error(w, http.StatusInternalServerError, "could not list short urls") return } response.JSONWithMeta(w, http.StatusOK, items, meta(total, limit, offset)) } // ShortURLStats — GET /admin/short-urls/stats?from=YYYY-MM-DD&to=YYYY-MM-DD — // today/week/month/all-time counts, plus a custom range when from+to are given. func (h *AdminHandler) ShortURLStats(w http.ResponseWriter, r *http.Request) { from, to := parseDateRange(r) stats, err := h.svc.ShortURLStats(r.Context(), from, to) if err != nil { response.Error(w, http.StatusInternalServerError, "could not load short url stats") return } response.JSON(w, http.StatusOK, stats) } // parseDateRange reads ?from=YYYY-MM-DD&to=YYYY-MM-DD (UTC). `to` is treated as // inclusive, so the returned upper bound is the exclusive start of the next // day. Returns (nil, nil) unless both dates are present and valid. func parseDateRange(r *http.Request) (*time.Time, *time.Time) { fs := r.URL.Query().Get("from") ts := r.URL.Query().Get("to") if fs == "" || ts == "" { return nil, nil } from, err1 := time.ParseInLocation("2006-01-02", fs, time.UTC) to, err2 := time.ParseInLocation("2006-01-02", ts, time.UTC) if err1 != nil || err2 != nil { return nil, nil } toExclusive := to.AddDate(0, 0, 1) return &from, &toExclusive }