package planreplayer

import (
	"context"
	"strconv"
	"time"

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

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	openapingv1beta2 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/nextgen/v1beta2"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/eventbus"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/grpc/metadata"
)

func (s *serverImpl) UpdatePlanReplayerStatus(
	ctx context.Context,
	req *openapingv1beta2.UpdatePlanReplayerStatusRequest,
) (*openapingv1beta2.PlanReplayerStatus, error) {
	ctx, span := tracer.Start(ctx, "UpdatePlanReplayerStatus")
	defer span.End()

	var (
		err     error
		reqMeta *metadata.RequestMeta
	)

	detailsFunc := func() auditlog.Details {
		details := eventbus.NewAuditLogDetails(eventbus.TierTypePremium)
		details["plan_replayer_enabled"] = req.GetPlanReplayerStatus().GetEnabled()
		if req.GetPlanReplayerStatus().GetEnabled() && req.GetPlanReplayerStatus().GetExpireTime() != nil {
			details["plan_replayer_expire_time"] = req.GetPlanReplayerStatus().GetExpireTime().AsTime().UTC().Format(time.RFC3339)
		}
		return details
	}

	defer func() {
		if !req.GetValidateOnly() {
			s.auditLogSender.SubmitAuditLogForNextgen(ctx, auditlog.EventUpdateCluster, reqMeta, detailsFunc, err)
		}
	}()

	reqMeta, err = metadata.ExtractRequestMetaWithCheckPermission(ctx)
	if err != nil {
		err = bizerr.WrapErrorWithCode(err, bizerr.ErrCodeParams, "failed to extract request metadata")
		return nil, err
	}

	tidbID, err := strconv.ParseUint(req.GetTidbId(), 10, 64)
	if err != nil {
		err = bizerr.WrapErrorWithCode(err, bizerr.ErrCodeParams, "invalid tidb id")
		return nil, err
	}

	patch := req.GetPlanReplayerStatus()
	if patch == nil {
		err = bizerr.New(bizerr.ErrCodeParams, "plan_replayer_status is required")
		return nil, err
	}

	status, err := s.nextgenCli.UpdatePlanReplayerStatus(
		ctx,
		&globalngv1.UpdatePlanReplayerStatusRequest{
			ClusterId: tidbID,
			PlanReplayerStatus: &globalngv1.PlanReplayerStatusPatch{
				Enabled:    patch.GetEnabled(),
				ExpireTime: patch.GetExpireTime(),
			},
			ValidateOnly: req.GetValidateOnly(),
		},
	)
	if err != nil {
		return nil, err
	}

	return cvtGlobalToOpenapiStatus(status), nil
}
