package tenant

import (
	"time"

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

	domaintenant "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/tenant"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security/ipcrypt"
)

// CreateTenantInput represents the input for creating a tenant
type CreateTenantInput struct {
	Name                 string
	Slug                 string
	CreatedFromIPAddress string // Plain IP address (will be encrypted before storage)
}

// CreateTenantOutput represents the output after creating a tenant
type CreateTenantOutput struct {
	ID        string
	Name      string
	Slug      string
	Status    string
	CreatedAt time.Time
}

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

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

// Execute creates a new tenant domain entity with validation
func (uc *CreateTenantEntityUseCase) Execute(input *CreateTenantInput) (*domaintenant.Tenant, error) {
	now := time.Now()

	// Encrypt IP address (CWE-359: GDPR compliance)
	encryptedIP, err := uc.ipEncryptor.Encrypt(input.CreatedFromIPAddress)
	if err != nil {
		uc.logger.Error("failed to encrypt IP address",
			zap.String("slug", input.Slug),
			zap.Error(err))
		return nil, err
	}

	// Create domain entity
	tenant := &domaintenant.Tenant{
		ID:        gocql.TimeUUID().String(),
		Name:      input.Name,
		Slug:      input.Slug,
		Status:    domaintenant.StatusActive,
		CreatedAt: now,
		UpdatedAt: now,
		// CWE-359: Encrypted IP address tracking for GDPR compliance
		CreatedFromIPAddress:    encryptedIP,
		CreatedFromIPTimestamp:  now,
		ModifiedFromIPAddress:   encryptedIP,
		ModifiedFromIPTimestamp: now,
	}

	// Validate domain entity
	if err := tenant.Validate(); err != nil {
		uc.logger.Warn("tenant validation failed",
			zap.String("slug", input.Slug),
			zap.Error(err))
		return nil, err
	}

	uc.logger.Debug("tenant entity created and validated",
		zap.String("tenant_id", tenant.ID),
		zap.String("slug", tenant.Slug))

	return tenant, nil
}
