package web

import "net/http"

// flashCookie carries a one-shot notification code between a POST→redirect and
// the next rendered page (PRG pattern). The value is a non-sensitive code (not
// user data), so it is not signed; HttpOnly + SameSite=Lax + a short MaxAge bound
// it. The flashBanner component maps the code to a styled message.
const flashCookie = "tapir_flash"

// Flash codes. Kept small and stable — the message + severity live in
// flashMessages (view.go), not here, so the cookie never carries free text.
const (
	flashConnected     = "connected"
	flashConnectFailed = "connect_failed"
	flashDisconnected  = "disconnected"
	flashDeleted       = "deleted"
	flashRegistered    = "registered"
)

// flashMaxAge bounds how long an unread flash lingers (seconds). Long enough to
// survive the redirect, short enough that a stale banner never reappears.
const flashMaxAge = 60

// setFlash queues a one-shot notification surfaced by the next full page render.
func setFlash(w http.ResponseWriter, code string) {
	http.SetCookie(w, &http.Cookie{
		Name:     flashCookie,
		Value:    code,
		Path:     "/",
		MaxAge:   flashMaxAge,
		HttpOnly: true,
		SameSite: http.SameSiteLaxMode,
	})
}

// takeFlash returns the pending flash code (if any) and clears the cookie so the
// banner shows exactly once. Call it only on full-page renders, not HTMX
// fragments, so a fragment swap never consumes a flash meant for the next page.
func takeFlash(w http.ResponseWriter, r *http.Request) string {
	c, err := r.Cookie(flashCookie)
	if err != nil || c.Value == "" {
		return ""
	}
	http.SetCookie(w, &http.Cookie{
		Name:     flashCookie,
		Value:    "",
		Path:     "/",
		MaxAge:   -1,
		HttpOnly: true,
		SameSite: http.SameSiteLaxMode,
	})
	return c.Value
}
