package port

import (
	"context"
	"time"

	"github.com/orchard9/rdev/internal/domain"
)

// APIKeyUpdate contains mutable fields for updating an API key.
// A nil pointer means "don't change" that field.
type APIKeyUpdate struct {
	Name       *string
	Scopes     []domain.Scope      // nil = don't change; non-nil = replace
	ProjectIDs *[]domain.ProjectID // nil ptr = don't change; ptr to nil slice = unrestricted
	AllowedIPs *[]string           // nil ptr = don't change; ptr to nil slice = no restriction
	ExpiresAt  **time.Time         // nil ptr = don't change; ptr to nil ptr = remove expiry
}

// APIKeyRepository defines operations for managing API keys.
type APIKeyRepository interface {
	// Create stores a new API key.
	Create(ctx context.Context, key *domain.APIKey, keyHash string) error

	// GetByHash retrieves an API key by its hash.
	GetByHash(ctx context.Context, keyHash string) (*domain.APIKey, error)

	// Get retrieves an API key by ID.
	Get(ctx context.Context, id domain.APIKeyID) (*domain.APIKey, error)

	// List returns all API keys (without secrets).
	List(ctx context.Context) ([]*domain.APIKey, error)

	// Revoke marks an API key as revoked.
	Revoke(ctx context.Context, id domain.APIKeyID) error

	// UpdateLastUsed updates the last used timestamp for a key.
	UpdateLastUsed(ctx context.Context, id domain.APIKeyID) error

	// Update applies a partial update to an API key.
	Update(ctx context.Context, id domain.APIKeyID, update APIKeyUpdate) error

	// ListByProjectID returns all active keys that have the given project ID in their project_ids.
	ListByProjectID(ctx context.Context, projectID domain.ProjectID) ([]*domain.APIKey, error)
}
