package ngoperation

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"

	opent "github.com/tidbcloud/devops/entity/operation"
	"github.com/tidbcloud/devops/pkg/infra/clients/mgmthttpcli"
	"github.com/tidbcloud/devops/pkg/service/operation/actions"
)

var (
	ActionCreateChangefeedVPCPeering opent.ActionMetadata = opent.ActionMetadata{
		Name: "CreateChangefeedVPCPeering",
		Type: opent.ActionTypeAuto,
	}
)

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

func NewCreateChangefeedVPCPeering(comps *actions.Components) actions.AutoAction {
	return &createChangefeedVPCPeering{
		comps: comps,
	}
}

func (p *createChangefeedVPCPeering) Metadata() opent.ActionMetadata {
	return ActionCreateChangefeedVPCPeering
}

func (p *createChangefeedVPCPeering) PreCheck(ctx context.Context, instance *opent.Instance) error {
	_, _, _, err := p.getParam(ctx, instance)
	if err != nil {
		return err
	}

	return nil
}

func (p *createChangefeedVPCPeering) Start(ctx context.Context, instance *opent.Instance) (*actions.ActionResult, error) {
	req, cid, dataPlaneID, err := p.getParam(ctx, instance)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}
	vpcPeering, err := p.comps.MgmtHTTP.NextGen().CreateVPCPeering(ctx, cid, dataPlaneID, req)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}

	return actions.RunningActionResult(fmt.Sprintf("sent request to create vpc peering: %s", vpcPeering.ID), nil), nil
}

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

func (p *createChangefeedVPCPeering) getParam(ctx context.Context, instance *opent.Instance) (*mgmthttpcli.VPCPeering, string, string, error) {
	cidstr, err := actions.GetClusterIDStr(instance)
	if err != nil {
		return nil, "", "", err
	}

	cid, err := strconv.ParseUint(cidstr, 10, 64)
	if err != nil {
		return nil, "", "", err
	}

	cluster, err := p.comps.CoreSvc.Mgmt.GetCluster(ctx, cid)
	if err != nil {
		return nil, "", "", err
	}
	ngCluster := cluster.GetNextGenCluster()

	data := instance.Params[opent.ParamCreateVPCPeeringRequest]
	if data == "" {
		return nil, "", "", fmt.Errorf("missing required param")
	}

	req := &mgmthttpcli.VPCPeering{}
	err = json.Unmarshal([]byte(data), req)
	if err != nil {
		return nil, "", "", fmt.Errorf("unmarshal param failed: %w", err)
	}

	return req, cidstr, ngCluster.GetDataplaneId(), nil
}
