package mgmtportalaction

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	mgmtportal_ent "github.com/tidbcloud/devops/entity/mgmtportal"
	opent "github.com/tidbcloud/devops/entity/operation"
	"github.com/tidbcloud/devops/pkg/service/operation/actions"
)

var (
	ActionPatchSku opent.ActionMetadata = opent.ActionMetadata{
		Name: "PatchSku",
		Type: opent.ActionTypeAuto,
	}
)

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

func NewPatchSku(comps *actions.Components) actions.AutoAction {
	return &patchSku{
		comps: comps,
	}
}

func (p *patchSku) Metadata() opent.ActionMetadata {
	return ActionPatchSku
}

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

	return nil
}

func (p *patchSku) Start(ctx context.Context, instance *opent.Instance) (*actions.ActionResult, error) {
	req, err := p.getParam(instance)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}
	httpReq, err := http.NewRequest(req.Method, req.URL, bytes.NewReader([]byte(req.Body)))
	if err != nil {
		return actions.FailedActionResult(err), nil
	}

	for k, v := range req.Headers {
		httpReq.Header[k] = v
	}

	client := &http.Client{}
	resp, err := client.Do(httpReq)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}
	defer resp.Body.Close()
	if resp.StatusCode > 300 {
		return actions.FailedActionResult(fmt.Errorf("%s", resp.Status)), nil
	}

	return actions.SucceededActionResult(nil), nil // return succeeded directly
}

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

func (p *patchSku) getParam(instance *opent.Instance) (*mgmtportal_ent.StoredRequest, error) {
	body, _ := instance.GetParam(opent.ParamPatchSkuBody)
	bodyStruct := &mgmtportal_ent.StoredRequest{}
	err := json.Unmarshal([]byte(body), bodyStruct)
	if err != nil {
		return nil, err
	}
	return bodyStruct, nil
}
