package vpc

import (
	"context"

	"github.com/tidbcloud/pkgv2/db"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/adapter/account"
	"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"
	clusterrepo "github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/endpoint"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/idgenerator"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow"
)

type Service interface {
	// vpc
	ListVpcs(
		ctx context.Context,
		req *globaldedicatedv1.ListVpcsRequest,
	) (*globaldedicatedv1.ListVpcsResponse, bizerr.BizError)
	DeleteVpc(ctx context.Context, req *globaldedicatedv1.DeleteVpcRequest) bizerr.BizError

	// vpc peering
	ListVpcPeerings(
		ctx context.Context,
		req *globaldedicatedv1.ListVpcPeeringsRequest,
	) (*globaldedicatedv1.ListVpcPeeringsResponse, bizerr.BizError)
	DeleteVpcPeering(ctx context.Context, req *globaldedicatedv1.DeleteVpcPeeringRequest) bizerr.BizError
	CreateVpcPeering(ctx context.Context, req *globaldedicatedv1.VpcPeering) (*entity.VpcPeering, bizerr.BizError)
	GetVpcPeering(
		ctx context.Context,
		cloudProvider globalcommonv1.CloudProvider_Name,
		peeringID uint64,
	) (*entity.VpcPeering, bizerr.BizError)

	QueryCidrs(
		ctx context.Context,
		request *globaldedicatedv1.QueryCidrsRequest,
	) ([]*globaldedicatedv1.Cidr, bizerr.BizError)
	GetDefaultCidr(
		ctx context.Context,
		request *globaldedicatedv1.GetDefaultCidrRequest,
	) (*globaldedicatedv1.GetDefaultCidrResponse_DefaultCidr, bizerr.BizError)
	CreateCidr(
		ctx context.Context,
		req *globaldedicatedv1.CreateCidrRequest,
	) (*entity.CIDR, *ValidateOnlyResponse, bizerr.BizError)

	AddSecondaryCidr(
		ctx context.Context,
		req *globaldedicatedv1.AddSecondaryCidrRequest,
	) (*globaldedicatedv1.Vpc, bizerr.BizError)
}

type serviceImpl struct {
	regionRepo      region.Repo
	clusterRepo     clusterrepo.Repo
	vpcPeeringRepo  endpoint.VpcPeeringRepo
	cidrRepo        cidr.Repo
	accountCli      account.Client
	regionServerCli regionserver.Client

	workflow    workflow.Workflow
	transaction db.Transactioner

	idGeneratorFacade idgenerator.IDGenerator
	helper            Helper
}

func NewService(
	regionRepo region.Repo,
	clusterRepo clusterrepo.Repo,
	vpcPeeringRepo endpoint.VpcPeeringRepo,
	cidrRepo cidr.Repo,
	accountCli account.Client,
	regionServerCli regionserver.Client,
	flow workflow.Workflow,
	transaction db.Transactioner,
	idGeneratorFacade idgenerator.IDGenerator,
	helper Helper,
) Service {
	return &serviceImpl{
		regionRepo:        regionRepo,
		clusterRepo:       clusterRepo,
		vpcPeeringRepo:    vpcPeeringRepo,
		cidrRepo:          cidrRepo,
		accountCli:        accountCli,
		regionServerCli:   regionServerCli,
		workflow:          flow,
		transaction:       transaction,
		idGeneratorFacade: idGeneratorFacade,
		helper:            helper,
	}
}
