package vpc

import (
	"context"
	"strconv"

	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/service/workflow/common"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/enum"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow"
)

func (s *serviceImpl) DeleteVpcPeering(
	ctx context.Context,
	req *globaldedicatedv1.DeleteVpcPeeringRequest,
) bizerr.BizError {
	ctx, span := tracer.Start(ctx, "Domain.DeleteVpcPeeringSvc")
	defer span.End()

	if req.VpcPeeringId == 0 {
		return bizerr.New(bizerr.ErrCodeParams, "vpc peering id is required")
	}

	transErr := s.transaction.Transaction(ctx, func(ctx context.Context) error {
		vpcPeering, err := s.vpcPeeringRepo.Load(ctx, req.GetCloudProvider(), req.GetVpcPeeringId())
		if err != nil {
			return err
		}

		regionName, err_ := enum.FromString[globalcommonv1.Region_Name](vpcPeering.GetTidbCloudRegion())
		if err_ != nil {
			return bizerr.WrapError(err_, "invalid region")
		}

		region, err := s.regionRepo.SelectRegionById(
			ctx,
			globalcommonv1.Region_Name(regionName),
			vpcPeering.GetOrganizationId(),
		)
		if err != nil {
			return err
		}

		if region.State != globalcommonv1.Region_ACTIVE {
			return bizerr.New(bizerr.ErrCodePermission, "region is not active")
		}

		if region.CloudProviderId != req.GetCloudProvider() {
			return bizerr.New(bizerr.ErrCodeParams, "cloud provider id not match")
		}

		if err := s.vpcPeeringRepo.Delete(ctx, vpcPeering); err != nil {
			return err
		}

		workFlowErr := s.workflow.RunDag(
			ctx,
			common.DeleteVpcPeering,
			strconv.FormatUint(vpcPeering.GetOrganizationId(), 10),
			strconv.FormatUint(vpcPeering.GetProjectId(), 10),
			map[string]string{
				workflow.KeyTraceId:         workflow.GetTraceId(ctx),
				common.KeyVpcPeeringId:      strconv.FormatUint(req.GetVpcPeeringId(), 10),
				common.KeyRegionLogicalName: region.LogicalName,
			},
		)
		if workFlowErr != nil {
			return bizerr.WrapErrorWithCode(workFlowErr, bizerr.ErrCodeUnknown, "create async workflow failed")
		}

		return nil
	})
	if transErr != nil {
		return bizerr.WrapError(transErr, "failed to delete vpc peering")
	}

	return nil
}
