// Code generated by "requestgen -method POST -responseType .APIResponse -responseDataField Data -url /api/v1/orders -type PlaceOrderRequest -responseDataType .OrderResponse"; DO NOT EDIT.

package kucoinapi

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/google/uuid"
	"net/url"
	"regexp"
)

func (r *PlaceOrderRequest) ClientOrderID(clientOrderID string) *PlaceOrderRequest {
	r.clientOrderID = &clientOrderID
	return r
}

func (r *PlaceOrderRequest) Symbol(symbol string) *PlaceOrderRequest {
	r.symbol = symbol
	return r
}

func (r *PlaceOrderRequest) Tag(tag string) *PlaceOrderRequest {
	r.tag = &tag
	return r
}

func (r *PlaceOrderRequest) Side(side SideType) *PlaceOrderRequest {
	r.side = side
	return r
}

func (r *PlaceOrderRequest) OrderType(orderType OrderType) *PlaceOrderRequest {
	r.orderType = orderType
	return r
}

func (r *PlaceOrderRequest) Size(size string) *PlaceOrderRequest {
	r.size = size
	return r
}

func (r *PlaceOrderRequest) Price(price string) *PlaceOrderRequest {
	r.price = &price
	return r
}

func (r *PlaceOrderRequest) TimeInForce(timeInForce TimeInForceType) *PlaceOrderRequest {
	r.timeInForce = &timeInForce
	return r
}

func (r *PlaceOrderRequest) PostOnly(postOnly bool) *PlaceOrderRequest {
	r.postOnly = &postOnly
	return r
}

// GetQueryParameters builds and checks the query parameters and returns url.Values
func (r *PlaceOrderRequest) GetQueryParameters() (url.Values, error) {
	var params = map[string]interface{}{}

	query := url.Values{}
	for k, v := range params {
		query.Add(k, fmt.Sprintf("%v", v))
	}

	return query, nil
}

// GetParameters builds and checks the parameters and return the result in a map object
func (r *PlaceOrderRequest) GetParameters() (map[string]interface{}, error) {
	var params = map[string]interface{}{}
	// check clientOrderID field -> json key clientOid
	if r.clientOrderID != nil {
		clientOrderID := *r.clientOrderID

		// TEMPLATE check-required
		if len(clientOrderID) == 0 {
			return nil, fmt.Errorf("clientOid is required, empty string given")
		}
		// END TEMPLATE check-required

		// assign parameter of clientOrderID
		params["clientOid"] = clientOrderID
	} else {
		// assign default of clientOrderID
		clientOrderID := uuid.New().String()
		// assign parameter of clientOrderID
		params["clientOid"] = clientOrderID
	}
	// check symbol field -> json key symbol
	symbol := r.symbol

	// TEMPLATE check-required
	if len(symbol) == 0 {
		return nil, fmt.Errorf("symbol is required, empty string given")
	}
	// END TEMPLATE check-required

	// assign parameter of symbol
	params["symbol"] = symbol
	// check tag field -> json key tag
	if r.tag != nil {
		tag := *r.tag

		// assign parameter of tag
		params["tag"] = tag
	} else {
	}
	// check side field -> json key side
	side := r.side

	// assign parameter of side
	params["side"] = side
	// check orderType field -> json key ordType
	orderType := r.orderType

	// assign parameter of orderType
	params["ordType"] = orderType
	// check size field -> json key size
	size := r.size

	// TEMPLATE check-required
	if len(size) == 0 {
		return nil, fmt.Errorf("size is required, empty string given")
	}
	// END TEMPLATE check-required

	// assign parameter of size
	params["size"] = size
	// check price field -> json key price
	if r.price != nil {
		price := *r.price

		// assign parameter of price
		params["price"] = price
	} else {
	}
	// check timeInForce field -> json key timeInForce
	if r.timeInForce != nil {
		timeInForce := *r.timeInForce

		// TEMPLATE check-required
		if len(timeInForce) == 0 {
			return nil, fmt.Errorf("timeInForce is required, empty string given")
		}
		// END TEMPLATE check-required

		// assign parameter of timeInForce
		params["timeInForce"] = timeInForce
	} else {
	}
	// check postOnly field -> json key postOnly
	if r.postOnly != nil {
		postOnly := *r.postOnly

		// assign parameter of postOnly
		params["postOnly"] = postOnly
	} else {
	}

	return params, nil
}

// GetParametersQuery converts the parameters from GetParameters into the url.Values format
func (r *PlaceOrderRequest) GetParametersQuery() (url.Values, error) {
	query := url.Values{}

	params, err := r.GetParameters()
	if err != nil {
		return query, err
	}

	for k, v := range params {
		query.Add(k, fmt.Sprintf("%v", v))
	}

	return query, nil
}

// GetParametersJSON converts the parameters from GetParameters into the JSON format
func (r *PlaceOrderRequest) GetParametersJSON() ([]byte, error) {
	params, err := r.GetParameters()
	if err != nil {
		return nil, err
	}

	return json.Marshal(params)
}

// GetSlugParameters builds and checks the slug parameters and return the result in a map object
func (r *PlaceOrderRequest) GetSlugParameters() (map[string]interface{}, error) {
	var params = map[string]interface{}{}

	return params, nil
}

func (r *PlaceOrderRequest) applySlugsToUrl(url string, slugs map[string]string) string {
	for k, v := range slugs {
		needleRE := regexp.MustCompile(":" + k + "\\b")
		url = needleRE.ReplaceAllString(url, v)
	}

	return url
}

func (r *PlaceOrderRequest) GetSlugsMap() (map[string]string, error) {
	slugs := map[string]string{}
	params, err := r.GetSlugParameters()
	if err != nil {
		return slugs, nil
	}

	for k, v := range params {
		slugs[k] = fmt.Sprintf("%v", v)
	}

	return slugs, nil
}

func (r *PlaceOrderRequest) Do(ctx context.Context) (*OrderResponse, error) {

	params, err := r.GetParameters()
	if err != nil {
		return nil, err
	}
	query := url.Values{}

	apiURL := "/api/v1/orders"

	req, err := r.client.NewAuthenticatedRequest(ctx, "POST", apiURL, query, params)
	if err != nil {
		return nil, err
	}

	response, err := r.client.SendRequest(req)
	if err != nil {
		return nil, err
	}

	var apiResponse APIResponse
	if err := response.DecodeJSON(&apiResponse); err != nil {
		return nil, err
	}
	var data OrderResponse
	if err := json.Unmarshal(apiResponse.Data, &data); err != nil {
		return nil, err
	}
	return &data, nil
}
