package tenantaction

import (
	"context"
	"strconv"

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

var (
	ActionUpdateTenant opent.ActionMetadata = opent.ActionMetadata{
		Name:             "UpdateTenant",
		Type:             opent.ActionTypeAuto,
		AllowAnyoneApply: true,
	}
)

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

func NewUpdateTenant(comps *actions.Components) actions.AutoAction {
	return &updateTenant{comps: comps}
}

func (a *updateTenant) Metadata() opent.ActionMetadata {
	return ActionUpdateTenant
}

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

	id, err := strconv.ParseUint(oid, 10, 64)
	if err != nil {
		return err
	}

	_, err = a.comps.TenantAPI.GetTenant(ctx, id)
	if err != nil {
		return err
	}
	return nil
}

func (a *updateTenant) Start(ctx context.Context, instance *opent.Instance) (*actions.ActionResult, error) {
	req, oid, err := a.getParam(instance)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}
	err = a.comps.TenantAPI.UpdateTenant(ctx, req, oid, instance.Applicant)
	if err != nil {
		return actions.FailedActionResult(err), nil
	}

	return actions.SucceededActionResult(nil), nil
}

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

func (a *updateTenant) getParam(instance *opent.Instance) (*accountcli.UpdateTenantReq, string, error) {
	oid, err := actions.GetTenantIDStr(instance)
	if err != nil {
		return nil, "", err
	}
	p := &accountcli.UpdateTenantReq{}

	email, _ := instance.GetParam(opent.ParamTenantEmail)
	if len(email) > 0 {
		p.Email = &email
	}

	status, _ := instance.GetParam(opent.ParamTenantStatus)
	if len(status) > 0 {
		p.Status = &status
	}

	orgType, _ := instance.GetParam(opent.ParamTenantType)
	if len(orgType) > 0 {
		p.OrgType = &orgType
	}
	return p, oid, nil
}
