// Package api provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
package api

import (
	"context"
	"fmt"
	"net/http"

	"github.com/deepmap/oapi-codegen/pkg/runtime"
	"github.com/go-chi/chi/v5"
)

const (
	BearerAuthScopes = "BearerAuth.Scopes"
)

// Defines values for ExportASNToFileParamsFormat.
const (
	Csv ExportASNToFileParamsFormat = "csv"
)

// Response defines model for Response.
type Response struct {
	Error   *map[string]interface{} `json:"error,omitempty"`
	Result  interface{}             `json:"result"`
	Success bool                    `json:"success"`
}

// ResponseUpdate defines model for ResponseUpdate.
type ResponseUpdate = interface{}

// RestError defines model for RestError.
type RestError struct {
	Message    *string `json:"message,omitempty"`
	StatusText *string `json:"status_text,omitempty"`
	Success    *bool   `json:"success,omitempty"`
}

// BidID defines model for BidID.
type BidID = string

// OrderReference defines model for OrderReference.
type OrderReference = string

// PostSaleOrdersRestResponse defines model for PostSaleOrdersRestResponse.
type PostSaleOrdersRestResponse = Response

// PostUpdateSaleOrdersRestResponse defines model for PostUpdateSaleOrdersRestResponse.
type PostUpdateSaleOrdersRestResponse = ResponseUpdate

// PutBidAwardWinnerResponse defines model for PutBidAwardWinnerResponse.
type PutBidAwardWinnerResponse = Response

// UpdateSaleOrderMultipartBody defines parameters for UpdateSaleOrder.
type UpdateSaleOrderMultipartBody struct {
	Method           *string `json:"_method,omitempty"`
	Types            *string `json:"_types,omitempty"`
	CollectDate      *string `json:"collect_date,omitempty"`
	CourierName      *string `json:"courier_name,omitempty"`
	DocTypeID        *uint32 `json:"doc_type_id,omitempty"`
	Document         *string `json:"document,omitempty"`
	IncotermID       *uint64 `json:"incoterm_id,omitempty"`
	NoAirbill        *int    `json:"no_airbill,omitempty" validate:"min=0,max=1"`
	Note             *string `json:"note,omitempty"`
	PaymentOverdue   *uint64 `json:"payment_overdue,omitempty" validate:"min=0,max=1"`
	ShippedDate      *string `json:"shipped_date,omitempty"`
	ShippingMethodID *uint64 `json:"shipping_method_id,omitempty"`
	SKUReleaseTime   *string `json:"sku_release_time,omitempty"`
	Status           *uint32 `json:"status,omitempty"`
	TrackingCode     *string `json:"tracking_code,omitempty"`
	TrackingURL      *string `json:"tracking_url,omitempty"`
	Type             *string `json:"type,omitempty"`
}

// ExportASNToFileParams defines parameters for ExportASNToFile.
type ExportASNToFileParams struct {
	// Format The desired file format (e.g., csv)
	Format ExportASNToFileParamsFormat `form:"format" json:"format"`
}

// ExportASNToFileParamsFormat defines parameters for ExportASNToFile.
type ExportASNToFileParamsFormat string

// UpdateSaleOrderMultipartRequestBody defines body for UpdateSaleOrder for multipart/form-data ContentType.
type UpdateSaleOrderMultipartRequestBody UpdateSaleOrderMultipartBody

// ServerInterface represents all server handlers.
type ServerInterface interface {
	// award  winner
	// (PUT /bids/{bid_id}/winner)
	CreateFromAuction(w http.ResponseWriter, r *http.Request, bidID BidID)
	// Create new sale Orders from Cart
	// (POST /sale-orders)
	CreateFromCart(w http.ResponseWriter, r *http.Request)
	// Get Sale Order Summary
	// (GET /sale-orders/summary)
	GetSOSummary(w http.ResponseWriter, r *http.Request)
	// update sale Orders adding documents/ updating status
	// (POST /sale-orders/{order_reference})
	UpdateSaleOrder(w http.ResponseWriter, r *http.Request, orderReference OrderReference)
	// Export ASN data into a file in the specified format
	// (GET /sale-orders/{order_reference}/asn/export)
	ExportASNToFile(w http.ResponseWriter, r *http.Request, orderReference OrderReference, params ExportASNToFileParams)
}

// ServerInterfaceWrapper converts contexts to parameters.
type ServerInterfaceWrapper struct {
	Handler            ServerInterface
	HandlerMiddlewares []MiddlewareFunc
	ErrorHandlerFunc   func(w http.ResponseWriter, r *http.Request, err error)
}

type MiddlewareFunc func(http.Handler) http.Handler

// CreateFromAuction operation middleware
func (siw *ServerInterfaceWrapper) CreateFromAuction(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var err error

	// ------------- Path parameter "bid_id" -------------
	var bidID BidID

	err = runtime.BindStyledParameterWithLocation("simple", false, "bid_id", runtime.ParamLocationPath, chi.URLParam(r, "bid_id"), &bidID)
	if err != nil {
		siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "bid_id", Err: err})
		return
	}

	ctx = context.WithValue(ctx, BearerAuthScopes, []string{""})

	var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.CreateFromAuction(w, r, bidID)
	})

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler.ServeHTTP(w, r.WithContext(ctx))
}

// CreateFromCart operation middleware
func (siw *ServerInterfaceWrapper) CreateFromCart(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	ctx = context.WithValue(ctx, BearerAuthScopes, []string{""})

	var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.CreateFromCart(w, r)
	})

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler.ServeHTTP(w, r.WithContext(ctx))
}

// GetSOSummary operation middleware
func (siw *ServerInterfaceWrapper) GetSOSummary(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	ctx = context.WithValue(ctx, BearerAuthScopes, []string{""})

	var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.GetSOSummary(w, r)
	})

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler.ServeHTTP(w, r.WithContext(ctx))
}

// UpdateSaleOrder operation middleware
func (siw *ServerInterfaceWrapper) UpdateSaleOrder(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var err error

	// ------------- Path parameter "order_reference" -------------
	var orderReference OrderReference

	err = runtime.BindStyledParameterWithLocation("simple", false, "order_reference", runtime.ParamLocationPath, chi.URLParam(r, "order_reference"), &orderReference)
	if err != nil {
		siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "order_reference", Err: err})
		return
	}

	ctx = context.WithValue(ctx, BearerAuthScopes, []string{""})

	var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.UpdateSaleOrder(w, r, orderReference)
	})

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler.ServeHTTP(w, r.WithContext(ctx))
}

// ExportASNToFile operation middleware
func (siw *ServerInterfaceWrapper) ExportASNToFile(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	var err error

	// ------------- Path parameter "order_reference" -------------
	var orderReference OrderReference

	err = runtime.BindStyledParameterWithLocation("simple", false, "order_reference", runtime.ParamLocationPath, chi.URLParam(r, "order_reference"), &orderReference)
	if err != nil {
		siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "order_reference", Err: err})
		return
	}

	ctx = context.WithValue(ctx, BearerAuthScopes, []string{""})

	// Parameter object where we will unmarshal all parameters from the context
	var params ExportASNToFileParams

	// ------------- Required query parameter "format" -------------

	if paramValue := r.URL.Query().Get("format"); paramValue != "" {

	} else {
		siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "format"})
		return
	}

	err = runtime.BindQueryParameter("form", true, true, "format", r.URL.Query(), &params.Format)
	if err != nil {
		siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "format", Err: err})
		return
	}

	var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		siw.Handler.ExportASNToFile(w, r, orderReference, params)
	})

	for _, middleware := range siw.HandlerMiddlewares {
		handler = middleware(handler)
	}

	handler.ServeHTTP(w, r.WithContext(ctx))
}

type UnescapedCookieParamError struct {
	ParamName string
	Err       error
}

func (e *UnescapedCookieParamError) Error() string {
	return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName)
}

func (e *UnescapedCookieParamError) Unwrap() error {
	return e.Err
}

type UnmarshallingParamError struct {
	ParamName string
	Err       error
}

func (e *UnmarshallingParamError) Error() string {
	return fmt.Sprintf("Error unmarshalling parameter %s as JSON: %s", e.ParamName, e.Err.Error())
}

func (e *UnmarshallingParamError) Unwrap() error {
	return e.Err
}

type RequiredParamError struct {
	ParamName string
}

func (e *RequiredParamError) Error() string {
	return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName)
}

type RequiredHeaderError struct {
	ParamName string
	Err       error
}

func (e *RequiredHeaderError) Error() string {
	return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName)
}

func (e *RequiredHeaderError) Unwrap() error {
	return e.Err
}

type InvalidParamFormatError struct {
	ParamName string
	Err       error
}

func (e *InvalidParamFormatError) Error() string {
	return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error())
}

func (e *InvalidParamFormatError) Unwrap() error {
	return e.Err
}

type TooManyValuesForParamError struct {
	ParamName string
	Count     int
}

func (e *TooManyValuesForParamError) Error() string {
	return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count)
}

// Handler creates http.Handler with routing matching OpenAPI spec.
func Handler(si ServerInterface) http.Handler {
	return HandlerWithOptions(si, ChiServerOptions{})
}

type ChiServerOptions struct {
	BaseURL          string
	BaseRouter       chi.Router
	Middlewares      []MiddlewareFunc
	ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)
}

// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.
func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler {
	return HandlerWithOptions(si, ChiServerOptions{
		BaseRouter: r,
	})
}

func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler {
	return HandlerWithOptions(si, ChiServerOptions{
		BaseURL:    baseURL,
		BaseRouter: r,
	})
}

// HandlerWithOptions creates http.Handler with additional options
func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler {
	r := options.BaseRouter

	if r == nil {
		r = chi.NewRouter()
	}
	if options.ErrorHandlerFunc == nil {
		options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) {
			http.Error(w, err.Error(), http.StatusBadRequest)
		}
	}
	wrapper := ServerInterfaceWrapper{
		Handler:            si,
		HandlerMiddlewares: options.Middlewares,
		ErrorHandlerFunc:   options.ErrorHandlerFunc,
	}

	r.Group(func(r chi.Router) {
		r.Put(options.BaseURL+"/bids/{bid_id}/winner", wrapper.CreateFromAuction)
	})
	r.Group(func(r chi.Router) {
		r.Post(options.BaseURL+"/sale-orders", wrapper.CreateFromCart)
	})
	r.Group(func(r chi.Router) {
		r.Get(options.BaseURL+"/sale-orders/summary", wrapper.GetSOSummary)
	})
	r.Group(func(r chi.Router) {
		r.Post(options.BaseURL+"/sale-orders/{order_reference}", wrapper.UpdateSaleOrder)
	})
	r.Group(func(r chi.Router) {
		r.Get(options.BaseURL+"/sale-orders/{order_reference}/asn/export", wrapper.ExportASNToFile)
	})

	return r
}
