package cluster

import (
	"context"
	"strconv"

	clusterngv1beta "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	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/utilities/bizerr"
)

func (s *serviceImpl) GetProviderRole(
	ctx context.Context,
	req *globalngv1.GetProviderRoleRequest,
) (*entity.ProviderRole, bizerr.BizError) {
	ctx, span := tracer.Start(ctx, "Domain.GetProviderRole")
	defer span.End()

	if req.ClusterId == 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster_id is required")
	}
	cluster, err := s.clusterRepo.Get(ctx, req.ClusterId, false)
	if err != nil {
		return nil, err
	}
	if cluster == nil {
		tilog.Warn(ctx, "cluster not found", zap.Uint64("cluster_id", req.ClusterId))
		return nil, bizerr.New(bizerr.ErrCodeRecordNotFound, "cluster not found")
	}

	region, err := s.regionRepo.Get(ctx, cluster.RegionId)
	if err != nil {
		return nil, err
	}

	providerRole, err := s.regionalCli.GetProviderRole(ctx, region, &clusterngv1beta.GetProviderRoleRequest{
		ClusterId: strconv.FormatUint(cluster.ClusterId, 10),
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "failed to get provider role: %v", err)
	}

	if providerRole == nil {
		return nil, bizerr.New(
			bizerr.ErrCodeRecordNotFound,
			"provider role not found for cluster ID: %d",
			req.ClusterId,
		)
	}

	return &entity.ProviderRole{
		CloudIamIdentity: providerRole.GetCloudIamIdentity(),
		NodeRole:         providerRole.GetNodeRole(),
		ExternalId:       providerRole.GetExternalId(),
	}, nil
}
