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"
)

// RecalculateAllFileCounts recalculates the file_count for all collections
// by counting active files in each collection. This is useful for fixing
// collections that were created before file count tracking was implemented.
func (impl *collectionRepositoryImpl) RecalculateAllFileCounts(ctx context.Context) (*dom_collection.RecalculateAllFileCountsResult, error) {
	impl.Logger.Info("Starting recalculation of all collection file counts")

	result := &dom_collection.RecalculateAllFileCountsResult{}

	// Get all collection IDs
	query := `SELECT id FROM maplefile.collections_by_id`
	iter := impl.Session.Query(query).WithContext(ctx).Iter()

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

	if err := iter.Close(); err != nil {
		return nil, fmt.Errorf("failed to get collection IDs: %w", err)
	}

	result.TotalCollections = len(collectionIDs)
	impl.Logger.Info("Found collections to process",
		zap.Int("count", result.TotalCollections))

	// For each collection, count active files and update
	for _, colID := range collectionIDs {
		// Count active files in this collection
		countQuery := `SELECT COUNT(*) FROM maplefile.files_by_collection WHERE collection_id = ? AND state = 'active' ALLOW FILTERING`
		var fileCount int64
		if err := impl.Session.Query(countQuery, colID).WithContext(ctx).Scan(&fileCount); err != nil {
			impl.Logger.Error("Failed to count files for collection",
				zap.String("collection_id", colID.String()),
				zap.Error(err))
			result.ErrorCount++
			continue
		}

		// Update the collection's file_count
		updateQuery := `UPDATE maplefile.collections_by_id SET file_count = ? WHERE id = ?`
		if err := impl.Session.Query(updateQuery, fileCount, colID).WithContext(ctx).Exec(); err != nil {
			impl.Logger.Error("Failed to update file count for collection",
				zap.String("collection_id", colID.String()),
				zap.Int64("file_count", fileCount),
				zap.Error(err))
			result.ErrorCount++
			continue
		}

		result.UpdatedCount++
		impl.Logger.Debug("Updated file count for collection",
			zap.String("collection_id", colID.String()),
			zap.Int64("file_count", fileCount))
	}

	impl.Logger.Info("Completed recalculation of all collection file counts",
		zap.Int("total", result.TotalCollections),
		zap.Int("updated", result.UpdatedCount),
		zap.Int("errors", result.ErrorCount))

	return result, nil
}
