package usecase

import (
	"context"

	"gateway/internal/model/member/domain/enum"
)

// GenerateOTPRequest creates a new OTP challenge.
type GenerateOTPRequest struct {
	TenantID   string
	UID        string
	Purpose    enum.OTPPurpose
	Target     string // email or phone for verification flows
	Identifier string // optional audit key when uid is empty
}

// VerifyOTPRequest validates a challenge.
type VerifyOTPRequest struct {
	TenantID    string
	UID         string // must match challenge UID when the challenge was issued with a UID
	ChallengeID string
	Code        string
	Purpose     enum.OTPPurpose
}

// MatchChallengeRequest validates persisted challenge metadata before orchestration.
type MatchChallengeRequest struct {
	ChallengeID   string
	TenantID      string
	Purpose       enum.OTPPurpose
	RequireUID    bool
	RequireTarget bool
}

// OTPUseCase is the purpose-agnostic OTP primitive.
type OTPUseCase interface {
	Generate(ctx context.Context, req *GenerateOTPRequest) (*OTPChallengeDTO, string, error)
	// Verify returns the challenge target (e.g. email/phone) after successful validation.
	Verify(ctx context.Context, req *VerifyOTPRequest) (target string, err error)
	Invalidate(ctx context.Context, challengeID string) error
	// GetChallenge returns persisted challenge metadata for orchestration (e.g. register resend).
	GetChallenge(ctx context.Context, challengeID string) (*OTPChallengeInfo, error)
	// MatchChallenge loads a challenge and validates tenant / purpose / required fields.
	MatchChallenge(ctx context.Context, req *MatchChallengeRequest) (*OTPChallengeInfo, error)
}

// OTPChallengeInfo is read-only challenge metadata.
type OTPChallengeInfo struct {
	TenantID string
	UID      string
	Purpose  enum.OTPPurpose
	Target   string
}
