// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/collection/anonymize_user_references.go
package collection

import (
	"context"
	"fmt"

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

	dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection"
)

// AnonymizeUserReferencesUseCase handles anonymizing CreatedByUserID and ModifiedByUserID
// references when a user is deleted, replacing them with a special "deleted user" UUID.
type AnonymizeUserReferencesUseCase interface {
	Execute(ctx context.Context, userID gocql.UUID) (int, error)
}

type anonymizeUserReferencesUseCaseImpl struct {
	logger *zap.Logger
	repo   dom_collection.CollectionRepository
}

// NewAnonymizeUserReferencesUseCase creates a new use case for anonymizing user references in collections
func NewAnonymizeUserReferencesUseCase(
	logger *zap.Logger,
	repo dom_collection.CollectionRepository,
) AnonymizeUserReferencesUseCase {
	return &anonymizeUserReferencesUseCaseImpl{
		logger: logger,
		repo:   repo,
	}
}

// DeletedUserUUID is a well-known UUID representing a deleted user
// UUID: 00000000-0000-0000-0000-000000000001 (DELETED_USER)
var DeletedUserUUID = gocql.UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}

func (uc *anonymizeUserReferencesUseCaseImpl) Execute(ctx context.Context, userID gocql.UUID) (int, error) {
	uc.logger.Info("Anonymizing user references in collection metadata",
		zap.String("user_id", userID.String()))

	// Get all collections owned by this user
	collections, err := uc.repo.GetAllByUserID(ctx, userID)
	if err != nil {
		uc.logger.Error("Failed to get collections by owner",
			zap.String("user_id", userID.String()),
			zap.Error(err))
		return 0, fmt.Errorf("failed to get collections by owner: %w", err)
	}

	updatedCount := 0

	// Update each collection to replace user references with deleted user UUID
	for _, collection := range collections {
		needsUpdate := false

		// Check if this collection has references to the deleted user
		if collection.CreatedByUserID == userID {
			collection.CreatedByUserID = DeletedUserUUID
			needsUpdate = true
		}

		if collection.ModifiedByUserID == userID {
			collection.ModifiedByUserID = DeletedUserUUID
			needsUpdate = true
		}

		// Also anonymize GrantedByID in collection memberships
		for i := range collection.Members {
			if collection.Members[i].GrantedByID == userID {
				collection.Members[i].GrantedByID = DeletedUserUUID
				needsUpdate = true
			}
		}

		if needsUpdate {
			// Update the collection with anonymized references
			if err := uc.repo.Update(ctx, collection); err != nil {
				uc.logger.Error("Failed to anonymize user references in collection",
					zap.String("collection_id", collection.ID.String()),
					zap.String("user_id", userID.String()),
					zap.Error(err))
				// Continue with other collections even if one fails
				continue
			}
			updatedCount++
		}
	}

	uc.logger.Info("✅ Anonymized user references in collection metadata",
		zap.String("user_id", userID.String()),
		zap.Int("collections_updated", updatedCount))

	return updatedCount, nil
}
