package domain

import "strings"

// RedisKey is the member module Redis key prefix. The package-level helpers
// (Get*RedisKey) are the supported way to compose keys; direct string
// concatenation should be avoided so the layout stays auditable.
type RedisKey string

// Key prefixes for the member module. Layout matches
// internal/model/member/SDD.md §4.1 (Redis Keys).
const (
	OTPChallengeRedisKey RedisKey = "member:otp:challenge"
	VerifyRateRedisKey   RedisKey = "member:verify:rate"
	VerifyDailyRedisKey  RedisKey = "member:verify:daily"
	TOTPEnrollRedisKey   RedisKey = "member:totp:enroll"
	TOTPUsedRedisKey     RedisKey = "member:totp:used"
	StepUpRedisKey       RedisKey = "member:stepup"
	MemberSeqRedisKey    RedisKey = "member:seq"
)

// With appends colon-separated parts to the key.
func (key RedisKey) With(parts ...string) RedisKey {
	if len(parts) == 0 {
		return key
	}
	return RedisKey(string(key) + ":" + strings.Join(parts, ":"))
}

// String returns the raw key.
func (key RedisKey) String() string {
	return string(key)
}

// GetOTPChallengeRedisKey returns the challenge-state Redis key.
func GetOTPChallengeRedisKey(challengeID string) string {
	return OTPChallengeRedisKey.With(challengeID).String()
}

// GetOTPAttemptsRedisKey returns the per-challenge failed-attempt counter key.
func GetOTPAttemptsRedisKey(challengeID string) string {
	return OTPChallengeRedisKey.With(challengeID, "attempts").String()
}

// GetVerifyRateRedisKey returns the resend cooldown key.
func GetVerifyRateRedisKey(tenantID, uid, kind string) string {
	return VerifyRateRedisKey.With(tenantID, uid, kind).String()
}

// GetVerifyDailyRedisKey returns the daily verification cap counter key.
func GetVerifyDailyRedisKey(tenantID, uid, kind string) string {
	return VerifyDailyRedisKey.With(tenantID, uid, kind).String()
}

// GetTOTPEnrollRedisKey returns the staged-secret cache key.
func GetTOTPEnrollRedisKey(tenantID, uid string) string {
	return TOTPEnrollRedisKey.With(tenantID, uid).String()
}

// GetTOTPUsedRedisKey returns the replay-protection key for a verified timestep.
func GetTOTPUsedRedisKey(tenantID, uid, timestep string) string {
	return TOTPUsedRedisKey.With(tenantID, uid, timestep).String()
}

// GetMemberSeqRedisKey returns the UID sequence counter key for a tenant.
func GetMemberSeqRedisKey(tenantID string) string {
	return MemberSeqRedisKey.With(tenantID).String()
}

// GetStepUpRedisKey returns the step-up session key for a issued token.
func GetStepUpRedisKey(tokenID string) string {
	return StepUpRedisKey.With(tokenID).String()
}
