// monorepo/cloud/maplefile-backend/internal/maplefile/repo/collection/list_by_tag_id.go
package collection

import (
	"context"
	"fmt"

	"github.com/gocql/gocql"
	dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection"
	"go.uber.org/zap"
)

// ListByTagID retrieves all collections that have the specified tag assigned
// Uses the denormalized collections_by_tag_id table for efficient lookups
func (impl *collectionRepositoryImpl) ListByTagID(ctx context.Context, tagID gocql.UUID) ([]*dom_collection.Collection, error) {
	impl.Logger.Info("🏷️  REPO: Listing collections by tag ID",
		zap.String("tag_id", tagID.String()))

	var collectionIDs []gocql.UUID

	// Query the denormalized table
	query := `SELECT collection_id FROM collections_by_tag_id WHERE tag_id = ?`

	iter := impl.Session.Query(query, tagID).WithContext(ctx).Iter()

	var collectionID gocql.UUID
	for iter.Scan(&collectionID) {
		collectionIDs = append(collectionIDs, collectionID)
	}

	if err := iter.Close(); err != nil {
		impl.Logger.Error("🏷️  REPO: Failed to query collections by tag",
			zap.String("tag_id", tagID.String()),
			zap.Error(err))
		return nil, fmt.Errorf("failed to list collections by tag: %w", err)
	}

	impl.Logger.Info("🏷️  REPO: Found collection IDs for tag",
		zap.String("tag_id", tagID.String()),
		zap.Int("count", len(collectionIDs)))

	// Load full collection details with members
	collections, err := impl.loadMultipleCollectionsWithMembers(ctx, collectionIDs)
	if err != nil {
		impl.Logger.Error("🏷️  REPO: Failed to load collections",
			zap.String("tag_id", tagID.String()),
			zap.Error(err))
		return nil, err
	}

	// Filter to only active collections
	var activeCollections []*dom_collection.Collection
	for _, collection := range collections {
		if collection.State == dom_collection.CollectionStateActive {
			activeCollections = append(activeCollections, collection)
		}
	}

	impl.Logger.Info("🏷️  REPO: Successfully loaded collections by tag",
		zap.String("tag_id", tagID.String()),
		zap.Int("total_found", len(collections)),
		zap.Int("active_count", len(activeCollections)))

	return activeCollections, nil
}
