package cluster

import (
	"context"
	"strconv"
	"time"

	"github.com/tidbcloud/tiinf/sdk/auditlog"

	openapiserverlessv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/serverless/v1beta1"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/eventbus"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/pkg/apimiddleware/bizerror"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/grpc/metadata"
)

func (c serverImpl) TakeoverClusterFromPool(
	ctx context.Context,
	request *openapiserverlessv1beta1.TakeoverClusterFromPoolRequest,
) (respCluster *openapiserverlessv1beta1.Cluster, err error) {
	tenantID := unknownTenantID
	startTime := time.Now()
	defer func() {
		recordWriteClusterAPIMetrics(apiTakeoverClusterFromPool, tenantID, time.Since(startTime).Seconds(), err)
	}()

	if request.GetPoolId() == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "pool_id must not be empty")
	}

	poolID, err := strconv.ParseUint(request.GetPoolId(), 10, 64)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "invalid pool_id: %s", request.GetPoolId())
	}

	// Extract request meta - caller must be authenticated; org ID is used for pool ownership check
	reqMeta, err := metadata.ExtractRequestMetaWithCheckPermission(ctx)
	if err != nil {
		return nil, bizerr.WrapErrorWithCode(err, bizerr.ErrCodeParams, "failed to extract request metadata")
	}
	tenantID = strconv.FormatUint(reqMeta.OrgID, 10)

	detailsFunc := func() auditlog.Details {
		details := eventbus.NewAuditLogDetails(eventbus.TierTypeServerless)
		details["pool_id"] = request.GetPoolId()
		if respCluster != nil {
			details = eventbus.AppendServerlessClusterDetails(details, respCluster)
		}
		return details
	}
	defer func() {
		c.auditLogSender.SubmitAuditLog(ctx, auditlog.EventCreateCluster, reqMeta, detailsFunc, err)
	}()

	cluster, err := c.clusterSvc.TakeoverCluster(ctx, poolID, reqMeta.OrgID, request.GetRootPassword())
	if err != nil {
		return nil, err
	}

	respCluster, err = buildClusterFromEntity(cluster, nil, openapiserverlessv1beta1.ClusterView_BASIC)
	if err != nil {
		return nil, bizerror.NewInternal(err, "failed to build cluster response")
	}

	return respCluster, nil
}
