package user

import (
	"time"

	"github.com/gocql/gocql"
	"go.uber.org/zap"

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

// CreateUserEntityUseCase creates and validates a user domain entity
type CreateUserEntityUseCase struct {
	ipEncryptor *ipcrypt.IPEncryptor
	logger      *zap.Logger
}

// ProvideCreateUserEntityUseCase creates a new CreateUserEntityUseCase
func ProvideCreateUserEntityUseCase(ipEncryptor *ipcrypt.IPEncryptor, logger *zap.Logger) *CreateUserEntityUseCase {
	return &CreateUserEntityUseCase{
		ipEncryptor: ipEncryptor,
		logger:      logger.Named("create-user-entity-usecase"),
	}
}

// Execute creates a new user domain entity with validation
func (uc *CreateUserEntityUseCase) Execute(tenantID string, input *CreateUserInput) (*domainuser.User, error) {
	// Set default role if not provided
	role := int(input.Role)
	if role == 0 {
		role = 1 // Default role
	}

	now := time.Now()

	// CWE-359: Encrypt IP address for GDPR compliance
	encryptedIP := ""
	if input.CreatedFromIPAddress != "" {
		encrypted, err := uc.ipEncryptor.Encrypt(input.CreatedFromIPAddress)
		if err != nil {
			uc.logger.Error("failed to encrypt IP address",
				zap.Error(err),
				zap.String("ip_plain", input.CreatedFromIPAddress))
			// Don't fail user creation if encryption fails, just log it
			encryptedIP = ""
		} else {
			encryptedIP = encrypted
			uc.logger.Debug("IP address encrypted for user creation")
		}
	}

	// Create domain entity
	user := &domainuser.User{
		ID:        gocql.TimeUUID().String(),
		TenantID:  tenantID,
		Email:     input.Email,
		FirstName: input.FirstName,
		LastName:  input.LastName,
		Name:      input.FirstName + " " + input.LastName, // Computed from FirstName + LastName
		Role:      role,
		Status:    1, // Default active status

		ProfileData: &domainuser.UserProfileData{
			AgreeTermsOfService: true, // Default to true for entity creation
		},

		SecurityData: &domainuser.UserSecurityData{
			PasswordHash:          input.PasswordHash,
			PasswordHashAlgorithm: "argon2id",
			WasEmailVerified:      false,
		},

		Metadata: &domainuser.UserMetadata{
			CreatedFromIPAddress:    encryptedIP, // CWE-359: Encrypted IP
			CreatedFromIPTimestamp:  now,         // CWE-359: For 90-day GDPR expiration
			ModifiedFromIPAddress:   encryptedIP, // CWE-359: Encrypted IP
			ModifiedFromIPTimestamp: now,         // CWE-359: For 90-day GDPR expiration
			CreatedAt:               now,
			ModifiedAt:              now,
		},

		CreatedAt: now,
		UpdatedAt: now,
	}

	// Validate domain entity
	if err := user.Validate(); err != nil {
		// CWE-532: Use hashed email to prevent PII in logs
		uc.logger.Warn("user validation failed",
			logger.EmailHash(input.Email),
			zap.Error(err))
		return nil, err
	}

	// CWE-532: Use hashed email to prevent PII in logs
	uc.logger.Debug("user entity created and validated",
		zap.String("user_id", user.ID),
		logger.EmailHash(user.Email),
		zap.Int("role", user.Role))

	return user, nil
}
