package byocvpcpeering

import (
	"context"

	"github.com/tidbcloud/pkgv2/db"
	"go.opentelemetry.io/otel"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/regionalserver"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	repobyocvpcpeering "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/byocvpcpeering"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/resourcepool"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/tidbgroup"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/pkg/config"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow"
)

var tracer = otel.Tracer("domain.byocvpcpeering")

type Service interface {
	ListVpcPeerings(
		ctx context.Context,
		req *globalngv1.ListVpcPeeringsRequest,
	) ([]*entity.VpcPeering, bizerr.BizError)
	GetVpcPeering(
		ctx context.Context,
		req *globalngv1.GetVpcPeeringRequest,
	) (*entity.VpcPeering, bizerr.BizError)
	GetVpcPeeringAllowlistSetting(
		ctx context.Context,
		req *globalngv1.GetVpcPeeringAllowlistSettingRequest,
	) (*entity.VpcPeeringAllowlistSetting, bizerr.BizError)
	UpdateVpcPeeringAllowlistSetting(
		ctx context.Context,
		req *globalngv1.UpdateVpcPeeringAllowlistSettingRequest,
	) (*entity.VpcPeeringAllowlistSetting, bizerr.BizError)
}

func NewService(
	cfg *config.Config,
	flow workflow.Workflow,
	transaction db.Transactioner,
	clusterRepo cluster.Repo,
	regionRepo region.Repo,
	tidbGroupRepo tidbgroup.Repo,
	repo repobyocvpcpeering.Repo,
	regionalCli regionalserver.Client,
	resourcePoolRepo resourcepool.Repo,
) (Service, error) {
	return &serviceImpl{
		cfg:              cfg,
		workflow:         flow,
		transaction:      transaction,
		clusterRepo:      clusterRepo,
		regionRepo:       regionRepo,
		tidbGroupRepo:    tidbGroupRepo,
		allowlistRepo:    repo,
		regionalCli:      regionalCli,
		resourcePoolRepo: resourcePoolRepo,
	}, nil
}

// The /byoc surface is currently the rollout boundary for these APIs.
// We intentionally keep service-plan validation out of this layer for now so
// all BYOC peering methods preserve the existing behavior consistently.
type serviceImpl struct {
	cfg              *config.Config
	workflow         workflow.Workflow
	transaction      db.Transactioner
	clusterRepo      cluster.Repo
	regionRepo       region.Repo
	tidbGroupRepo    tidbgroup.Repo
	allowlistRepo    repobyocvpcpeering.Repo
	regionalCli      regionalserver.Client
	resourcePoolRepo resourcepool.Repo
}
