package ngoperation

import (
	"context"
	"fmt"

	clusterng "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	opent "github.com/tidbcloud/devops/entity/operation"
	"github.com/tidbcloud/devops/pkg/service/operation/actions"
	nextgenv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
)

var (
	ActionDeletePlacementPolicy = opent.ActionMetadata{
		Name: "DeletePlacementPolicy",
		Type: opent.ActionTypeAuto,
	}
)

var _ actions.Action = &deletePlacementPolicy{}

type deletePlacementPolicy struct {
	actions.BaseAction
	comps *actions.Components
}

func NewDeletePlacementPolicy(comps *actions.Components) actions.AutoAction {
	return &deletePlacementPolicy{comps: comps}
}

func (a *deletePlacementPolicy) Metadata() opent.ActionMetadata {
	return ActionDeletePlacementPolicy
}

func (a *deletePlacementPolicy) PreCheck(ctx context.Context, instance *opent.Instance) error {
	_, _, err := a.getParam(ctx, instance)
	return err
}

func (a *deletePlacementPolicy) Start(ctx context.Context, instance *opent.Instance) (*actions.ActionResult, error) {
	req, rp, err := a.getParam(ctx, instance)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}

	logicalRegion, provider := GetLogicalRegionAndProviderString(rp.GetRegion())
	err = a.comps.MgmtHTTP.NextGenRegionServer(logicalRegion, provider).DeletePlacementPolicy(ctx, req)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}

	return actions.RunningActionResult(fmt.Sprintf("sent request to delete placement policy: %s", req.GetPlacementPolicyId()), nil), nil
}

func (a *deletePlacementPolicy) Result(ctx context.Context, instance *opent.Instance) (*actions.ActionResult, error) {
	return actions.SucceededActionResult(nil), nil
}

func (a *deletePlacementPolicy) getParam(ctx context.Context, instance *opent.Instance) (*clusterng.DeletePlacementPolicyRequest, *nextgenv1.ResourcePoolProfile, error) {
	req, err := buildDeletePlacementPolicyParam(instance)
	if err != nil {
		return nil, nil, err
	}

	rp, err := a.comps.CoreSvc.Mgmt.GetResourcePoolString(ctx, req.GetSharedPoolId())
	if err != nil {
		return nil, nil, err
	}

	return req, rp, nil
}

func buildDeletePlacementPolicyParam(instance *opent.Instance) (*clusterng.DeletePlacementPolicyRequest, error) {
	sharedPoolID, err := actions.GetResourcePoolID(instance)
	if err != nil {
		return nil, err
	}

	placementPolicyID, err := actions.GetClusterIDStr(instance)
	if err != nil {
		return nil, err
	}

	return &clusterng.DeletePlacementPolicyRequest{
		SharedPoolId:      sharedPoolID,
		PlacementPolicyId: placementPolicyID,
	}, nil
}
