package cluster

import (
	"context"

	openapiserverlessv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/serverless/v1beta1"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/account"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/eventbus"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/service/customstatus"
	clustersvc "github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/service/serverless/cluster"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/pkg/config"
)

type Server interface {
	CreateCluster(
		ctx context.Context,
		req *openapiserverlessv1beta1.CreateClusterRequest,
	) (*openapiserverlessv1beta1.Cluster, error)
	ListClusters(
		ctx context.Context,
		req *openapiserverlessv1beta1.ListClustersRequest,
	) (*openapiserverlessv1beta1.ListClustersResponse, error)
	GetCluster(
		ctx context.Context,
		req *openapiserverlessv1beta1.GetClusterRequest,
	) (*openapiserverlessv1beta1.Cluster, error)
	BindTags(
		ctx context.Context,
		req *openapiserverlessv1beta1.BindTagsRequest,
	) (*openapiserverlessv1beta1.BindTagsResponse, error)
	UnbindTags(
		ctx context.Context,
		req *openapiserverlessv1beta1.UnbindTagsRequest,
	) (*openapiserverlessv1beta1.UnbindTagsResponse, error)
	DeleteCluster(
		ctx context.Context,
		req *openapiserverlessv1beta1.DeleteClusterRequest,
	) (*openapiserverlessv1beta1.Cluster, error)
	UpdateCluster(
		ctx context.Context,
		req *openapiserverlessv1beta1.PartialUpdateClusterRequest,
	) (*openapiserverlessv1beta1.Cluster, error)
	BatchCreateClusters(
		ctx context.Context,
		request *openapiserverlessv1beta1.BatchCreateClustersRequest,
	) (*openapiserverlessv1beta1.BatchCreateClustersResponse, error)
	BatchGetClusters(
		ctx context.Context,
		request *openapiserverlessv1beta1.BatchGetClustersRequest,
	) (*openapiserverlessv1beta1.BatchGetClustersResponse, error)
	BatchDeleteClusters(
		ctx context.Context,
		request *openapiserverlessv1beta1.BatchDeleteClustersRequest,
	) (*openapiserverlessv1beta1.BatchDeleteClustersResponse, error)
	ClaimClusterFromZero(
		ctx context.Context,
		request *openapiserverlessv1beta1.ClaimClusterFromZeroRequest,
	) (*openapiserverlessv1beta1.Cluster, error)
	TakeoverClusterFromPool(
		ctx context.Context,
		request *openapiserverlessv1beta1.TakeoverClusterFromPoolRequest,
	) (*openapiserverlessv1beta1.Cluster, error)
}

func NewServer(
	clusterSvc clustersvc.Service,
	customStatusSvc customstatus.Service,
	auditLogSender eventbus.ConsoleAuditLogSender,
	accountCli account.Client,
	oneConsoleConfig *config.OneConsoleConfig,
) Server {
	return &serverImpl{
		clusterSvc:       clusterSvc,
		customStatusSvc:  customStatusSvc,
		auditLogSender:   auditLogSender,
		accountCli:       accountCli,
		oneConsoleConfig: oneConsoleConfig,
	}
}

type serverImpl struct {
	clusterSvc      clustersvc.Service
	customStatusSvc customstatus.Service
	auditLogSender  eventbus.ConsoleAuditLogSender
	// accountCli is used to validate project types when CheckXProjectType is enabled.
	accountCli account.Client
	// oneConsoleConfig holds the OneConsole feature flags. May be nil if not configured.
	oneConsoleConfig *config.OneConsoleConfig
}
