package port

import (
	"context"

	"{{GO_MODULE}}/services/{{COMPONENT_NAME}}/internal/domain"
)

// UserRepository defines the interface for user persistence.
type UserRepository interface {
	// Create persists a new user.
	Create(ctx context.Context, user *domain.User) error

	// Get returns a user by ID. Returns domain.ErrUserNotFound if not found.
	Get(ctx context.Context, id domain.UserID) (*domain.User, error)

	// GetByEmail returns a user by email. Returns domain.ErrUserNotFound if not found.
	GetByEmail(ctx context.Context, email string) (*domain.User, error)

	// Update persists changes to an existing user.
	Update(ctx context.Context, user *domain.User) error

	// UpdateLastLogin sets the last_login_at timestamp.
	UpdateLastLogin(ctx context.Context, id domain.UserID) error

	// ExistsByEmail returns true if a user with the given email exists.
	ExistsByEmail(ctx context.Context, email string) (bool, error)

	// Password operations (separate from user CRUD because OAuth-only users have no password)

	// SetPassword stores a bcrypt hash for a user. Creates or replaces existing.
	SetPassword(ctx context.Context, userID domain.UserID, hash string) error

	// GetPasswordHash returns the bcrypt hash for a user.
	// Returns empty string and nil error if user has no password set.
	GetPasswordHash(ctx context.Context, userID domain.UserID) (string, error)

	// HasPassword returns true if the user has a password set.
	HasPassword(ctx context.Context, userID domain.UserID) (bool, error)

	// Role operations

	// AddRole grants a role to a user. No-op if already granted.
	AddRole(ctx context.Context, userID domain.UserID, role string) error

	// RemoveRole revokes a role from a user. No-op if not granted.
	RemoveRole(ctx context.Context, userID domain.UserID, role string) error

	// GetRoles returns all roles for a user.
	GetRoles(ctx context.Context, userID domain.UserID) ([]string, error)
}
