package serverlesssvc

import (
	"encoding/json"

	httptransport "github.com/go-openapi/runtime/client"
	"github.com/go-openapi/strfmt"
	"github.com/stretchr/testify/require"
	"github.com/stretchr/testify/suite"

	"github.com/tidbcloud/tidb-management-service/functional-test/pkg/serverlesssvc/client"
	"github.com/tidbcloud/tidb-management-service/functional-test/pkg/serverlesssvc/client/serverless_billing_service"
	"github.com/tidbcloud/tidb-management-service/functional-test/pkg/serverlesssvc/model"
)

type Cli struct {
	*client.APIsForServerlessService

	su *suite.Suite
}

func NewClient(su *suite.Suite, host, bearerToken string) (*Cli, error) {
	trans := httptransport.New(host, "", []string{"https"})
	trans.DefaultAuthentication = httptransport.BearerToken(bearerToken)
	return &Cli{su: su, APIsForServerlessService: client.New(trans, strfmt.Default)}, nil
}

func (cli *Cli) respJson(resp any) string {
	b, err := json.Marshal(resp)
	require.NoErrorf(cli.su.T(), err, "marshal error: %s", err)
	return string(b)
}

func (cli *Cli) ListOrgSpendLimits(orgID string) *model.ServerlessGetAllSpendLimitsResp {
	params := serverless_billing_service.NewGetAllSpendLimitsParams()
	params.SetOrgID(orgID)

	resp, err := cli.ServerlessBillingService.GetAllSpendLimits(params)

	require.NoError(cli.su.T(), err)
	require.Falsef(
		cli.su.T(),
		resp.Payload == nil || (resp.Payload.BaseResp != nil && resp.Payload.BaseResp.ErrCode != "0"),
		"invalid response: %s",
		cli.respJson(resp),
	)

	return resp.Payload
}

func (cli *Cli) PredictSpendLimit(orgID, region string, spendLimit int64) *model.ServerlessPredictSpendLimitResp {
	params := serverless_billing_service.NewPredictSpendLimitParams()
	params.SetOrgID(orgID)
	params.SetRegion(region)
	params.SetSpendLimit(spendLimit)

	resp, err := cli.ServerlessBillingService.PredictSpendLimit(params)

	require.NoError(cli.su.T(), err)
	require.Falsef(
		cli.su.T(),
		resp.Payload == nil || (resp.Payload.BaseResp != nil && resp.Payload.BaseResp.ErrCode != "0"),
		"invalid response: %s",
		cli.respJson(resp),
	)

	return resp.Payload
}

func (cli *Cli) GetClusterSpendLimitDetail(orgID, clusterID string) *model.ServerlessGetSpendLimitDetailsResp {
	params := serverless_billing_service.NewGetSpendLimitDetailsParams()
	params.SetOrgID(orgID)
	params.SetClusterID(clusterID)

	resp, err := cli.ServerlessBillingService.GetSpendLimitDetails(params)

	require.NoError(cli.su.T(), err)
	require.Falsef(
		cli.su.T(),
		resp.Payload == nil || (resp.Payload.BaseResp != nil && resp.Payload.BaseResp.ErrCode != "0"),
		"invalid response: %s",
		cli.respJson(resp),
	)

	return resp.Payload
}
