package gateway

import (
	"context"
	"errors"
	"fmt"

	"go.uber.org/zap"

	domainuser "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/logger"
)

// GetUserByEmailUseCase retrieves a user by email for authentication
type GetUserByEmailUseCase struct {
	userRepo domainuser.Repository
	logger   *zap.Logger
}

// ProvideGetUserByEmailUseCase creates a new GetUserByEmailUseCase
func ProvideGetUserByEmailUseCase(
	userRepo domainuser.Repository,
	logger *zap.Logger,
) *GetUserByEmailUseCase {
	return &GetUserByEmailUseCase{
		userRepo: userRepo,
		logger:   logger.Named("get-user-by-email-usecase"),
	}
}

// Execute retrieves a user by email globally (across all tenants)
// Returns ErrInvalidCredentials instead of ErrUserNotFound for security (timing attack prevention)
func (uc *GetUserByEmailUseCase) Execute(ctx context.Context, email string) (*domainuser.User, error) {
	user, err := uc.userRepo.GetByEmailGlobal(ctx, email)
	if err != nil {
		if errors.Is(err, domainuser.ErrUserNotFound) {
			// CWE-532: Use hashed email to prevent PII in logs
			uc.logger.Warn("user not found for login",
				logger.EmailHash(email))
			// Return generic error to prevent email enumeration
			return nil, ErrInvalidCredentials
		}
		uc.logger.Error("failed to get user by email", zap.Error(err))
		return nil, fmt.Errorf("failed to get user: %w", err)
	}

	// CWE-532: Use hashed email to prevent PII in logs
	uc.logger.Debug("user found for login",
		zap.String("user_id", user.ID),
		logger.EmailHash(email))

	return user, nil
}
