package domain

import "time"

// Default rate limit values. These must match the defaults in
// internal/db/migrations/005_rate_limiting.sql
const (
	DefaultRateLimitPerMinute = 60
	DefaultRateLimitPerHour   = 1000
)

// RateLimitConfig holds the rate limit configuration for an API key.
type RateLimitConfig struct {
	// PerMinute is the maximum number of requests allowed per minute.
	PerMinute int

	// PerHour is the maximum number of requests allowed per hour.
	PerHour int
}

// DefaultRateLimitConfig returns the default rate limit configuration.
func DefaultRateLimitConfig() RateLimitConfig {
	return RateLimitConfig{
		PerMinute: DefaultRateLimitPerMinute,
		PerHour:   DefaultRateLimitPerHour,
	}
}

// RateLimitState tracks the current usage within a time window.
type RateLimitState struct {
	// APIKeyID is the identifier of the API key.
	APIKeyID string

	// WindowStart is the beginning of the current time window.
	WindowStart time.Time

	// WindowType indicates the type of window ("minute" or "hour").
	WindowType string

	// RequestCount is the number of requests made in this window.
	RequestCount int

	// UpdatedAt is when this state was last updated.
	UpdatedAt time.Time
}

// WindowTypeMinute is the constant for minute-based windows.
const WindowTypeMinute = "minute"

// WindowTypeHour is the constant for hour-based windows.
const WindowTypeHour = "hour"

// RateLimitResult contains the result of a rate limit check.
type RateLimitResult struct {
	// Allowed indicates whether the request is allowed.
	Allowed bool

	// RetryAfter is the duration to wait before retrying (when not allowed).
	RetryAfter time.Duration

	// RemainingMinute is the number of requests remaining in the current minute.
	RemainingMinute int

	// RemainingHour is the number of requests remaining in the current hour.
	RemainingHour int

	// LimitMinute is the per-minute limit for this key.
	LimitMinute int

	// LimitHour is the per-hour limit for this key.
	LimitHour int

	// ResetMinute is when the minute window resets.
	ResetMinute time.Time

	// ResetHour is when the hour window resets.
	ResetHour time.Time
}

// TruncateToMinute truncates a time to the start of the minute.
func TruncateToMinute(t time.Time) time.Time {
	return t.Truncate(time.Minute)
}

// TruncateToHour truncates a time to the start of the hour.
func TruncateToHour(t time.Time) time.Time {
	return t.Truncate(time.Hour)
}
