package cluster

import (
	"context"
	"fmt"

	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/repository"
)

func (svc *service) CountClusters(ctx context.Context, filter *repository.ClusterFilter) (int64, error) {
	ctx, span := tracer.Start(ctx, "ClusterService.CountClusters")
	defer span.End()

	if filter == nil {
		filter = &repository.ClusterFilter{
			View:       entity.ClusterViewClusterViewBasic,
			DeployType: entity.DeployTypeNextGen,
		}
	}

	// make sure deploy type is dedicated
	filter.DeployType = entity.DeployTypeNextGen
	if hasClusterStateFilter(filter) && filter.View != entity.ClusterViewClusterViewLocal {
		return svc.countClustersWithStateFilter(ctx, filter)
	}

	count, err := svc.clusterRepo.CountClusterByFilter(ctx, filter)
	if err != nil {
		return 0, fmt.Errorf("failed to count clusters: %w", err)
	}

	return count, nil
}

func (svc *service) countClustersWithStateFilter(
	ctx context.Context,
	filter *repository.ClusterFilter,
) (int64, error) {
	var count int64
	for queryOffset := 0; ; queryOffset += stateFilterBatchSize {
		baseClusters, err := svc.clusterRepo.QueryClusterByFilterAndPage(
			ctx,
			filter,
			queryOffset,
			stateFilterBatchSize,
		)
		if err != nil {
			return 0, fmt.Errorf("failed to query clusters for state count: %w", err)
		}
		if len(baseClusters) == 0 {
			return count, nil
		}

		matchedClusters, err := svc.enrichNextGenClusterBatch(ctx, filter, baseClusters, true, false)
		if err != nil {
			return 0, fmt.Errorf("failed to count clusters after global state filtering: %w", err)
		}
		count += int64(len(matchedClusters))
		if len(baseClusters) < stateFilterBatchSize {
			return count, nil
		}
	}
}
