package usecase

import "context"

// TOTPUseCase manages business-tier RFC 6238 TOTP enrollment and verification.
//
// The contract mirrors internal/model/member/SDD.md §3.5: enrollment is split
// in two steps (start → confirm) so the secret is only committed after the
// user proves possession; backup codes are returned exactly once on
// confirmation and replenished via RegenerateBackupCodes.
type TOTPUseCase interface {
	// StartEnroll generates a fresh secret, stashes it in a short-lived cache,
	// and returns the otpauth URL for QR rendering. Calling it twice replaces
	// the staged secret.
	StartEnroll(ctx context.Context, tenantID, uid, account string) (*EnrollStartDTO, error)

	// ConfirmEnroll validates the first user-supplied code against the staged
	// secret, persists the encrypted secret on the profile, and returns the
	// plaintext backup codes (only returned here once).
	ConfirmEnroll(ctx context.Context, tenantID, uid, code string) ([]string, error)

	// VerifyCode validates a code (TOTP or backup) for step-up. Backup codes
	// are single-use; replays of a successful TOTP code are rejected.
	VerifyCode(ctx context.Context, tenantID, uid, code string) error

	// Disable clears the secret and backup codes; intended to be guarded by a
	// step-up token in the logic layer.
	Disable(ctx context.Context, tenantID, uid string) error

	// RegenerateBackupCodes replaces existing backup codes with a new batch.
	RegenerateBackupCodes(ctx context.Context, tenantID, uid string) ([]string, error)

	// Status reports the current enrollment state for UI/admin views.
	Status(ctx context.Context, tenantID, uid string) (*TOTPStatusDTO, error)
}

// EnrollStartDTO is returned by TOTPUseCase.StartEnroll. Secret material is
// never returned in plaintext outside the otpauth URL.
type EnrollStartDTO struct {
	OtpauthURL string `json:"otpauth_url"`
	Issuer     string `json:"issuer"`
	Account    string `json:"account"`
	Digits     int    `json:"digits"`
	PeriodSec  int    `json:"period_seconds"`
	ExpiresIn  int    `json:"expires_in"`
}

// TOTPStatusDTO reports whether TOTP is active for the member and how many
// backup codes remain unused.
type TOTPStatusDTO struct {
	Enrolled             bool  `json:"enrolled"`
	EnrolledAt           int64 `json:"enrolled_at,omitempty"`
	BackupCodesRemaining int   `json:"backup_codes_remaining"`
}
