package requestparams

import (
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// PositiveLimit reads an optional positive-integer query param `key`,
// defaulting to defaultValue when absent and clamping to maxValue. It writes a
// 400 response and returns ok=false on a non-numeric or non-positive value.
func PositiveLimit(c *gin.Context, key string, defaultValue, maxValue int) (int, bool) {
	raw := c.Query(key)
	if raw == "" {
		return defaultValue, true
	}
	n, err := strconv.Atoi(raw)
	if err != nil || n <= 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid " + key})
		return 0, false
	}
	if n > maxValue {
		return maxValue, true
	}
	return n, true
}

// OptionalNonNegativeInt reads an optional non-negative-integer query param
// `key`, defaulting to defaultValue when absent. It writes a 400 response and
// returns ok=false on a non-numeric or negative value.
func OptionalNonNegativeInt(c *gin.Context, key string, defaultValue int) (int, bool) {
	raw := c.Query(key)
	if raw == "" {
		return defaultValue, true
	}
	n, err := strconv.Atoi(raw)
	if err != nil || n < 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid " + key})
		return 0, false
	}
	return n, true
}

// OptionalRFC3339Nano reads an optional RFC3339Nano timestamp query param
// `key`, returning the zero time when absent. It writes a 400 response and
// returns ok=false on an unparseable value.
func OptionalRFC3339Nano(c *gin.Context, key string) (time.Time, bool) {
	raw := c.Query(key)
	if raw == "" {
		return time.Time{}, true
	}
	ts, err := time.Parse(time.RFC3339Nano, raw)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid " + key})
		return time.Time{}, false
	}
	return ts, true
}
