package publicconnectionsetting

import (
	"context"

	dataplanemanagerv1 "github.com/tidbcloud/cluster-service-ng/api/tidbcloud/dataplane-manager/v1"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/cluster"
	regionrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *serviceImpl) Get(
	ctx context.Context,
	req *globalngv1.GetPublicConnectionSettingRequest,
) (*entity.PublicConnectionSetting, bizerr.BizError) {
	ctx, span := tracer.Start(ctx, "PublicConnectionSettingService.Get")
	defer span.End()

	if req.ClusterId == 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster_id is required")
	}

	clusters, err := s.clusterRepo.Query(ctx, &cluster.Filter{
		ClusterIds: []uint64{req.ClusterId},
	})
	if err != nil {
		return nil, err
	}

	if len(clusters) == 0 {
		return nil, bizerr.New(bizerr.ErrCodeRecordNotFound, "cluster not found")
	}

	c := clusters[0]

	settings, err := s.publicConnectionSettingRepo.LoadByClusterId(ctx, c.ClusterId)
	if err != nil {
		return nil, err
	}

	if len(settings) == 0 {
		return nil, bizerr.New(bizerr.ErrCodeRecordNotFound, "public connection setting not found")
	}

	if err := s.fullEgressIPs(ctx, c, settings[0]); err != nil {
		return nil, err
	}

	return settings[0], nil
}

func (s *serviceImpl) fullEgressIPs(
	ctx context.Context,
	clusterEntity *entity.Cluster,
	setting *entity.PublicConnectionSetting,
) bizerr.BizError {
	if clusterEntity == nil || setting == nil || setting.PublicConnectionSetting == nil || clusterEntity.GetDataplaneId() == "" {
		return nil
	}
	if !setting.GetEnable() {
		setting.EgressIps = nil
		return nil
	}

	regions, err := s.regionRepo.ListRegions(ctx, regionrepo.Filter{DBRegionIds: []uint64{clusterEntity.RegionId}})
	if err != nil {
		return bizerr.WrapError(err, "failed to list regions")
	}
	if len(regions) == 0 {
		return bizerr.New(bizerr.ErrCodeRecordNotFound, "region not found for cluster")
	}

	dataplane, err := s.regionalCli.GetDataPlane(ctx, regions[0], &dataplanemanagerv1.GetDataPlaneRequest{
		DataPlaneId: clusterEntity.GetDataplaneId(),
	})
	if err != nil {
		return err
	}

	setting.EgressIps = append([]string(nil), dataplane.GetVpc().GetNatIps()...)
	return nil
}
