package auth

import (
	"context"
	"time"
)

type Repository interface {
	// Users
	CreateUser(ctx context.Context, user *User) error
	GetUserByID(ctx context.Context, id []byte) (*User, error)
	GetUserByEmail(ctx context.Context, email string) (*User, error)
	GetUserBySSOEmail(ctx context.Context, ssoEmail string) (*User, error)
	GetUserByUsername(ctx context.Context, username string) (*User, error)
	UpdateUserTimezone(ctx context.Context, id []byte, timezone string) error
	SetUserPassword(ctx context.Context, id []byte, passwordHash, salt []byte) error
	SetUserSecurityPIN(ctx context.Context, id []byte, pinHash []byte, setAt time.Time) error
	MarkEmailVerified(ctx context.Context, id []byte) error

	// Password resets
	CreatePasswordResetToken(ctx context.Context, token *PasswordResetToken) error
	InvalidateActivePasswordResetTokensByUserID(ctx context.Context, userID []byte, usedAt time.Time) error
	ConsumePasswordResetTokenAndSetPassword(ctx context.Context, tokenHash, passwordHash, salt []byte, usedAt time.Time) ([]byte, bool, error)

	// Security PIN resets
	CreateSecurityPINResetToken(ctx context.Context, token *SecurityPINResetToken) error
	InvalidateActiveSecurityPINResetTokensByUserID(ctx context.Context, userID []byte, usedAt time.Time) error
	GetActiveSecurityPINResetTokenUser(ctx context.Context, tokenHash []byte, now time.Time) (*User, error)
	ConsumeSecurityPINResetTokenAndSetPIN(ctx context.Context, tokenHash, pinHash []byte, usedAt time.Time) ([]byte, bool, error)

	// Identities (SSO)
	UpsertIdentity(ctx context.Context, identity *UserIdentity) error
	CreateIdentity(ctx context.Context, identity *UserIdentity) error
	GetIdentityByProviderSubject(ctx context.Context, provider, subject string) (*UserIdentity, error)
	GetIdentityByUserID(ctx context.Context, userID []byte) (*UserIdentity, error)
	DeleteIdentityByUserIDProvider(ctx context.Context, userID []byte, provider string) (bool, error)

	// TOTP
	GetUserTOTP(ctx context.Context, userID []byte) (*UserTOTP, error)
	UpsertUserTOTP(ctx context.Context, totp *UserTOTP) error
	DisableUserTOTP(ctx context.Context, userID []byte) error
	DeleteUserTOTPSetup(ctx context.Context, userID []byte) error
	UpdateUserTOTPLastUsed(ctx context.Context, userID []byte) error

	// Email login OTP
	GetActiveUserEmailLoginOTP(ctx context.Context, userID []byte, now time.Time) (*UserEmailLoginOTP, error)
	CountUserEmailLoginOTPSince(ctx context.Context, userID []byte, since time.Time) (int64, error)
	CreateUserEmailLoginOTP(ctx context.Context, otp *UserEmailLoginOTP) error
	InvalidateActiveUserEmailLoginOTPs(ctx context.Context, userID []byte, usedAt time.Time) error
	ConsumeUserEmailLoginOTP(ctx context.Context, userID, otpHash []byte, now time.Time) (bool, int, error)

	// WebAuthn
	ListUserWebAuthnCredentials(ctx context.Context, userID []byte) ([]UserWebAuthnCredential, error)
	CreateUserWebAuthnCredential(ctx context.Context, credential *UserWebAuthnCredential) error
	UpdateUserWebAuthnCredential(ctx context.Context, userID, credentialID, credentialJSON []byte, usedAt time.Time) error
	DeleteAllUserWebAuthnCredentials(ctx context.Context, userID []byte) error
}
