// monorepo/cloud/backend/internal/maplefile/usecase/user/anonymize_user_ips_immediately.go
package user

import (
	"context"

	"go.uber.org/zap"

	"github.com/gocql/gocql"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
	dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection"
	dom_file "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/file"
	dom_user "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)

// AnonymizeUserIPsImmediatelyUseCase immediately anonymizes all IP addresses for a user
// Used for GDPR right-to-be-forgotten implementation
type AnonymizeUserIPsImmediatelyUseCase interface {
	Execute(ctx context.Context, userID gocql.UUID) error
}

type anonymizeUserIPsImmediatelyUseCaseImpl struct {
	config         *config.Configuration
	logger         *zap.Logger
	userRepo       dom_user.Repository
	collectionRepo dom_collection.CollectionRepository
	fileRepo       dom_file.FileMetadataRepository
}

func NewAnonymizeUserIPsImmediatelyUseCase(
	config *config.Configuration,
	logger *zap.Logger,
	userRepo dom_user.Repository,
	collectionRepo dom_collection.CollectionRepository,
	fileRepo dom_file.FileMetadataRepository,
) AnonymizeUserIPsImmediatelyUseCase {
	logger = logger.Named("AnonymizeUserIPsImmediatelyUseCase")
	return &anonymizeUserIPsImmediatelyUseCaseImpl{config, logger, userRepo, collectionRepo, fileRepo}
}

func (uc *anonymizeUserIPsImmediatelyUseCaseImpl) Execute(ctx context.Context, userID gocql.UUID) error {
	//
	// STEP 1: Validation.
	//

	e := make(map[string]string)
	if userID.String() == "" {
		e["user_id"] = "User ID is required"
	}
	if len(e) != 0 {
		uc.logger.Warn("Failed validating immediate IP anonymization",
			zap.Any("error", e))
		return httperror.NewForBadRequest(&e)
	}

	uc.logger.Info("Starting immediate IP anonymization for user (GDPR mode)",
		zap.String("user_id", userID.String()))

	//
	// STEP 2: Anonymize user metadata IPs
	//

	uc.logger.Debug("Anonymizing user metadata IPs",
		zap.String("user_id", userID.String()))

	err := uc.userRepo.AnonymizeUserIPs(ctx, userID)
	if err != nil {
		uc.logger.Error("Failed to anonymize user metadata IPs",
			zap.String("user_id", userID.String()),
			zap.Error(err))
		return err
	}

	uc.logger.Debug("✅ User metadata IPs anonymized")

	//
	// STEP 3: Anonymize collection IPs for all user's collections
	//

	uc.logger.Debug("Anonymizing collection IPs for user's collections",
		zap.String("user_id", userID.String()))

	collectionCount, err := uc.collectionRepo.AnonymizeCollectionIPsByOwner(ctx, userID)
	if err != nil {
		uc.logger.Error("Failed to anonymize collection IPs",
			zap.String("user_id", userID.String()),
			zap.Error(err))
		return err
	}

	uc.logger.Debug("✅ Collection IPs anonymized",
		zap.Int("collection_count", collectionCount))

	//
	// STEP 4: Anonymize file IPs for all user's files
	//

	uc.logger.Debug("Anonymizing file IPs for user's files",
		zap.String("user_id", userID.String()))

	fileCount, err := uc.fileRepo.AnonymizeFileIPsByOwner(ctx, userID)
	if err != nil {
		uc.logger.Error("Failed to anonymize file IPs",
			zap.String("user_id", userID.String()),
			zap.Error(err))
		return err
	}

	uc.logger.Debug("✅ File IPs anonymized",
		zap.Int("file_count", fileCount))

	//
	// SUCCESS
	//

	uc.logger.Info("✅ Successfully anonymized all IPs for user",
		zap.String("user_id", userID.String()),
		zap.Int("collections_anonymized", collectionCount),
		zap.Int("files_anonymized", fileCount))

	return nil
}
