package handlers

import (
	"net/http"

	"github.com/google/uuid"
)

// POST /api/projects/{id}/pin — idempotent pin. Returns 201 (or 200 if
// already pinned). Empty body. Visibility-gated by PinService.
func handlePinProject(w http.ResponseWriter, r *http.Request) {
	if !requireDB(w) {
		return
	}
	uid, ok := requireUser(w, r)
	if !ok {
		return
	}
	id, err := uuid.Parse(r.PathValue("id"))
	if err != nil {
		writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid id"})
		return
	}
	if dbSvc.pin == nil {
		writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": "pin service not configured"})
		return
	}
	if err := dbSvc.pin.Pin(r.Context(), uid, id); err != nil {
		writeServiceError(w, err)
		return
	}
	w.WriteHeader(http.StatusCreated)
}

// DELETE /api/projects/{id}/pin — idempotent unpin. Always returns 204.
// Does NOT gate on visibility (so users can clean up pins on projects
// they've lost access to).
func handleUnpinProject(w http.ResponseWriter, r *http.Request) {
	if !requireDB(w) {
		return
	}
	uid, ok := requireUser(w, r)
	if !ok {
		return
	}
	id, err := uuid.Parse(r.PathValue("id"))
	if err != nil {
		writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid id"})
		return
	}
	if dbSvc.pin == nil {
		writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": "pin service not configured"})
		return
	}
	if err := dbSvc.pin.Unpin(r.Context(), uid, id); err != nil {
		writeServiceError(w, err)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}

// GET /api/user-pinned-projects — flat list of project IDs the user has
// pinned, most-recent-pin first. Used by the (deferred) sidebar pin widget;
// the /projects tree response carries `pinned: bool` per node, so the
// /projects page itself doesn't hit this endpoint.
func handleListPinnedProjects(w http.ResponseWriter, r *http.Request) {
	if !requireDB(w) {
		return
	}
	uid, ok := requireUser(w, r)
	if !ok {
		return
	}
	if dbSvc.pin == nil {
		writeJSON(w, http.StatusServiceUnavailable, map[string]string{"error": "pin service not configured"})
		return
	}
	ids, err := dbSvc.pin.ListPinned(r.Context(), uid)
	if err != nil {
		writeServiceError(w, err)
		return
	}
	type row struct {
		ProjectID uuid.UUID `json:"project_id"`
	}
	out := make([]row, len(ids))
	for i, id := range ids {
		out[i] = row{ProjectID: id}
	}
	writeJSON(w, http.StatusOK, out)
}
