package user

import (
	"context"

	"go.uber.org/zap"

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

// CreateUserService handles user creation operations
type CreateUserService interface {
	CreateUser(ctx context.Context, tenantID string, input *userusecase.CreateUserInput) (*userusecase.CreateUserOutput, error)
}

type createUserService struct {
	// Focused usecases
	validateEmailUC  *userusecase.ValidateUserEmailUniqueUseCase
	createEntityUC   *userusecase.CreateUserEntityUseCase
	saveUserToRepoUC *userusecase.SaveUserToRepoUseCase

	logger *zap.Logger
}

// NewCreateUserService creates a new CreateUserService
func NewCreateUserService(
	validateEmailUC *userusecase.ValidateUserEmailUniqueUseCase,
	createEntityUC *userusecase.CreateUserEntityUseCase,
	saveUserToRepoUC *userusecase.SaveUserToRepoUseCase,
	logger *zap.Logger,
) CreateUserService {
	return &createUserService{
		validateEmailUC:  validateEmailUC,
		createEntityUC:   createEntityUC,
		saveUserToRepoUC: saveUserToRepoUC,
		logger:           logger.Named("create-user-service"),
	}
}

// CreateUser orchestrates the user creation workflow
func (s *createUserService) CreateUser(ctx context.Context, tenantID string, input *userusecase.CreateUserInput) (*userusecase.CreateUserOutput, error) {
	// CWE-532: Use redacted email for logging
	s.logger.Info("creating user",
		zap.String("tenant_id", tenantID),
		logger.EmailHash(input.Email),
		logger.SafeEmail("email_redacted", input.Email))

	// Step 1: Validate email uniqueness (fail fast)
	if err := s.validateEmailUC.Execute(ctx, tenantID, input.Email); err != nil {
		// CWE-532: Use redacted email for logging
		s.logger.Error("email validation failed",
			logger.EmailHash(input.Email),
			logger.SafeEmail("email_redacted", input.Email),
			zap.Error(err))
		return nil, err
	}

	// Step 2: Create and validate user entity
	user, err := s.createEntityUC.Execute(tenantID, input)
	if err != nil {
		// CWE-532: Use redacted email for logging
		s.logger.Error("entity creation failed",
			logger.EmailHash(input.Email),
			logger.SafeEmail("email_redacted", input.Email),
			zap.Error(err))
		return nil, err
	}

	// Step 3: Save user to repository
	if err := s.saveUserToRepoUC.Execute(ctx, tenantID, user); err != nil {
		s.logger.Error("failed to save user",
			zap.String("user_id", user.ID),
			zap.Error(err))
		return nil, err
	}

	// CWE-532: Use redacted email for logging
	s.logger.Info("user created successfully",
		zap.String("user_id", user.ID),
		logger.EmailHash(user.Email),
		logger.SafeEmail("email_redacted", user.Email))

	// Step 4: Build output
	return &userusecase.CreateUserOutput{
		ID:        user.ID,
		Email:     user.Email,
		Name:      user.Name,
		CreatedAt: user.CreatedAt,
	}, nil
}
