package region

import (
	"context"

	"github.com/tidbcloud/pkgv2/db"
	"google.golang.org/protobuf/types/known/emptypb"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/adapter/regionserver"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cidr"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

type Service interface {
	RegisterCloudProvider(
		ctx context.Context,
		req *globaldedicatedv1.RegisterCloudProviderRequest,
	) (*entity.CloudProvider, bizerr.BizError)
	ListCloudProviders(
		ctx context.Context,
		req *globaldedicatedv1.ListCloudProvidersRequest,
	) ([]*entity.CloudProvider, bizerr.BizError)
	RegisterRegion(ctx context.Context, req *globaldedicatedv1.RegisterRegionRequest) (*entity.Region, bizerr.BizError)
	GetRegionByLogicalName(
		ctx context.Context,
		req *globaldedicatedv1.GetRegionByLogicalNameRequest,
	) (*entity.Region, bizerr.BizError)
	SelectRegionByOrgId(
		ctx context.Context,
		req *globaldedicatedv1.SelectRegionByOrgIdRequest,
	) (*entity.Region, bizerr.BizError)
	ListRegions(ctx context.Context, req *globaldedicatedv1.ListRegionsRequest) ([]*entity.Region, bizerr.BizError)
	UpdateRegion(ctx context.Context, req *globaldedicatedv1.UpdateRegionRequest) (*entity.Region, bizerr.BizError)
	CheckRegionStatus(
		ctx context.Context,
		req *globaldedicatedv1.CheckRegionStatusRequest,
	) (*emptypb.Empty, bizerr.BizError)
	DeleteRegion(ctx context.Context, req *globaldedicatedv1.DeleteRegionRequest) (*emptypb.Empty, bizerr.BizError)
}

type service struct {
	repo            region.Repo
	cidrRepo        cidr.Repo
	clusterRepo     cluster.Repo
	regionServerCli regionserver.Client
	transaction     db.Transactioner
}

func NewService(
	repo region.Repo,
	cidrRepo cidr.Repo,
	clusterRepo cluster.Repo,
	regionServerCli regionserver.Client,
	transaction db.Transactioner,
) Service {
	return &service{
		repo:            repo,
		cidrRepo:        cidrRepo,
		clusterRepo:     clusterRepo,
		regionServerCli: regionServerCli,
		transaction:     transaction,
	}
}
